hints &= ~INLINE_HINT_known_hot;
       fprintf (f, " known_hot");
     }
+  if (hints & INLINE_HINT_builtin_constant_p)
+    {
+      hints &= ~INLINE_HINT_builtin_constant_p;
+      fprintf (f, " builtin_constant_p");
+    }
   gcc_assert (!hints);
 }
 
   vec_free (call_size_time_table);
   vec_free (loop_iterations);
   vec_free (loop_strides);
+  builtin_constant_p_parms.release ();
 }
 
 void
          new_predicate = es->predicate->remap_after_duplication
                                 (possible_truths);
          if (new_predicate == false && *es->predicate != false)
-           optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
+           optimized_out_size
+                += es->call_stmt_size * ipa_fn_summary::size_scale;
          edge_set_predicate (edge, &new_predicate);
        }
       info->loop_iterations
       info->loop_strides
        = remap_freqcounting_preds_after_dup (info->loop_strides,
                                              possible_truths);
+      if (info->builtin_constant_p_parms.length())
+       {
+         vec <int, va_heap, vl_ptr> parms = info->builtin_constant_p_parms;
+         int ip;
+         info->builtin_constant_p_parms = vNULL;
+         for (i = 0; parms.iterate (i, &ip); i++)
+           if (!avals.m_known_vals[ip])
+             info->builtin_constant_p_parms.safe_push (ip);
+       }
 
       /* If inliner or someone after inliner will ever start producing
          non-trivial clones, we will get trouble with lack of information
       info->loop_iterations = vec_safe_copy (info->loop_iterations);
       info->loop_strides = vec_safe_copy (info->loop_strides);
 
+      info->builtin_constant_p_parms
+            = info->builtin_constant_p_parms.copy ();
+
       ipa_freqcounting_predicate *f;
       for (int i = 0; vec_safe_iterate (info->loop_iterations, i, &f); i++)
        {
            fprintf (f, " inlinable");
          if (s->fp_expressions)
            fprintf (f, " fp_expression");
+         if (s->builtin_constant_p_parms.length ())
+           {
+             fprintf (f, " builtin_constant_p_parms");
+             for (unsigned int i = 0;
+                  i < s->builtin_constant_p_parms.length (); i++)
+               fprintf (f, " %i", s->builtin_constant_p_parms[i]);
+           }
          fprintf (f, "\n  global time:     %f\n", s->time.to_double ());
          fprintf (f, "  self size:       %i\n", ss->self_size);
          fprintf (f, "  global size:     %i\n", ss->size);
   return false;
 }
 
+/* Record to SUMMARY that PARM is used by builtin_constant_p.  */
+
+static void
+add_builtin_constant_p_parm (class ipa_fn_summary *summary, int parm)
+{
+  int ip;
+
+  /* Avoid duplicates.  */
+  for (unsigned int i = 0;
+       summary->builtin_constant_p_parms.iterate (i, &ip); i++)
+    if (ip == parm)
+      return;
+  summary->builtin_constant_p_parms.safe_push (parm);
+}
+
 /* If BB ends by a conditional we can turn into predicates, attach corresponding
    predicates to the CFG edges.   */
 
   op2 = gimple_call_arg (set_stmt, 0);
   if (!decompose_param_expr (fbi, set_stmt, op2, &index, ¶m_type, &aggpos))
     return;
+  if (!aggpos.by_ref)
+    add_builtin_constant_p_parm (summary, index);
   FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
     {
       predicate p = add_condition (summary, params_summary, index,
        hints |= INLINE_HINT_in_scc;
       if (DECL_DECLARED_INLINE_P (m_node->decl))
        hints |= INLINE_HINT_declared_inline;
+      if (info->builtin_constant_p_parms.length ()
+         && DECL_DECLARED_INLINE_P (m_node->decl))
+       hints |= INLINE_HINT_builtin_constant_p;
 
       ipa_freqcounting_predicate *fcp;
       for (i = 0; vec_safe_iterate (info->loop_iterations, i, &fcp); i++)
          operand_map[i] = map;
          gcc_assert (map < ipa_get_param_count (params_summary));
        }
+
+      int ip;
+      for (i = 0; callee_info->builtin_constant_p_parms.iterate (i, &ip); i++)
+       if (ip < count && operand_map[ip] >= 0)
+         add_builtin_constant_p_parm (info, operand_map[ip]);
     }
-  sreal freq =  edge->sreal_frequency ();
+  sreal freq = edge->sreal_frequency ();
   for (i = 0; vec_safe_iterate (callee_info->size_time_table, i, &e); i++)
     {
       predicate p;
              vec_safe_push (info->loop_strides, fcp);
            }
        }
+      count2 = streamer_read_uhwi (&ib);
+      if (info && count2)
+       info->builtin_constant_p_parms.reserve_exact (count2);
+      for (j = 0; j < count2; j++)
+       {
+         int parm = streamer_read_uhwi (&ib);
+         if (info)
+           info->builtin_constant_p_parms.quick_push (parm);
+       }
       for (e = node->callees; e; e = e->next_callee)
        read_ipa_call_summary (&ib, e, info != NULL);
       for (e = node->indirect_calls; e; e = e->next_callee)
              fcp->predicate->stream_out (ob);
              fcp->freq.stream_out (ob);
            }
+         streamer_write_uhwi (ob, info->builtin_constant_p_parms.length ());
+         int ip;
+         for (i = 0; info->builtin_constant_p_parms.iterate (i, &ip);
+              i++)
+           streamer_write_uhwi (ob, ip);
          for (edge = cnode->callees; edge; edge = edge->next_callee)
            write_ipa_call_summary (ob, edge);
          for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
 
      Set by simple_edge_hints in ipa-inline-analysis.c.   */
   INLINE_HINT_cross_module = 64,
   /* We know that the callee is hot by profile.  */
-  INLINE_HINT_known_hot = 128
+  INLINE_HINT_known_hot = 128,
+  /* There is builtin_constant_p dependent on parameter which is usually
+     a strong hint to inline.  */
+  INLINE_HINT_builtin_constant_p = 256
 };
 
 typedef int ipa_hints;
   ipa_fn_summary ()
     : min_size (0),
       inlinable (false), single_caller (false),
-      fp_expressions (false), estimated_stack_size (false),
+      fp_expressions (false),
+      estimated_stack_size (false),
       time (0), conds (NULL),
       size_time_table (NULL), call_size_time_table (NULL),
       loop_iterations (NULL), loop_strides (NULL),
+      builtin_constant_p_parms (vNULL),
       growth (0), scc_no (0)
   {
   }
     time (s.time), conds (s.conds), size_time_table (s.size_time_table),
     call_size_time_table (NULL),
     loop_iterations (s.loop_iterations), loop_strides (s.loop_strides),
+    builtin_constant_p_parms (s.builtin_constant_p_parms),
     growth (s.growth), scc_no (s.scc_no)
   {}
 
   vec<ipa_freqcounting_predicate, va_gc> *loop_iterations;
   /* Predicates on when some loops in the function can have known strides.  */
   vec<ipa_freqcounting_predicate, va_gc> *loop_strides;
+  /* Parameters tested by builtin_constant_p.  */
+  vec<int, va_heap, vl_ptr> GTY((skip)) builtin_constant_p_parms;
   /* Estimated growth for inlining all copies of the function before start
      of small functions inlining.
      This value will get out of date as the callers are duplicated, but