The following works around PR70992 but the issue came up repeatedly that we are not very consistent in preserving the undefined behavior of division or modulo by zero. Ok - the only inconsistency is that we fold 0 % x to 0 but not 0 % 0 (with literal zero).
After folding is now no longer done early in the C family FEs the number of diagnostic regressions with the patch below is two. FAIL: g++.dg/cpp1y/constexpr-sfinae.C -std=c++14 (test for excess errors) FAIL: gcc.dg/wcaselabel-1.c (test for errors, line 10) And then there is a -fnon-call-exceptions testcase FAIL: gcc.c-torture/execute/20101011-1.c -O1 execution test FAIL: gcc.c-torture/execute/20101011-1.c -O2 execution test FAIL: gcc.c-torture/execute/20101011-1.c -O2 -flto -fno-use-linker-plugin -flt o-partition=none execution test FAIL: gcc.c-torture/execute/20101011-1.c -O2 -flto -fuse-linker-plugin -fno-fa t-lto-objects execution test FAIL: gcc.c-torture/execute/20101011-1.c -O3 -g execution test FAIL: gcc.c-torture/execute/20101011-1.c -Os execution test which tests that 0/0 traps (on targets where it does). This shows we might want to guard the simplifications against -fnon-call-exceptions. The other way to fix the inconsistency is of course to not rely on undefinedness in 0 % x simplification and disable that if x is not known to be nonzero. We can introduce the other transforms with properly guarding against a zero 2nd operand as well. So - any opinions here? Thanks, Richard. FAIL: g++.dg/cpp1y/constexpr-sfinae.C -std=c++14 (test for excess errors) FAIL: gcc.c-torture/execute/20101011-1.c -O1 execution test FAIL: gcc.c-torture/execute/20101011-1.c -O2 execution test FAIL: gcc.c-torture/execute/20101011-1.c -O2 -flto -fno-use-linker-plugin -flt o-partition=none execution test FAIL: gcc.c-torture/execute/20101011-1.c -O2 -flto -fuse-linker-plugin -fno-fa t-lto-objects execution test FAIL: gcc.c-torture/execute/20101011-1.c -O3 -g execution test FAIL: gcc.c-torture/execute/20101011-1.c -Os execution test FAIL: gcc.dg/wcaselabel-1.c (test for errors, line 10) 2016-06-08 Richard Biener <rguent...@suse.de> PR middle-end/70992 * match.pd (X / X -> 1): Add. (0 / X -> 0): Likewise. (0 % X -> 0): Remove restriction on X not being literal zero. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 237205) +++ gcc/match.pd (working copy) @@ -140,12 +140,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || !COMPLEX_FLOAT_TYPE_P (type))) (negate @0))) -/* Make sure to preserve divisions by zero. This is the reason why - we don't simplify x / x to 1 or 0 / x to 0. */ (for op (mult trunc_div ceil_div floor_div round_div exact_div) (simplify (op @0 integer_onep) (non_lvalue @0))) +/* Make sure to preserve divisions by zero. This is the reason why + we don't simplify x / x to 1 or 0 / x to 0. */ +(for op (trunc_div ceil_div floor_div round_div exact_div) + (simplify + (op @0 @0) + { build_one_cst (type); }) + (simplify + (op integer_zerop@0 @1) + @0)) /* X / -1 is -X. */ (for div (trunc_div ceil_div floor_div round_div exact_div) @@ -255,9 +262,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* 0 % X is always zero. */ (simplify (mod integer_zerop@0 @1) - /* But not for 0 % 0 so that we can get the proper warnings and errors. */ - (if (!integer_zerop (@1)) - @0)) + @0) /* X % 1 is always zero. */ (simplify (mod @0 integer_onep)