Bug 57656 - [4.7 Regression] Wrong constant folding
Summary: [4.7 Regression] Wrong constant folding
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: 4.7.4
Assignee: Richard Biener
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-19 22:10 UTC by Ishiura Lab Compiler Team
Modified: 2014-03-18 08:47 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 4.8.2, 4.9.0
Known to fail: 4.8.1
Last reconfirmed: 2013-06-20 00:00:00


Attachments
patch (1.21 KB, patch)
2013-06-24 11:54 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ishiura Lab Compiler Team 2013-06-19 22:10:01 UTC
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)
Comment 1 Jakub Jelinek 2013-06-20 06:14:35 UTC
Most likely broken by the r117969 changes.
Comment 2 Richard Biener 2013-06-20 09:06:02 UTC
Mine.
Comment 3 Richard Biener 2013-06-24 11:54:55 UTC
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.
Comment 4 Richard Biener 2013-09-03 10:00:08 UTC
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
Comment 5 Richard Biener 2013-09-03 10:00:33 UTC
Fixed on trunk sofar.
Comment 6 Richard Biener 2013-09-09 09:49:56 UTC
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
Comment 7 Richard Biener 2014-03-18 08:46:53 UTC
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
Comment 8 Richard Biener 2014-03-18 08:47:09 UTC
Fixed.