On Mon, 1 Dec 2014, Marc Glisse wrote: > On Mon, 1 Dec 2014, Richard Biener wrote: > > > The following fixes the oldest bug in my list of assigned PRs, namely > > combining A / CST / CST' to A / (CST * CST'). extract_muldiv does > > this in fold-const.c (but it fails to optimize to zero when CST * CST' > > overflows). > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. > > > > Richard. > > > > 2014-12-01 Richard Biener <rguent...@suse.de> > > > > PR tree-optimization/15346 > > * Makefile.in (gimple-match.o-warn): Remove -Wno-unused-parameter, > > add -Wno-unused-but-set-variable. > > * match.pd: Combine two successive divisions. > > > > * gcc.dg/tree-ssa/forwprop-32.c: New testcase. > > > > Index: gcc/match.pd > > =================================================================== > > --- gcc/match.pd (revision 218140) > > +++ gcc/match.pd (working copy) > > @@ -129,6 +129,19 @@ (define_operator_list inverted_tcc_compa > > && TYPE_UNSIGNED (type)) > > (trunc_div @0 @1))) > > > > +/* Combine two successive divisions. */ > > +(for div (trunc_div ceil_div floor_div round_div exact_div) > > + (simplify > > + (div (div @0 INTEGER_CST@1) INTEGER_CST@2) > > + (with { > > + bool overflow_p; > > + wide_int mul = wi::mul (@1, @2, TYPE_SIGN (type), &overflow_p); > > + } > > + (if (!overflow_p) > > + (div @0 { wide_int_to_tree (type, mul); })) > > + (if (overflow_p) > > + { build_zero_cst (type); })))) > > + > > Can't you have something like: > INT_MIN / 2 / (INT_MIN / -2) == -1 > where > 2 * (INT_MIN / -2) overflows?
Hmm, right. It should work if overflow_p && mul != INT_MIN as far as I can see. I am testing the following. Thanks, Richard. 2014-12-02 Richard Biener <rguent...@suse.de> * match.pd: When combining divisions exclude the degenerate case involving INT_MIN from overflow handling. * gcc.dg/torture/20141202-1.c: New testcase. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 218260) +++ gcc/match.pd (working copy) @@ -140,7 +140,9 @@ (define_operator_list inverted_tcc_compa } (if (!overflow_p) (div @0 { wide_int_to_tree (type, mul); })) - (if (overflow_p) + (if (overflow_p + && (TYPE_UNSIGNED (type) + || mul != wi::min_value (TYPE_PRECISION (type), SIGNED))) { build_zero_cst (type); })))) /* Optimize A / A to 1.0 if we don't care about Index: gcc/testsuite/gcc.dg/torture/20141202-1.c =================================================================== --- gcc/testsuite/gcc.dg/torture/20141202-1.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/20141202-1.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do run } */ + +extern void abort (void); + +int foo (int x) +{ + return (x / 2) / ((-__INT_MAX__ - 1) / -2); +} + +int main() +{ + if (foo (- __INT_MAX__ - 1) != -1) + abort (); + return 0; +}