> > As said in the other thread - this makes sure we don't perform inlining > that might end up generating invalid code. It also preserves > user-provided optimize attributes more properly. > > Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. > > Richard. > > 2015-01-22 Richard Biener <rguent...@suse.de> > > * ipa-inline.c (can_inline_edge_p): Disable inlining of edges > with IL incompatible options. Properly honor user optimize > attributes.
Thanks, in fact I had similar patch in queue, just wanted to catch you on IRC and discuss posibility of making this a flag in common.opt Honza > > Index: gcc/ipa-inline.c > =================================================================== > --- gcc/ipa-inline.c (revision 219929) > +++ gcc/ipa-inline.c (working copy) > @@ -404,17 +404,56 @@ can_inline_edge_p (struct cgraph_edge *e > optimization attribute. */ > else if (caller_tree != callee_tree) > { > - /* gcc.dg/pr43564.c. Look at forced inline even in -O0. */ > - if (DECL_DISREGARD_INLINE_LIMITS (callee->decl)) > + /* There are some options that change IL semantics which means > + we cannot inline in these cases for correctness reason. > + Not even for always_inline declared functions. */ > + /* Strictly speaking only when the callee contains signed integer > + math where overflow is undefined. */ > + if ((opt_for_fn (e->caller->decl, flag_strict_overflow) > + != opt_for_fn (e->caller->decl, flag_strict_overflow)) > + || (opt_for_fn (e->caller->decl, flag_wrapv) > + != opt_for_fn (e->caller->decl, flag_wrapv)) > + || (opt_for_fn (e->caller->decl, flag_trapv) > + != opt_for_fn (e->caller->decl, flag_trapv)) > + /* Strictly speaking only when the callee contains memory > + accesses that are not using alias-set zero anyway. */ > + || (opt_for_fn (e->caller->decl, flag_strict_aliasing) > + != opt_for_fn (e->caller->decl, flag_strict_aliasing)) > + /* Strictly speaking only when the callee uses FP math. */ > + || (opt_for_fn (e->caller->decl, flag_rounding_math) > + != opt_for_fn (e->caller->decl, flag_rounding_math)) > + || (opt_for_fn (e->caller->decl, flag_trapping_math) > + != opt_for_fn (e->caller->decl, flag_trapping_math)) > + || (opt_for_fn (e->caller->decl, flag_unsafe_math_optimizations) > + != opt_for_fn (e->caller->decl, flag_unsafe_math_optimizations)) > + || (opt_for_fn (e->caller->decl, flag_finite_math_only) > + != opt_for_fn (e->caller->decl, flag_finite_math_only)) > + || (opt_for_fn (e->caller->decl, flag_signaling_nans) > + != opt_for_fn (e->caller->decl, flag_signaling_nans)) > + || (opt_for_fn (e->caller->decl, flag_cx_limited_range) > + != opt_for_fn (e->caller->decl, flag_cx_limited_range)) > + || (opt_for_fn (e->caller->decl, flag_signed_zeros) > + != opt_for_fn (e->caller->decl, flag_signed_zeros)) > + || (opt_for_fn (e->caller->decl, flag_associative_math) > + != opt_for_fn (e->caller->decl, flag_associative_math)) > + || (opt_for_fn (e->caller->decl, flag_reciprocal_math) > + != opt_for_fn (e->caller->decl, flag_reciprocal_math)) > + /* Strictly speaking only when the callee contains function > + calls that may end up setting errno. */ > + || (opt_for_fn (e->caller->decl, flag_errno_math) > + != opt_for_fn (e->caller->decl, flag_errno_math))) > + { > + e->inline_failed = CIF_OPTIMIZATION_MISMATCH; > + inlinable = false; > + } > + /* gcc.dg/pr43564.c. Apply user-forced inline even at -O0. */ > + else if (DECL_DISREGARD_INLINE_LIMITS (callee->decl) > + && lookup_attribute ("always_inline", > + DECL_ATTRIBUTES (callee->decl))) > ; > - /* When user added an attribute, honnor it. */ > - else if ((lookup_attribute ("optimize", DECL_ATTRIBUTES (caller->decl)) > - || lookup_attribute ("optimize", > - DECL_ATTRIBUTES (callee->decl))) > - && ((opt_for_fn (caller->decl, optimize) > - > opt_for_fn (callee->decl, optimize)) > - || (opt_for_fn (caller->decl, optimize_size) > - != opt_for_fn (callee->decl, optimize_size)))) > + /* When user added an attribute to the callee honor it. */ > + else if (lookup_attribute ("optimize", DECL_ATTRIBUTES (callee->decl)) > + && opts_for_fn (caller->decl) != opts_for_fn (callee->decl)) > { > e->inline_failed = CIF_OPTIMIZATION_MISMATCH; > inlinable = false;