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(); }
Started with r217349.
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.
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)
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);
Mine.
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.
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); }
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
Fixed on trunk sofar.
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 (
unsigned char perhaps? Let me fix up the testcase. It has other non-portable assumptions.
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
That fixed the issues on power, thanks!
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
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
Fixed.