On Tue, Jan 19, 2016 at 8:48 PM, Marek Polacek <pola...@redhat.com> wrote: > Recently on IRC we've concluded that for GCC 5 the simplest solution > will be to just disable the problematic pattern on GENERIC. So done > in the following. (The problem was that the match.pd pattern created > SAVE_EXPRs which then leaked into gimplification.) > > Bootstrapped/regtested on x86_64-linux, ok for 5?
Please instead wrap the pattern in #if GIMPLE ... #endif and add a comment refering to the PR. Ok with that change. Thanks, Richard. > 2016-01-19 Marek Polacek <pola...@redhat.com> > > PR c/68513 > * match.pd ((x & ~m) | (y & m)): Only perform on GIMPLE. > > * gcc.dg/pr68513.c: New test. > > diff --git gcc/match.pd gcc/match.pd > index e40720e..0b557e6 100644 > --- gcc/match.pd > +++ gcc/match.pd > @@ -385,8 +385,9 @@ along with GCC; see the file COPYING3. If not see > /* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */ > (simplify > (bit_ior:c (bit_and:c@3 @0 (bit_not @2)) (bit_and:c@4 @1 @2)) > - (if ((TREE_CODE (@3) != SSA_NAME || has_single_use (@3)) > - && (TREE_CODE (@4) != SSA_NAME || has_single_use (@4))) > + (if (GIMPLE > + && (TREE_CODE (@3) != SSA_NAME || has_single_use (@3)) > + && (TREE_CODE (@4) != SSA_NAME || has_single_use (@4))) > (bit_xor (bit_and (bit_xor @0 @1) @2) @0))) > > > diff --git gcc/testsuite/gcc.dg/pr68513.c gcc/testsuite/gcc.dg/pr68513.c > index e69de29..86f878d 100644 > --- gcc/testsuite/gcc.dg/pr68513.c > +++ gcc/testsuite/gcc.dg/pr68513.c > @@ -0,0 +1,125 @@ > +/* PR c/68513 */ > +/* { dg-do compile } */ > +/* { dg-options "-funsafe-math-optimizations -fno-math-errno -O > -Wno-div-by-zero" } */ > + > +int i; > +unsigned u; > +volatile int *e; > + > +#define E (i ? *e : 0) > + > +/* Can't trigger some of them because operand_equal_p will return false > + for side-effects. */ > + > +/* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */ > +int > +fn1 (void) > +{ > + int r = 0; > + r += (short) (E & ~u | i & u); > + r += -(short) (E & ~u | i & u); > + r += (short) -(E & ~u | i & u); > + return r; > +} > + > +/* sqrt(x) < y is x >= 0 && x != +Inf, when y is large. */ > +double > +fn2 (void) > +{ > + double r; > + r = __builtin_sqrt (E) < __builtin_inf (); > + return r; > +} > + > +/* sqrt(x) < c is the same as x >= 0 && x < c*c. */ > +double > +fn3 (void) > +{ > + double r; > + r = __builtin_sqrt (E) < 1.3; > + return r; > +} > + > +/* copysign(x,y)*copysign(x,y) -> x*x. */ > +double > +fn4 (double y, double x) > +{ > + return __builtin_copysign (E, y) * __builtin_copysign (E, y); > +} > + > +/* x <= +Inf is the same as x == x, i.e. !isnan(x). */ > +int > +fn5 (void) > +{ > + return E <= __builtin_inf (); > +} > + > +/* Fold (A & ~B) - (A & B) into (A ^ B) - B. */ > +int > +fn6 (void) > +{ > + return (i & ~E) - (i & E); > +} > + > +/* Fold (A & B) - (A & ~B) into B - (A ^ B). */ > +int > +fn7 (void) > +{ > + return (i & E) - (i & ~E); > +} > + > +/* x + (x & 1) -> (x + 1) & ~1 */ > +int > +fn8 (void) > +{ > + return E + (E & 1); > +} > + > +/* Simplify comparison of something with itself. */ > +int > +fn9 (void) > +{ > + return E <= E | E >= E; > +} > + > +/* Fold (A & ~B) - (A & B) into (A ^ B) - B. */ > +int > +fn10 (void) > +{ > + return (i & ~E) - (i & E); > +} > + > +/* abs(x)*abs(x) -> x*x. Should be valid for all types. */ > +int > +fn11 (void) > +{ > + return __builtin_abs (E) * __builtin_abs (E); > +} > + > +/* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */ > +int > +fn12 (void) > +{ > + return (E | 11) & 12; > +} > + > +/* fold_range_test */ > +int > +fn13 (const char *s) > +{ > + return s[E] != '\0' && s[E] != '/'; > +} > + > +/* fold_comparison */ > +int > +fn14 (void) > +{ > + return (!!i ? : (u *= E / 0)) >= (u = E); > +} > + > +/* fold_mult_zconjz */ > +_Complex int > +fn15 (_Complex volatile int *z) > +{ > + return *z * ~*z; > +} > > Marek