GCC 4.8.2 for i686 miscompiles the following code. $ cat error.c int main (void) { int a = -1; int b = 2147483647; int c = 2; int t = 1 - ((a - b) / c); // t = 1 - ( -2147483648 / 2 ) if (t != 1073741825) { __builtin_abort(); } return 0; } $ i686-pc-linux-gnu-gcc-4.8.2 error.c -O2 $ ./a.out Aborted (core dumped) There was no problem with an x86_64 target. $ i686-pc-linux-gnu-gcc-4.8.2 -v Using built-in specs. COLLECT_GCC=i686-pc-linux-gnu-gcc-4.8.2 COLLECT_LTO_WRAPPER=/usr/local/i686-tools/gcc-4.8.2/libexec/gcc/i686-pc-linux-gnu/4.8.2/lto-wrapper Target: i686-pc-linux-gnu Configured with: /home/hassy/gcc/configure --prefix=/usr/local/i686-tools/gcc-4.8.2/ --with-gmp=/usr/local/gmp-5.1.1/ --with-mpfr=/usr/local/mpfr-3.1.2/ --with-mpc=/usr/local/mpc-1.0.1/ --disable-multilib --disable-nls --enable-languages=c Thread model: posix gcc version 4.8.2 20130607 (prerelease) (GCC)
Most likely broken by the r117969 changes.
Mine.
Created attachment 30352 [details] patch Fails at -O0 -fstrict-overflow as we fold int t = 1 - (a - b) / c; into int t = (b - a) / c + 1; The change in r117969 exposed a bug in negate_expr_p, namely that we cannot negate (a - b) / c as (b - a) / c because that associates the negate with the division which exposes possible undefined overflow in -(a - b) that is not there in the original expression for c != +-1. This is a bit a problem with the negate_expr_p specification - the API doesn't specify whether we are removing an existing negate or whether we are adding one. This case removes one from the division and adds it to the subtraction. -(a - b) -> (b - a) is ok, but (a - b) -> -(b - a) is not - the API doesn't really distinguish these two cases but in the MINUS_EXPR case clearly implements -(a - b) -> (b - a). Testing the attached.
Author: rguenth Date: Tue Sep 3 10:00:06 2013 New Revision: 202204 URL: http://gcc.gnu.org/viewcvs?rev=202204&root=gcc&view=rev Log: 2013-09-03 Richard Biener <rguenther@suse.de> PR middle-end/57656 * fold-const.c (negate_expr_p): Fix division case. (negate_expr): Likewise. * gcc.dg/torture/pr57656.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr57656.c Modified: trunk/gcc/ChangeLog trunk/gcc/fold-const.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk sofar.
Author: rguenth Date: Mon Sep 9 09:49:54 2013 New Revision: 202387 URL: http://gcc.gnu.org/viewcvs?rev=202387&root=gcc&view=rev Log: 2013-09-09 Richard Biener <rguenther@suse.de> Backport from mainline 2013-09-03 Richard Biener <rguenther@suse.de> PR middle-end/57656 * fold-const.c (negate_expr_p): Fix division case. (negate_expr): Likewise. * gcc.dg/torture/pr57656.c: New testcase. Added: branches/gcc-4_8-branch/gcc/testsuite/gcc.dg/torture/pr57656.c Modified: branches/gcc-4_8-branch/gcc/ChangeLog branches/gcc-4_8-branch/gcc/fold-const.c branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Author: rguenth Date: Tue Mar 18 08:46:21 2014 New Revision: 208632 URL: http://gcc.gnu.org/viewcvs?rev=208632&root=gcc&view=rev Log: 2014-03-18 Richard Biener <rguenther@suse.de> Backport from mainline 2013-08-27 Richard Biener <rguenther@suse.de> PR tree-optimization/57521 * tree-if-conv.c (if_convertible_bb_p): Verify that at least one edge is non-critical. (find_phi_replacement_condition): Make sure to use a non-critical edge. Cleanup and remove old bug workarounds. (bb_postdominates_preds): Remove. (if_convertible_loop_p_1): Do not compute post-dominators. (combine_blocks): Do not free post-dominators. (main_tree_if_conversion): Likewise. * gcc.dg/torture/pr57521.c: New testcase. 2013-09-03 Richard Biener <rguenther@suse.de> PR middle-end/57656 * fold-const.c (negate_expr_p): Fix division case. (negate_expr): Likewise. * gcc.dg/torture/pr57656.c: New testcase. 2013-11-19 Richard Biener <rguenther@suse.de> PR tree-optimization/57517 * tree-predcom.c (combinable_refs_p): Verify the combination is always executed when the refs are. * gfortran.fortran-torture/compile/pr57517.f90: New testcase. * gcc.dg/torture/pr57517.c: Likewise. Added: branches/gcc-4_7-branch/gcc/testsuite/gcc.dg/torture/pr57517.c branches/gcc-4_7-branch/gcc/testsuite/gcc.dg/torture/pr57521.c branches/gcc-4_7-branch/gcc/testsuite/gcc.dg/torture/pr57656.c branches/gcc-4_7-branch/gcc/testsuite/gfortran.fortran-torture/compile/pr57517.f90 Modified: branches/gcc-4_7-branch/gcc/ChangeLog branches/gcc-4_7-branch/gcc/fold-const.c branches/gcc-4_7-branch/gcc/testsuite/ChangeLog branches/gcc-4_7-branch/gcc/tree-if-conv.c branches/gcc-4_7-branch/gcc/tree-predcom.c
Fixed.