Bug 70941 - [5 Regression] Test miscompiled with -O2.
Summary: [5 Regression] Test miscompiled with -O2.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 7.0
: P2 normal
Target Milestone: 5.4
Assignee: Richard Biener
URL:
Keywords: wrong-code
Depends on:
Blocks: yarpgen
  Show dependency treegraph
 
Reported: 2016-05-04 08:25 UTC by Vsevolod Livinskii
Modified: 2021-11-01 23:07 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-*-*
Build:
Known to work: 4.9.4, 6.2.0, 7.0
Known to fail: 5.3.1, 6.1.1
Last reconfirmed: 2016-05-04 00:00:00


Attachments
Reproducer. (140 bytes, text/x-csrc)
2016-05-04 08:25 UTC, Vsevolod Livinskii
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vsevolod Livinskii 2016-05-04 08:25:48 UTC
Created attachment 38409 [details]
Reproducer.

Test case produces incorrect result with -O2 option.

Output:
> g++ -O0 repr.cpp; ./a.out
-109
> g++ -O3 repr.cpp; ./a.out
-110

GCC version:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/export/users/vlivinsk/gcc-trunk/bin/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /export/users/gnutester/stability/svn/trunk/configure --prefix=/export/users/gnutester/stability/work/trunk/64/install --enable-bootstrap=no --enable-languages=c,c++,fortran
Thread model: posix
gcc version 7.0.0 20160430 (experimental) (GCC)

Testcase:
#include <iostream>
#include <cstdlib>

char a = 0, b = 0, c = 0, d = 0;
int main() {
    a = -(b - 405418259) - ((d && c) ^ 2040097152);
    if (a != -109)
        abort();
}
Comment 1 Jakub Jelinek 2016-05-04 08:35:08 UTC
Started with r217349.
Comment 2 Jakub Jelinek 2016-05-04 08:50:28 UTC
I'd say this is already wrong in the original dump, the narrowing is done wrongly:
*.original has:
  a = (char) (((unsigned char) -((signed char) (d != 0 && c != 0) ^ -128(OVF)) - (unsigned char) b) + 19);
The (OVF) looks fishy and especially the negation performed in signed char instead of unsigned.  So we then have in signed char types:
 _1 = _2 ^ -128;
 _3 = -_1;
and VRP figures out that for valid program that is only possible if _2 is non-zero (i.e. if d and c are both non-zero).
But ((d && c) ^ 2040097152) is in the source subtracted in int type rather than signed char due to promotion, so we need to use unsigned char arithmetics if we want to narrow it.
Comment 3 Richard Biener 2016-05-04 08:54:04 UTC
4.9 has

  (void) (a = (char) ((-(unsigned char) b - (unsigned char) ((signed char) ((signed char) d != 0 && (signed char) c != 0) ^ -128)) + 19)) >>>>>;
if ((signed char) a != -109)
Comment 4 Jakub Jelinek 2016-05-04 08:58:54 UTC
That looks fine indeed.
The r217348 to r217349 *.original diff is similar (there is already the (OVF), but that is probably not it, after all we strip OVF flag away during gimplification:
-  a = (char) ((-(unsigned char) b - (unsigned char) ((signed char) ((signed char) d != 0 && (signed char) c != 0) ^ -128(OVF))) + 19);
+  a = (char) (((unsigned char) -((signed char) ((signed char) d != 0 && (signed char) c != 0) ^ -128(OVF)) - (unsigned char) b) + 19);
Comment 5 Richard Biener 2016-05-04 09:19:15 UTC
Mine.
Comment 6 Richard Biener 2016-05-04 09:44:26 UTC
The negation issue is a latent fold-const.c issue which when folding

 (19 - (unsigned char) b) + (unsigned char) ((signed char) (d != 0 && c != 0) ^ -128(OVF))

runs into the associate: case.  We partially fixed this for an ICE with

2016-02-01  Bin Cheng  <bin.cheng@arm.com>

        PR tree-optimization/67921
        * fold-const.c (split_tree): New parameters.  Convert pointer
        type variable part to proper type before negating.
        (fold_binary_loc): Pass new arguments to split_tree.

but appearantly the "real" fix never materialized.
Comment 7 Richard Biener 2016-05-04 09:50:41 UTC
The following fixes this.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 235859)
+++ gcc/fold-const.c    (working copy)
@@ -838,9 +838,8 @@ split_tree (location_t loc, tree in, tre
        *conp = negate_expr (*conp);
       if (neg_var_p)
        {
-         /* Convert to TYPE before negating a pointer type expr.  */
-         if (var && POINTER_TYPE_P (TREE_TYPE (var)))
-           var = fold_convert_loc (loc, type, var);
+         /* Convert to TYPE before negating.  */
+         var = fold_convert_loc (loc, type, var);
          var = negate_expr (var);
        }
     }
@@ -863,9 +862,8 @@ split_tree (location_t loc, tree in, tre
       else if (*minus_litp)
        *litp = *minus_litp, *minus_litp = 0;
       *conp = negate_expr (*conp);
-      /* Convert to TYPE before negating a pointer type expr.  */
-      if (var && POINTER_TYPE_P (TREE_TYPE (var)))
-       var = fold_convert_loc (loc, type, var);
+      /* Convert to TYPE before negating.  */
+      var = fold_convert_loc (loc, type, var);
       var = negate_expr (var);
     }
Comment 8 Richard Biener 2016-05-06 07:38:59 UTC
Author: rguenth
Date: Fri May  6 07:38:27 2016
New Revision: 235943

URL: https://gcc.gnu.org/viewcvs?rev=235943&root=gcc&view=rev
Log:
2016-05-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/70941
	* fold-const.c (split_tree): Always convert to the original type
	before negating.

	* gcc.dg/torture/pr70941.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr70941.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 Richard Biener 2016-05-06 07:43:24 UTC
Fixed on trunk sofar.
Comment 10 Bill Seurer 2016-05-06 15:03:06 UTC
The new test case fails on powerpc64le:

> FAIL: gcc.dg/torture/pr70941.c   -O0  execution test
> FAIL: gcc.dg/torture/pr70941.c   -O1  execution test
> FAIL: gcc.dg/torture/pr70941.c   -O2  execution test
> FAIL: gcc.dg/torture/pr70941.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  execution test
> FAIL: gcc.dg/torture/pr70941.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  execution test
> FAIL: gcc.dg/torture/pr70941.c   -O3 -g  execution test
> FAIL: gcc.dg/torture/pr70941.c   -Os  execution test

seurer@genoa:~/gcc/build/gcc-test$ /home/seurer/gcc/build/gcc-test/gcc/xgcc -B/home/seurer/gcc/build/gcc-test/gcc/ /home/seurer/gcc/gcc-test/gcc/testsuite/gcc.dg/torture/pr70941.c -fno-diagnostics-show-caret -fdiagnostics-color=never -O2 -flto -fno-use-linker-plugin -flto-partition=none -g -lm -o ./pr70941.exe
seurer@genoa:~/gcc/build/gcc-test$ gdb ./pr70941.exe 
(gdb) break 11
Breakpoint 1 at 0x100004d8: file /home/seurer/gcc/gcc-test/gcc/testsuite/gcc.dg/torture/pr70941.c, line 11.
(gdb) run
Starting program: /home/seurer/gcc/build/gcc-test/pr70941.exe 

Breakpoint 1, main () at /home/seurer/gcc/gcc-test/gcc/testsuite/gcc.dg/torture/pr70941.c:12
12	    abort();
(gdb) print a
$1 = 147 '\223'
(gdb) c
Continuing.

Program received signal SIGABRT, Aborted.
0x00003fffb7d00a88 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) where
#0  0x00003fffb7d00a88 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00003fffb7d0686c in __GI_abort () at abort.c:89
#2  0x00000000100004dc in main () at /home/seurer/gcc/gcc-test/gcc/testsuite/gcc.dg/torture/pr70941.c:12
(
Comment 11 Jakub Jelinek 2016-05-06 15:05:50 UTC
unsigned char perhaps?  Let me fix up the testcase.
It has other non-portable assumptions.
Comment 12 Jakub Jelinek 2016-05-06 15:24:28 UTC
Author: jakub
Date: Fri May  6 15:23:56 2016
New Revision: 235978

URL: https://gcc.gnu.org/viewcvs?rev=235978&root=gcc&view=rev
Log:
	PR middle-end/70941
	* gcc.dg/torture/pr70941.c (abort): Remove prototype.
	(a, b, c, d): Change type from char to signed char.
	(main): Compare against (signed char) -1634678893 instead of
	hardcoded -109.  Use __builtin_abort instead of abort.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/torture/pr70941.c
Comment 13 Bill Seurer 2016-05-06 16:13:06 UTC
That fixed the issues on power, thanks!
Comment 14 Richard Biener 2016-05-13 13:23:14 UTC
Author: rguenth
Date: Fri May 13 13:22:42 2016
New Revision: 236210

URL: https://gcc.gnu.org/viewcvs?rev=236210&root=gcc&view=rev
Log:
2016-05-13  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2016-04-27  Richard Biener  <rguenther@suse.de>

	PR ipa/70760
	* tree-ssa-structalias.c (find_func_aliases_for_call): Use
	aggregate_value_p to determine if a function result is
	returned by reference.

	* g++.dg/ipa/ipa-pta-2.C: New testcase.
	* gcc.dg/ipa/ipa-pta-1.c: Adjust.

	2016-05-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/70931
	* dwarf2out.c (native_encode_initializer): Skip zero-sized fields.

	* gfortran.dg/pr70931.f90: New testcase.

	2016-05-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/70941
	* fold-const.c (split_tree): Always convert to the original type
	before negating.

	* gcc.dg/torture/pr70941.c: New testcase.

	2016-05-06  Jakub Jelinek  <jakub@redhat.com>
 
	PR middle-end/70941
	* gcc.dg/torture/pr70941.c (abort): Remove prototype.
	(a, b, c, d): Change type from char to signed char.
	(main): Compare against (signed char) -1634678893 instead of
	hardcoded -109.  Use __builtin_abort instead of abort.

Added:
    branches/gcc-6-branch/gcc/testsuite/g++.dg/ipa/ipa-pta-2.C
    branches/gcc-6-branch/gcc/testsuite/gcc.dg/torture/pr70941.c
    branches/gcc-6-branch/gcc/testsuite/gfortran.dg/pr70931.f90
Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/dwarf2out.c
    branches/gcc-6-branch/gcc/fold-const.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
    branches/gcc-6-branch/gcc/tree-ssa-structalias.c
Comment 15 Richard Biener 2016-05-20 08:51:38 UTC
Author: rguenth
Date: Fri May 20 08:51:06 2016
New Revision: 236497

URL: https://gcc.gnu.org/viewcvs?rev=236497&root=gcc&view=rev
Log:
2016-05-20  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2016-02-01  Bin Cheng  <bin.cheng@arm.com>

	PR tree-optimization/67921
	* fold-const.c (split_tree): New parameters.  Convert pointer
	type variable part to proper type before negating. 
	(fold_binary_loc): Pass new arguments to split_tree.

	* c-c++-common/ubsan/pr67921.c: New test.

	2016-05-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/70941
	* fold-const.c (split_tree): Always convert to the original type
	before negating.

	* gcc.dg/torture/pr70941.c: New testcase.

	2016-05-06  Jakub Jelinek  <jakub@redhat.com>
 
	PR middle-end/70941
	* gcc.dg/torture/pr70941.c (abort): Remove prototype.
	(a, b, c, d): Change type from char to signed char.
	(main): Compare against (signed char) -1634678893 instead of
	hardcoded -109.  Use __builtin_abort instead of abort.
 
	2016-05-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/70931
	* dwarf2out.c (native_encode_initializer): Skip zero-sized fields.

	* gfortran.dg/pr70931.f90: New testcase.

	2016-04-14  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/70623
	* tree-ssa-pre.c (changed_blocks): Make global ...
	(compute_antic): ... local here.  Move and fix worklist
	handling here.  Do not clear EDGE_DFS_BACK.
	(compute_antic_aux): Add dumping for MAX assumed succs.  Remove
	worklist handling, dump when ANTIC_IN changed.
	(compute_partial_antic_aux): Remove worklist handling.
	(init_pre): Do not compute post dominators.  Add a comment about
	the CFG order chosen.
	(fini_pre): Do not free post dominators.

	* gcc.dg/torture/pr70623.c: New testcase.
	* gcc.dg/torture/pr70623-2.c: Likewise.

	2016-04-25  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/70780
	* tree-ssa-pre.c (compute_antic_aux): Also return true if the block
	wasn't visited yet.
	(compute_antic): Mark blocks with abnormal preds as visited as
	they have a final empty antic-in solution already.

	* gcc.dg/torture/pr70780.c: New testcase.

Added:
    branches/gcc-5-branch/gcc/testsuite/c-c++-common/ubsan/pr67921.c
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/torture/pr70623-2.c
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/torture/pr70623.c
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/torture/pr70780.c
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/torture/pr70941.c
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/pr70931.f90
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/dwarf2out.c
    branches/gcc-5-branch/gcc/fold-const.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
    branches/gcc-5-branch/gcc/tree-ssa-pre.c
Comment 16 Richard Biener 2016-05-20 08:52:15 UTC
Fixed.