Re: [PATCH] Fix c/68513 for GCC5 (match.pd and SAVE_EXPRs)
On Tue, Jan 19, 2016 at 8:48 PM, Marek Polacekwrote: > 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 > > 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
Re: [PATCH] Fix c/68513 for GCC5 (match.pd and SAVE_EXPRs)
On Wed, Jan 20, 2016 at 12:01:50PM +0100, Richard Biener wrote: > On Tue, Jan 19, 2016 at 8:48 PM, Marek Polacekwrote: > > 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, done: 2016-01-20 Marek Polacek 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..405fec6 100644 --- gcc/match.pd +++ gcc/match.pd @@ -382,12 +382,15 @@ along with GCC; see the file COPYING3. If not see (bit_not (bit_not @0)) @0) +/* Disable on GENERIC because of PR68513. */ +#if GIMPLE /* (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))) (bit_xor (bit_and (bit_xor @0 @1) @2) @0))) +#endif /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */ 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
[PATCH] Fix c/68513 for GCC5 (match.pd and SAVE_EXPRs)
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? 2016-01-19 Marek PolacekPR 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