public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Work around PR65873
@ 2015-05-12 22:13 Jan Hubicka
  2015-05-13 13:13 ` Richard Biener
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Jan Hubicka @ 2015-05-12 22:13 UTC (permalink / raw)
  To: gcc-patches


Hi,
this patch works around PR where we refuse to inline always_inline memcpy
into function with explicit Ofast optimization attribute.  This is because
we think we can not promote -fno-fast-math code to -fast-math code.
This is of course safe for memcpy because it contains to fast-math code,
but we don't really do the analysis for each of the flags we check.

Earlier compilers was happily producing wrong code here and it seems practical
to do that on GCC 5 to deal with common falout.  I will implement the more
fine grained check incrementally.

Bootstrapped/regtested x86_64-linux. Will commit it to mainline shortly and
to release branch later this week.

	PR ipa/65873
	* ipa-inline.c (can_inline_edge_p): Allow early inlining of always
	inlines across optimization boundary.
	* testsuite/gcc.c-torture/compile/pr65873.c: New testcase.
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 223093)
+++ ipa-inline.c	(working copy)
@@ -427,46 +427,55 @@ can_inline_edge_p (struct cgraph_edge *e
 	      && lookup_attribute ("always_inline",
 				   DECL_ATTRIBUTES (callee->decl)));
 
+     /* Until GCC 4.9 we did not check the semantics alterning flags
+	bellow and inline across optimization boundry.
+	Enabling checks bellow breaks several packages by refusing
+	to inline library always_inline functions. See PR65873.
+	Disable the check for early inlining for now until better solution
+	is found.  */
+     if (always_inline && early)
+	;
       /* 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 ((check_maybe_up (flag_strict_overflow)
-	   /* this flag is set by optimize.  Allow inlining across
-	      optimize boundary.  */
-	   && (!opt_for_fn (caller->decl, optimize)
-	       == !opt_for_fn (callee->decl, optimize) || !always_inline))
-	  || check_match (flag_wrapv)
-	  || check_match (flag_trapv)
-	  /* Strictly speaking only when the callee uses FP math.  */
-	  || check_maybe_up (flag_rounding_math)
-	  || check_maybe_up (flag_trapping_math)
-	  || check_maybe_down (flag_unsafe_math_optimizations)
-	  || check_maybe_down (flag_finite_math_only)
-	  || check_maybe_up (flag_signaling_nans)
-	  || check_maybe_down (flag_cx_limited_range)
-	  || check_maybe_up (flag_signed_zeros)
-	  || check_maybe_down (flag_associative_math)
-	  || check_maybe_down (flag_reciprocal_math)
-	  /* We do not want to make code compiled with exceptions to be brought
-	     into a non-EH function unless we know that the callee does not
-	     throw.  This is tracked by DECL_FUNCTION_PERSONALITY.  */
-	  || (check_match (flag_non_call_exceptions)
-	      /* TODO: We also may allow bringing !flag_non_call_exceptions
-		 to flag_non_call_exceptions function, but that may need
-		 extra work in tree-inline to add the extra EH edges.  */
-	      && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
-		  || DECL_FUNCTION_PERSONALITY (callee->decl)))
-	  || (check_maybe_up (flag_exceptions)
-	      && DECL_FUNCTION_PERSONALITY (callee->decl))
-	  /* Strictly speaking only when the callee contains function
-	     calls that may end up setting errno.  */
-	  || check_maybe_up (flag_errno_math)
-	  /* When devirtualization is diabled for callee, it is not safe
-	     to inline it as we possibly mangled the type info.
-	     Allow early inlining of always inlines.  */
-	  || (!early && check_maybe_down (flag_devirtualize)))
+     else if ((check_maybe_up (flag_strict_overflow)
+	       /* this flag is set by optimize.  Allow inlining across
+		  optimize boundary.  */
+	       && (!opt_for_fn (caller->decl, optimize)
+		   == !opt_for_fn (callee->decl, optimize) || !always_inline))
+	      || check_match (flag_wrapv)
+	      || check_match (flag_trapv)
+	      /* Strictly speaking only when the callee uses FP math.  */
+	      || check_maybe_up (flag_rounding_math)
+	      || check_maybe_up (flag_trapping_math)
+	      || check_maybe_down (flag_unsafe_math_optimizations)
+	      || check_maybe_down (flag_finite_math_only)
+	      || check_maybe_up (flag_signaling_nans)
+	      || check_maybe_down (flag_cx_limited_range)
+	      || check_maybe_up (flag_signed_zeros)
+	      || check_maybe_down (flag_associative_math)
+	      || check_maybe_down (flag_reciprocal_math)
+	      /* We do not want to make code compiled with exceptions to be
+		 brought into a non-EH function unless we know that the callee
+		 does not throw.
+		 This is tracked by DECL_FUNCTION_PERSONALITY.  */
+	      || (check_match (flag_non_call_exceptions)
+		  /* TODO: We also may allow bringing !flag_non_call_exceptions
+		     to flag_non_call_exceptions function, but that may need
+		     extra work in tree-inline to add the extra EH edges.  */
+		  && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
+		      || DECL_FUNCTION_PERSONALITY (callee->decl)))
+	      || (check_maybe_up (flag_exceptions)
+		  && DECL_FUNCTION_PERSONALITY (callee->decl))
+	      /* Strictly speaking only when the callee contains function
+		 calls that may end up setting errno.  */
+	      || check_maybe_up (flag_errno_math)
+	      /* When devirtualization is diabled for callee, it is not safe
+		 to inline it as we possibly mangled the type info.
+		 Allow early inlining of always inlines.  */
+	      || (!early && check_maybe_down (flag_devirtualize)))
 	{
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
@@ -481,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
 	}
+      /* If explicit optimize attribute are not used, the mismatch is caused
+	 by different command line options used to build different units.
+	 Do not care about COMDAT functions - those are intended to be
+         optimized with the optimization flags of module they are used in.
+	 Also do not care about mixing up size/speed optimization when
+	 DECL_DISREGARD_INLINE_LIMITS is set.  */
+      else if ((callee->merged
+	        && !lookup_attribute ("optimize",
+				      DECL_ATTRIBUTES (caller->decl)))
+	       || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
+	;
       /* If mismatch is caused by merging two LTO units with different
 	 optimizationflags we want to be bit nicer.  However never inline
 	 if one of functions is not optimized at all.  */
Index: testsuite/gcc.c-torture/compile/pr65873.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr65873.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/pr65873.c	(revision 0)
@@ -0,0 +1,14 @@
+typedef __SIZE_TYPE__ size_t;
+
+extern inline __attribute__ ((__always_inline__, __gnu_inline__, __artificial__, __nothrow__, __leaf__)) void *
+memcpy (void *__restrict __dest, const void *__restrict __src, size_t __len)
+{
+  return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
+}
+
+__attribute__((optimize ("Ofast"))) void
+bar (void *d, void *s, size_t l)
+{
+  memcpy (d, s, l);
+}
+

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Work around PR65873
  2015-05-12 22:13 Work around PR65873 Jan Hubicka
@ 2015-05-13 13:13 ` Richard Biener
  2015-05-13 14:17   ` Jan Hubicka
  2015-05-13 20:12 ` Sandra Loosemore
  2015-05-17 18:23 ` Jan Hubicka
  2 siblings, 1 reply; 5+ messages in thread
From: Richard Biener @ 2015-05-13 13:13 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: GCC Patches

On Wed, May 13, 2015 at 12:12 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>
> Hi,
> this patch works around PR where we refuse to inline always_inline memcpy
> into function with explicit Ofast optimization attribute.  This is because
> we think we can not promote -fno-fast-math code to -fast-math code.
> This is of course safe for memcpy because it contains to fast-math code,
> but we don't really do the analysis for each of the flags we check.
>
> Earlier compilers was happily producing wrong code here and it seems practical
> to do that on GCC 5 to deal with common falout.  I will implement the more
> fine grained check incrementally.
>
> Bootstrapped/regtested x86_64-linux. Will commit it to mainline shortly and
> to release branch later this week.

Hmm, the changelog or the description above doesn't cover the

@@ -481,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e
          e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
          inlinable = false;
        }
+      /* If explicit optimize attribute are not used, the mismatch is caused
+        by different command line options used to build different units.
+        Do not care about COMDAT functions - those are intended to be
+         optimized with the optimization flags of module they are used in.
+        Also do not care about mixing up size/speed optimization when
+        DECL_DISREGARD_INLINE_LIMITS is set.  */
+      else if ((callee->merged
+               && !lookup_attribute ("optimize",
+                                     DECL_ATTRIBUTES (caller->decl)))
+              || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
+       ;
       /* If mismatch is caused by merging two LTO units with different
         optimizationflags we want to be bit nicer.  However never inline
         if one of functions is not optimized at all.  */

hunk.

>         PR ipa/65873
>         * ipa-inline.c (can_inline_edge_p): Allow early inlining of always
>         inlines across optimization boundary.
>         * testsuite/gcc.c-torture/compile/pr65873.c: New testcase.
> Index: ipa-inline.c
> ===================================================================
> --- ipa-inline.c        (revision 223093)
> +++ ipa-inline.c        (working copy)
> @@ -427,46 +427,55 @@ can_inline_edge_p (struct cgraph_edge *e
>               && lookup_attribute ("always_inline",
>                                    DECL_ATTRIBUTES (callee->decl)));
>
> +     /* Until GCC 4.9 we did not check the semantics alterning flags
> +       bellow and inline across optimization boundry.
> +       Enabling checks bellow breaks several packages by refusing
> +       to inline library always_inline functions. See PR65873.
> +       Disable the check for early inlining for now until better solution
> +       is found.  */
> +     if (always_inline && early)
> +       ;
>        /* 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 ((check_maybe_up (flag_strict_overflow)
> -          /* this flag is set by optimize.  Allow inlining across
> -             optimize boundary.  */
> -          && (!opt_for_fn (caller->decl, optimize)
> -              == !opt_for_fn (callee->decl, optimize) || !always_inline))
> -         || check_match (flag_wrapv)
> -         || check_match (flag_trapv)
> -         /* Strictly speaking only when the callee uses FP math.  */
> -         || check_maybe_up (flag_rounding_math)
> -         || check_maybe_up (flag_trapping_math)
> -         || check_maybe_down (flag_unsafe_math_optimizations)
> -         || check_maybe_down (flag_finite_math_only)
> -         || check_maybe_up (flag_signaling_nans)
> -         || check_maybe_down (flag_cx_limited_range)
> -         || check_maybe_up (flag_signed_zeros)
> -         || check_maybe_down (flag_associative_math)
> -         || check_maybe_down (flag_reciprocal_math)
> -         /* We do not want to make code compiled with exceptions to be brought
> -            into a non-EH function unless we know that the callee does not
> -            throw.  This is tracked by DECL_FUNCTION_PERSONALITY.  */
> -         || (check_match (flag_non_call_exceptions)
> -             /* TODO: We also may allow bringing !flag_non_call_exceptions
> -                to flag_non_call_exceptions function, but that may need
> -                extra work in tree-inline to add the extra EH edges.  */
> -             && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
> -                 || DECL_FUNCTION_PERSONALITY (callee->decl)))
> -         || (check_maybe_up (flag_exceptions)
> -             && DECL_FUNCTION_PERSONALITY (callee->decl))
> -         /* Strictly speaking only when the callee contains function
> -            calls that may end up setting errno.  */
> -         || check_maybe_up (flag_errno_math)
> -         /* When devirtualization is diabled for callee, it is not safe
> -            to inline it as we possibly mangled the type info.
> -            Allow early inlining of always inlines.  */
> -         || (!early && check_maybe_down (flag_devirtualize)))
> +     else if ((check_maybe_up (flag_strict_overflow)
> +              /* this flag is set by optimize.  Allow inlining across
> +                 optimize boundary.  */
> +              && (!opt_for_fn (caller->decl, optimize)
> +                  == !opt_for_fn (callee->decl, optimize) || !always_inline))
> +             || check_match (flag_wrapv)
> +             || check_match (flag_trapv)
> +             /* Strictly speaking only when the callee uses FP math.  */
> +             || check_maybe_up (flag_rounding_math)
> +             || check_maybe_up (flag_trapping_math)
> +             || check_maybe_down (flag_unsafe_math_optimizations)
> +             || check_maybe_down (flag_finite_math_only)
> +             || check_maybe_up (flag_signaling_nans)
> +             || check_maybe_down (flag_cx_limited_range)
> +             || check_maybe_up (flag_signed_zeros)
> +             || check_maybe_down (flag_associative_math)
> +             || check_maybe_down (flag_reciprocal_math)
> +             /* We do not want to make code compiled with exceptions to be
> +                brought into a non-EH function unless we know that the callee
> +                does not throw.
> +                This is tracked by DECL_FUNCTION_PERSONALITY.  */
> +             || (check_match (flag_non_call_exceptions)
> +                 /* TODO: We also may allow bringing !flag_non_call_exceptions
> +                    to flag_non_call_exceptions function, but that may need
> +                    extra work in tree-inline to add the extra EH edges.  */
> +                 && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
> +                     || DECL_FUNCTION_PERSONALITY (callee->decl)))
> +             || (check_maybe_up (flag_exceptions)
> +                 && DECL_FUNCTION_PERSONALITY (callee->decl))
> +             /* Strictly speaking only when the callee contains function
> +                calls that may end up setting errno.  */
> +             || check_maybe_up (flag_errno_math)
> +             /* When devirtualization is diabled for callee, it is not safe
> +                to inline it as we possibly mangled the type info.
> +                Allow early inlining of always inlines.  */
> +             || (!early && check_maybe_down (flag_devirtualize)))
>         {
>           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
>           inlinable = false;
> @@ -481,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e
>           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
>           inlinable = false;
>         }
> +      /* If explicit optimize attribute are not used, the mismatch is caused
> +        by different command line options used to build different units.
> +        Do not care about COMDAT functions - those are intended to be
> +         optimized with the optimization flags of module they are used in.
> +        Also do not care about mixing up size/speed optimization when
> +        DECL_DISREGARD_INLINE_LIMITS is set.  */
> +      else if ((callee->merged
> +               && !lookup_attribute ("optimize",
> +                                     DECL_ATTRIBUTES (caller->decl)))
> +              || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
> +       ;
>        /* If mismatch is caused by merging two LTO units with different
>          optimizationflags we want to be bit nicer.  However never inline
>          if one of functions is not optimized at all.  */
> Index: testsuite/gcc.c-torture/compile/pr65873.c
> ===================================================================
> --- testsuite/gcc.c-torture/compile/pr65873.c   (revision 0)
> +++ testsuite/gcc.c-torture/compile/pr65873.c   (revision 0)
> @@ -0,0 +1,14 @@
> +typedef __SIZE_TYPE__ size_t;
> +
> +extern inline __attribute__ ((__always_inline__, __gnu_inline__, __artificial__, __nothrow__, __leaf__)) void *
> +memcpy (void *__restrict __dest, const void *__restrict __src, size_t __len)
> +{
> +  return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
> +}
> +
> +__attribute__((optimize ("Ofast"))) void
> +bar (void *d, void *s, size_t l)
> +{
> +  memcpy (d, s, l);
> +}
> +

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Work around PR65873
  2015-05-13 13:13 ` Richard Biener
@ 2015-05-13 14:17   ` Jan Hubicka
  0 siblings, 0 replies; 5+ messages in thread
From: Jan Hubicka @ 2015-05-13 14:17 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, GCC Patches

> On Wed, May 13, 2015 at 12:12 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >
> > Hi,
> > this patch works around PR where we refuse to inline always_inline memcpy
> > into function with explicit Ofast optimization attribute.  This is because
> > we think we can not promote -fno-fast-math code to -fast-math code.
> > This is of course safe for memcpy because it contains to fast-math code,
> > but we don't really do the analysis for each of the flags we check.
> >
> > Earlier compilers was happily producing wrong code here and it seems practical
> > to do that on GCC 5 to deal with common falout.  I will implement the more
> > fine grained check incrementally.
> >
> > Bootstrapped/regtested x86_64-linux. Will commit it to mainline shortly and
> > to release branch later this week.
> 
> Hmm, the changelog or the description above doesn't cover the
> 
> @@ -481,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e
>           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
>           inlinable = false;
>         }
> +      /* If explicit optimize attribute are not used, the mismatch is caused
> +        by different command line options used to build different units.
> +        Do not care about COMDAT functions - those are intended to be
> +         optimized with the optimization flags of module they are used in.
> +        Also do not care about mixing up size/speed optimization when
> +        DECL_DISREGARD_INLINE_LIMITS is set.  */
> +      else if ((callee->merged
> +               && !lookup_attribute ("optimize",
> +                                     DECL_ATTRIBUTES (caller->decl)))
> +              || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
> +       ;
>        /* If mismatch is caused by merging two LTO units with different
>          optimizationflags we want to be bit nicer.  However never inline
>          if one of functions is not optimized at all.  */
> 
> hunk.

Ah, sorry. The change was intended, but I forgot to write about it.
Yep, as comment says this makes us a bit more relaxed about inlining COMDATs
when the prevailing variant is -Os and caller body is -O3 or vice versa.

Honza
> 
> >         PR ipa/65873
> >         * ipa-inline.c (can_inline_edge_p): Allow early inlining of always
> >         inlines across optimization boundary.
> >         * testsuite/gcc.c-torture/compile/pr65873.c: New testcase.
> > Index: ipa-inline.c
> > ===================================================================
> > --- ipa-inline.c        (revision 223093)
> > +++ ipa-inline.c        (working copy)
> > @@ -427,46 +427,55 @@ can_inline_edge_p (struct cgraph_edge *e
> >               && lookup_attribute ("always_inline",
> >                                    DECL_ATTRIBUTES (callee->decl)));
> >
> > +     /* Until GCC 4.9 we did not check the semantics alterning flags
> > +       bellow and inline across optimization boundry.
> > +       Enabling checks bellow breaks several packages by refusing
> > +       to inline library always_inline functions. See PR65873.
> > +       Disable the check for early inlining for now until better solution
> > +       is found.  */
> > +     if (always_inline && early)
> > +       ;
> >        /* 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 ((check_maybe_up (flag_strict_overflow)
> > -          /* this flag is set by optimize.  Allow inlining across
> > -             optimize boundary.  */
> > -          && (!opt_for_fn (caller->decl, optimize)
> > -              == !opt_for_fn (callee->decl, optimize) || !always_inline))
> > -         || check_match (flag_wrapv)
> > -         || check_match (flag_trapv)
> > -         /* Strictly speaking only when the callee uses FP math.  */
> > -         || check_maybe_up (flag_rounding_math)
> > -         || check_maybe_up (flag_trapping_math)
> > -         || check_maybe_down (flag_unsafe_math_optimizations)
> > -         || check_maybe_down (flag_finite_math_only)
> > -         || check_maybe_up (flag_signaling_nans)
> > -         || check_maybe_down (flag_cx_limited_range)
> > -         || check_maybe_up (flag_signed_zeros)
> > -         || check_maybe_down (flag_associative_math)
> > -         || check_maybe_down (flag_reciprocal_math)
> > -         /* We do not want to make code compiled with exceptions to be brought
> > -            into a non-EH function unless we know that the callee does not
> > -            throw.  This is tracked by DECL_FUNCTION_PERSONALITY.  */
> > -         || (check_match (flag_non_call_exceptions)
> > -             /* TODO: We also may allow bringing !flag_non_call_exceptions
> > -                to flag_non_call_exceptions function, but that may need
> > -                extra work in tree-inline to add the extra EH edges.  */
> > -             && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
> > -                 || DECL_FUNCTION_PERSONALITY (callee->decl)))
> > -         || (check_maybe_up (flag_exceptions)
> > -             && DECL_FUNCTION_PERSONALITY (callee->decl))
> > -         /* Strictly speaking only when the callee contains function
> > -            calls that may end up setting errno.  */
> > -         || check_maybe_up (flag_errno_math)
> > -         /* When devirtualization is diabled for callee, it is not safe
> > -            to inline it as we possibly mangled the type info.
> > -            Allow early inlining of always inlines.  */
> > -         || (!early && check_maybe_down (flag_devirtualize)))
> > +     else if ((check_maybe_up (flag_strict_overflow)
> > +              /* this flag is set by optimize.  Allow inlining across
> > +                 optimize boundary.  */
> > +              && (!opt_for_fn (caller->decl, optimize)
> > +                  == !opt_for_fn (callee->decl, optimize) || !always_inline))
> > +             || check_match (flag_wrapv)
> > +             || check_match (flag_trapv)
> > +             /* Strictly speaking only when the callee uses FP math.  */
> > +             || check_maybe_up (flag_rounding_math)
> > +             || check_maybe_up (flag_trapping_math)
> > +             || check_maybe_down (flag_unsafe_math_optimizations)
> > +             || check_maybe_down (flag_finite_math_only)
> > +             || check_maybe_up (flag_signaling_nans)
> > +             || check_maybe_down (flag_cx_limited_range)
> > +             || check_maybe_up (flag_signed_zeros)
> > +             || check_maybe_down (flag_associative_math)
> > +             || check_maybe_down (flag_reciprocal_math)
> > +             /* We do not want to make code compiled with exceptions to be
> > +                brought into a non-EH function unless we know that the callee
> > +                does not throw.
> > +                This is tracked by DECL_FUNCTION_PERSONALITY.  */
> > +             || (check_match (flag_non_call_exceptions)
> > +                 /* TODO: We also may allow bringing !flag_non_call_exceptions
> > +                    to flag_non_call_exceptions function, but that may need
> > +                    extra work in tree-inline to add the extra EH edges.  */
> > +                 && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
> > +                     || DECL_FUNCTION_PERSONALITY (callee->decl)))
> > +             || (check_maybe_up (flag_exceptions)
> > +                 && DECL_FUNCTION_PERSONALITY (callee->decl))
> > +             /* Strictly speaking only when the callee contains function
> > +                calls that may end up setting errno.  */
> > +             || check_maybe_up (flag_errno_math)
> > +             /* When devirtualization is diabled for callee, it is not safe
> > +                to inline it as we possibly mangled the type info.
> > +                Allow early inlining of always inlines.  */
> > +             || (!early && check_maybe_down (flag_devirtualize)))
> >         {
> >           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
> >           inlinable = false;
> > @@ -481,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e
> >           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
> >           inlinable = false;
> >         }
> > +      /* If explicit optimize attribute are not used, the mismatch is caused
> > +        by different command line options used to build different units.
> > +        Do not care about COMDAT functions - those are intended to be
> > +         optimized with the optimization flags of module they are used in.
> > +        Also do not care about mixing up size/speed optimization when
> > +        DECL_DISREGARD_INLINE_LIMITS is set.  */
> > +      else if ((callee->merged
> > +               && !lookup_attribute ("optimize",
> > +                                     DECL_ATTRIBUTES (caller->decl)))
> > +              || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
> > +       ;
> >        /* If mismatch is caused by merging two LTO units with different
> >          optimizationflags we want to be bit nicer.  However never inline
> >          if one of functions is not optimized at all.  */
> > Index: testsuite/gcc.c-torture/compile/pr65873.c
> > ===================================================================
> > --- testsuite/gcc.c-torture/compile/pr65873.c   (revision 0)
> > +++ testsuite/gcc.c-torture/compile/pr65873.c   (revision 0)
> > @@ -0,0 +1,14 @@
> > +typedef __SIZE_TYPE__ size_t;
> > +
> > +extern inline __attribute__ ((__always_inline__, __gnu_inline__, __artificial__, __nothrow__, __leaf__)) void *
> > +memcpy (void *__restrict __dest, const void *__restrict __src, size_t __len)
> > +{
> > +  return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
> > +}
> > +
> > +__attribute__((optimize ("Ofast"))) void
> > +bar (void *d, void *s, size_t l)
> > +{
> > +  memcpy (d, s, l);
> > +}
> > +

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Work around PR65873
  2015-05-12 22:13 Work around PR65873 Jan Hubicka
  2015-05-13 13:13 ` Richard Biener
@ 2015-05-13 20:12 ` Sandra Loosemore
  2015-05-17 18:23 ` Jan Hubicka
  2 siblings, 0 replies; 5+ messages in thread
From: Sandra Loosemore @ 2015-05-13 20:12 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On 05/12/2015 04:12 PM, Jan Hubicka wrote:
>
> Hi,
> this patch works around PR where we refuse to inline always_inline memcpy
> into function with explicit Ofast optimization attribute.  This is because
> we think we can not promote -fno-fast-math code to -fast-math code.
> This is of course safe for memcpy because it contains to fast-math code,
> but we don't really do the analysis for each of the flags we check.
>
> Earlier compilers was happily producing wrong code here and it seems practical
> to do that on GCC 5 to deal with common falout.  I will implement the more
> fine grained check incrementally.
>
> Bootstrapped/regtested x86_64-linux. Will commit it to mainline shortly and
> to release branch later this week.
>
> 	PR ipa/65873
> 	* ipa-inline.c (can_inline_edge_p): Allow early inlining of always
> 	inlines across optimization boundary.
> 	* testsuite/gcc.c-torture/compile/pr65873.c: New testcase.
> Index: ipa-inline.c
> ===================================================================
> --- ipa-inline.c	(revision 223093)
> +++ ipa-inline.c	(working copy)
> @@ -427,46 +427,55 @@ can_inline_edge_p (struct cgraph_edge *e
>   	      && lookup_attribute ("always_inline",
>   				   DECL_ATTRIBUTES (callee->decl)));
>

I'm having problems parsing the following comment block:

> +     /* Until GCC 4.9 we did not check the semantics alterning flags

"alterning"?

> +	bellow and inline across optimization boundry.

s/bellow/below/g
s/boundry/boundary/

> +	Enabling checks bellow breaks several packages by refusing
> +	to inline library always_inline functions. See PR65873.
> +	Disable the check for early inlining for now until better solution
> +	is found.  */
> +     if (always_inline && early)
> +	;

-Sandra

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Work around PR65873
  2015-05-12 22:13 Work around PR65873 Jan Hubicka
  2015-05-13 13:13 ` Richard Biener
  2015-05-13 20:12 ` Sandra Loosemore
@ 2015-05-17 18:23 ` Jan Hubicka
  2 siblings, 0 replies; 5+ messages in thread
From: Jan Hubicka @ 2015-05-17 18:23 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

Hi,
this is a variant of patch I backported to GCC 4.9.  It also includes the earlier
for for -fstrict-aliasing boundary.

Honza

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 223269)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2015-04-16  Jan Hubicka  <hubicka@ucw.cz>
+
+	PR ipa/65873
+	* ipa-inline.c (can_inline_edge_p): Allow early inlining of always
+	inlines across optimization boundary; be tolerant about COMDAT;
+	allow inlining across -fstrict-aliasing boundary.
+
 2015-05-16  Segher Boessenkool  <segher@kernel.crashing.org>
 
 	Backport from mainline
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 223252)
+++ ipa-inline.c	(working copy)
@@ -427,49 +427,55 @@ can_inline_edge_p (struct cgraph_edge *e
 	      && lookup_attribute ("always_inline",
 				   DECL_ATTRIBUTES (callee->decl)));
 
+     /* Until GCC 4.9 we did not check the semantics alterning flags
+	bellow and inline across optimization boundry.
+	Enabling checks bellow breaks several packages by refusing
+	to inline library always_inline functions. See PR65873.
+	Disable the check for early inlining for now until better solution
+	is found.  */
+     if (always_inline && early)
+	;
       /* 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 ((check_maybe_up (flag_strict_overflow)
-	   /* this flag is set by optimize.  Allow inlining across
-	      optimize boundary.  */
-	   && (!opt_for_fn (caller->decl, optimize)
-	       == !opt_for_fn (callee->decl, optimize) || !always_inline))
-	  || check_match (flag_wrapv)
-	  || check_match (flag_trapv)
-	  /* Strictly speaking only when the callee contains memory
-	     accesses that are not using alias-set zero anyway.  */
-	  || check_maybe_down (flag_strict_aliasing)
-	  /* Strictly speaking only when the callee uses FP math.  */
-	  || check_maybe_up (flag_rounding_math)
-	  || check_maybe_up (flag_trapping_math)
-	  || check_maybe_down (flag_unsafe_math_optimizations)
-	  || check_maybe_down (flag_finite_math_only)
-	  || check_maybe_up (flag_signaling_nans)
-	  || check_maybe_down (flag_cx_limited_range)
-	  || check_maybe_up (flag_signed_zeros)
-	  || check_maybe_down (flag_associative_math)
-	  || check_maybe_down (flag_reciprocal_math)
-	  /* We do not want to make code compiled with exceptions to be brought
-	     into a non-EH function unless we know that the callee does not
-	     throw.  This is tracked by DECL_FUNCTION_PERSONALITY.  */
-	  || (check_match (flag_non_call_exceptions)
-	      /* TODO: We also may allow bringing !flag_non_call_exceptions
-		 to flag_non_call_exceptions function, but that may need
-		 extra work in tree-inline to add the extra EH edges.  */
-	      && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
-		  || DECL_FUNCTION_PERSONALITY (callee->decl)))
-	  || (check_maybe_up (flag_exceptions)
-	      && DECL_FUNCTION_PERSONALITY (callee->decl))
-	  /* Strictly speaking only when the callee contains function
-	     calls that may end up setting errno.  */
-	  || check_maybe_up (flag_errno_math)
-	  /* When devirtualization is diabled for callee, it is not safe
-	     to inline it as we possibly mangled the type info.
-	     Allow early inlining of always inlines.  */
-	  || (!early && check_maybe_down (flag_devirtualize)))
+     else if ((check_maybe_up (flag_strict_overflow)
+	       /* this flag is set by optimize.  Allow inlining across
+		  optimize boundary.  */
+	       && (!opt_for_fn (caller->decl, optimize)
+		   == !opt_for_fn (callee->decl, optimize) || !always_inline))
+	      || check_match (flag_wrapv)
+	      || check_match (flag_trapv)
+	      /* Strictly speaking only when the callee uses FP math.  */
+	      || check_maybe_up (flag_rounding_math)
+	      || check_maybe_up (flag_trapping_math)
+	      || check_maybe_down (flag_unsafe_math_optimizations)
+	      || check_maybe_down (flag_finite_math_only)
+	      || check_maybe_up (flag_signaling_nans)
+	      || check_maybe_down (flag_cx_limited_range)
+	      || check_maybe_up (flag_signed_zeros)
+	      || check_maybe_down (flag_associative_math)
+	      || check_maybe_down (flag_reciprocal_math)
+	      /* We do not want to make code compiled with exceptions to be
+		 brought into a non-EH function unless we know that the callee
+		 does not throw.
+		 This is tracked by DECL_FUNCTION_PERSONALITY.  */
+	      || (check_match (flag_non_call_exceptions)
+		  /* TODO: We also may allow bringing !flag_non_call_exceptions
+		     to flag_non_call_exceptions function, but that may need
+		     extra work in tree-inline to add the extra EH edges.  */
+		  && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
+		      || DECL_FUNCTION_PERSONALITY (callee->decl)))
+	      || (check_maybe_up (flag_exceptions)
+		  && DECL_FUNCTION_PERSONALITY (callee->decl))
+	      /* Strictly speaking only when the callee contains function
+		 calls that may end up setting errno.  */
+	      || check_maybe_up (flag_errno_math)
+	      /* When devirtualization is diabled for callee, it is not safe
+		 to inline it as we possibly mangled the type info.
+		 Allow early inlining of always inlines.  */
+	      || (!early && check_maybe_down (flag_devirtualize)))
 	{
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
@@ -484,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
 	}
+      /* If explicit optimize attribute are not used, the mismatch is caused
+	 by different command line options used to build different units.
+	 Do not care about COMDAT functions - those are intended to be
+         optimized with the optimization flags of module they are used in.
+	 Also do not care about mixing up size/speed optimization when
+	 DECL_DISREGARD_INLINE_LIMITS is set.  */
+      else if ((callee->merged
+	        && !lookup_attribute ("optimize",
+				      DECL_ATTRIBUTES (caller->decl)))
+	       || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
+	;
       /* If mismatch is caused by merging two LTO units with different
 	 optimizationflags we want to be bit nicer.  However never inline
 	 if one of functions is not optimized at all.  */
@@ -515,7 +532,7 @@ can_inline_edge_p (struct cgraph_edge *e
       else if (opt_for_fn (callee->decl, optimize_size)
 	       < opt_for_fn (caller->decl, optimize_size)
 	       || (opt_for_fn (callee->decl, optimize)
-		   >= opt_for_fn (caller->decl, optimize)))
+		   > opt_for_fn (caller->decl, optimize)))
 	{
 	  if (estimate_edge_time (e)
 	      >= 20 + inline_edge_summary (e)->call_stmt_time)

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-17 17:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-12 22:13 Work around PR65873 Jan Hubicka
2015-05-13 13:13 ` Richard Biener
2015-05-13 14:17   ` Jan Hubicka
2015-05-13 20:12 ` Sandra Loosemore
2015-05-17 18:23 ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).