On Fri, Nov 9, 2018 at 6:05 PM Wilco Dijkstra <wilco.dijks...@arm.com> wrote: > > Richard Biener wrote: > >Marc Glisse wrote: > >> Let's try with C = DBL_MIN and x = 婊BL_MAX. I don't believe it involves > >> signed zeros or infinities, just an underflow. First, the result depends on > >> the rounding mode. And in the default round-to-nearest, both divisions give > >> 0, and thus compare the same with 0, but we replace that with a sign test > >> on > >> x, where they clearly give opposite answers. > >> > >> What would be the proper flag to test to check if we care about underflow? > > > > We have none specific so this makes it flag_unsafe_math_optimizations. > > Right I have added the unsafe math check again like in the previous version: > > > The patch implements some of the optimizations discussed in > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71026. > > Simplify (C / x >= 0.0) into x >= 0.0 with -funsafe-math-optimizations > (since C / x can underflow to zero if x is huge, it's not safe otherwise). > If C is negative the comparison is reversed. > > > Simplify (x * C1) > C2 into x > (C2 / C1) with -funsafe-math-optimizations. > If C1 is negative the comparison is reversed. > > OK for commit?
OK. Thanks, Richard. > ChangeLog > 2018-11-09 Wilco Dijkstra <wdijk...@arm.com> > Jackson Woodruff <jackson.woodr...@arm.com> > > gcc/ > PR 71026/tree-optimization > * match.pd: Simplify floating point comparisons. > > gcc/testsuite/ > PR 71026/tree-optimization > * gcc.dg/div-cmp-1.c: New test. > * gcc.dg/div-cmp-2.c: New test. > > -- > diff --git a/gcc/match.pd b/gcc/match.pd > index > 94fbab841f5e36bd33fda849a686fd80886ee1ff..f6c76510f95be2485e5bacd07edab336705cbd25 > 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -405,6 +405,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (rdiv @0 (negate @1)) > (rdiv (negate @0) @1)) > > +(if (flag_unsafe_math_optimizations) > + /* Simplify (C / x op 0.0) to x op 0.0 for C != 0, C != Inf/Nan. > + Since C / x may underflow to zero, do this only for unsafe math. */ > + (for op (lt le gt ge) > + neg_op (gt ge lt le) > + (simplify > + (op (rdiv REAL_CST@0 @1) real_zerop@2) > + (if (!HONOR_SIGNED_ZEROS (@1) && !HONOR_INFINITIES (@1)) > + (switch > + (if (real_less (&dconst0, TREE_REAL_CST_PTR (@0))) > + (op @1 @2)) > + /* For C < 0, use the inverted operator. */ > + (if (real_less (TREE_REAL_CST_PTR (@0), &dconst0)) > + (neg_op @1 @2))))))) > + > /* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */ > (for div (trunc_div ceil_div floor_div round_div exact_div) > (simplify > @@ -4049,6 +4064,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (rdiv @2 @1)) > (rdiv (op @0 @2) @1))) > > + (for cmp (lt le gt ge) > + neg_cmp (gt ge lt le) > + /* Simplify (x * C1) cmp C2 -> x cmp (C2 / C1), where C1 != 0. */ > + (simplify > + (cmp (mult @0 REAL_CST@1) REAL_CST@2) > + (with > + { tree tem = const_binop (RDIV_EXPR, type, @2, @1); } > + (if (tem > + && !(REAL_VALUE_ISINF (TREE_REAL_CST (tem)) > + || (real_zerop (tem) && !real_zerop (@1)))) > + (switch > + (if (real_less (&dconst0, TREE_REAL_CST_PTR (@1))) > + (cmp @0 { tem; })) > + (if (real_less (TREE_REAL_CST_PTR (@1), &dconst0)) > + (neg_cmp @0 { tem; }))))))) > + > /* Simplify sqrt(x) * sqrt(y) -> sqrt(x*y). */ > (for root (SQRT CBRT) > (simplify > diff --git a/gcc/testsuite/gcc.dg/div-cmp-1.c > b/gcc/testsuite/gcc.dg/div-cmp-1.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..cd1a5cd3d6fee5a10e9859ca99b344fa3fdb7f5f > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/div-cmp-1.c > @@ -0,0 +1,29 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -funsafe-math-optimizations -fdump-tree-optimized-raw" > } */ > + > +int > +cmp_mul_1 (float x) > +{ > + return x * 3 <= 100; > +} > + > +int > +cmp_mul_2 (float x) > +{ > + return x * -5 > 100; > +} > + > +int > +div_cmp_1 (float x, float y) > +{ > + return x / 3 <= y; > +} > + > +int > +div_cmp_2 (float x, float y) > +{ > + return x / 3 <= 1; > +} > + > +/* { dg-final { scan-tree-dump-times "mult_expr" 1 "optimized" } } */ > +/* { dg-final { scan-tree-dump-not "rdiv_expr" "optimized" } } */ > diff --git a/gcc/testsuite/gcc.dg/div-cmp-2.c > b/gcc/testsuite/gcc.dg/div-cmp-2.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..f4ac42a196a804747d0b578e0aa2131671c8d3cf > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/div-cmp-2.c > @@ -0,0 +1,29 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -funsafe-math-optimizations -ffinite-math-only > -fdump-tree-optimized-raw" } */ > + > +int > +cmp_1 (float x) > +{ > + return 5 / x >= 0; > +} > + > +int > +cmp_2 (float x) > +{ > + return 1 / x <= 0; > +} > + > +int > +cmp_3 (float x) > +{ > + return -2 / x >= 0; > +} > + > +int > +cmp_4 (float x) > +{ > + return -5 / x <= 0; > +} > + > +/* { dg-final { scan-tree-dump-not "rdiv_expr" "optimized" } } */ > +