Created attachment 41140 [details] Reproducer. GCC generates incorrect code. Correct result is 90. Reproducer: >$ cat foo.c extern const signed char var_25; extern signed char var_465; void foo() { var_465 = (unsigned short) var_25 / -55; } >$ cat main.c #include <stdio.h> extern void foo (); const signed char var_25 = -84; signed char var_465 = 0; int main () { foo (); printf("%d\n", (int) var_465); return 0; } Run: >$ gcc main.c foo.c ; ./a.out 1 GCC version: Rev. 246681 >$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/vsevolod/workspace/gcc-dev/bin-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /home/vsevolod/workspace/gcc-dev/trunk/configure --prefix=/home/vsevolod/workspace/gcc-dev/bin-trunk --disable-bootstrap Thread model: posix gcc version 7.0.1 20170404 (experimental) (GCC)
GCC 4.4 gives 90 but GCC 4.5 gives 1.
Better testcase: const signed char c = -84; signed char s; void foo () { s = (unsigned short) c / -55; } int main () { foo (); if (s != 90) __builtin_abort (); }
Likely started with commit 4d307e1ff39d0c2f90123ef789d611e2323be76d Author: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed Feb 10 11:54:14 2010 +0000 2010-02-10 Richard Guenther <rguenther@suse.de> PR c/43007 * tree.c (get_unwidened): Handle constants. * convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR. * gcc.c-torture/execute/20100209-1.c: New testcase. * gcc.dg/fold-div-3.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156653 138bc75d-0d04-0410-961f-82ee72b054a4
With -O I get x.c: In function ‘foo’: x.c:7:7: warning: overflow in implicit constant conversion [-Woverflow] s = (unsigned short) c / -55; ^
hmm, get_unwidened ((int) (short unsigned int) c) returns c?! I wonder if that's by design...
Ah, it is as we pass it signed char as 2nd arg...
Testing patch.
Author: rguenth Date: Fri Apr 7 08:20:24 2017 New Revision: 246756 URL: https://gcc.gnu.org/viewcvs?rev=246756&root=gcc&view=rev Log: 2017-04-07 Richard Biener <rguenther@suse.de> PR middle-end/80341 * tree.c (get_unwidened): Also handle ! for_type case for INTEGER_CSTs. * convert.c (do_narrow): Split out from ... (convert_to_integer_1): ... here. Do not pass final truncation type to get_unwidened for TRUNC_DIV_EXPR. * gcc.dg/torture/pr80341.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr80341.c Modified: trunk/gcc/ChangeLog trunk/gcc/convert.c trunk/gcc/testsuite/ChangeLog trunk/gcc/tree.c
Fixed on trunk sofar.
Author: rguenth Date: Thu Jun 22 07:30:03 2017 New Revision: 249499 URL: https://gcc.gnu.org/viewcvs?rev=249499&root=gcc&view=rev Log: 2017-06-22 Richard Biener <rguenther@suse.de> Backport from mainline 2017-04-20 Richard Biener <rguenther@suse.de> PR tree-optimization/80453 * tree-ssa-sccvn.h (struct vn_phi_s): Add cclhs and ccrhs members. * tree-ssa-sccvn.c (cond_stmts_equal_p): Use recorded lhs and rhs from the conditions. (vn_phi_eq): Pass them down. (vn_phi_lookup): Record them. (vn_phi_insert): Likewise. 2017-04-07 Richard Biener <rguenther@suse.de> PR middle-end/80341 * tree.c (get_unwidened): Also handle ! for_type case for INTEGER_CSTs. * convert.c (do_narrow): Split out from ... (convert_to_integer_1): ... here. Do not pass final truncation type to get_unwidened for TRUNC_DIV_EXPR. * gcc.dg/torture/pr80341.c: New testcase. 2017-04-04 Richard Biener <rguenther@suse.de> PR middle-end/80281 * match.pd (A + (-B) -> A - B): Make sure to preserve unsigned arithmetic done for the negate or the plus. Simplify. (A - (-B) -> A + B): Likewise. * fold-const.c (split_tree): Make sure to not negate pointers. * gcc.dg/torture/pr80281.c: New testcase. Modified: branches/gcc-6-branch/gcc/ChangeLog branches/gcc-6-branch/gcc/convert.c branches/gcc-6-branch/gcc/fold-const.c branches/gcc-6-branch/gcc/match.pd branches/gcc-6-branch/gcc/testsuite/ChangeLog branches/gcc-6-branch/gcc/tree-ssa-sccvn.c branches/gcc-6-branch/gcc/tree-ssa-sccvn.h branches/gcc-6-branch/gcc/tree.c
Author: rguenth Date: Mon Sep 18 11:10:06 2017 New Revision: 252920 URL: https://gcc.gnu.org/viewcvs?rev=252920&root=gcc&view=rev Log: 2017-09-18 Richard Biener <rguenther@suse.de> Backport from mainline 2017-04-07 Richard Biener <rguenther@suse.de> PR middle-end/80341 * gcc.dg/torture/pr80341.c: New testcase. 2017-04-04 Richard Biener <rguenther@suse.de> PR middle-end/80281 * gcc.dg/torture/pr80281.c: New testcase. Added: branches/gcc-6-branch/gcc/testsuite/gcc.dg/torture/pr80281.c branches/gcc-6-branch/gcc/testsuite/gcc.dg/torture/pr80341.c Modified: branches/gcc-6-branch/gcc/testsuite/ChangeLog
GCC 5 branch has been closed, should be fixed in GCC 6.4 and later.