// Kudos to Yuriy Tsibizov for doing all dirty work hunting down miscompilation // of snd_emu10k1 driver in FreeBSD -CURRENT // small testcase, compile with -O1 -ftree-vrp void abort (void); struct T { int b : 1; } t; void __attribute__((noinline)) foo (int f) { t.b = (f & 0x10) ? 1 : 0; } int main (void) { foo (0x10); if (!t.b) abort (); return 0; }
Related to PR 23603.
D.1532_3 = D.1531_2 != 0; Found new range for D.1532_3: [0, +INF] So we have a "signed int:1" which we get the wrong range for. Confirmed, looking more into it.
set_value_range_to_nonnegative returns true which is wrong as the range of signed:1 is only [-1,0].
The fix: Index: fold-const.c =================================================================== --- fold-const.c (revision 125044) +++ fold-const.c (working copy) @@ -13485,9 +13485,14 @@ tree_expr_nonnegative_warnv_p (tree t, b /* ... fall through ... */ default: - if (truth_value_p (TREE_CODE (t))) - /* Truth values evaluate to 0 or 1, which is nonnegative. */ - return true; + { + tree type = TREE_TYPE (t); + if ((TYPE_PRECISION (t) != 1 || TYPE_UNSIGNED (t)) + &&truth_value_p (TREE_CODE (t))) + /* Truth values evaluate to 0 or 1, which is nonnegative unless we + have a signed:1 type (where the value is -1 and 0). */ + return true; + } } /* We don't know sign of `t', so be conservative and return false. */ The problem is that tree_expr_nonnegative_warnv_p is returning true for EQ_EXPR where the type is signed:1 where obvious the value is going to be -1/0 and not 0/1. Mine.
+ if ((TYPE_PRECISION (t) != 1 || TYPE_UNSIGNED (t)) Should obviously be: + if ((TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type)) This is why I should not change my patch after I made it working. Luckly this is why I did not apply it as obvious before doing a bootstrap/test :).
Subject: Bug 32100 Author: pinskia Date: Mon May 28 19:43:10 2007 New Revision: 125139 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=125139 Log: 2007-05-28 Andrew Pinski <andrew_pinski@playstation.sony.com> PR tree-opt/32100 * fold-const.c (tree_expr_nonnegative_warnv_p): Don't return true when truth_value_p is true and the type is of signed:1. 2007-05-28 Andrew Pinski <andrew_pinski@playstation.sony.com> PR tree-opt/32100 * gcc.c-torture/execute/vrp-7.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/vrp-7.c Modified: trunk/gcc/ChangeLog trunk/gcc/fold-const.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 32100 Author: pinskia Date: Mon May 28 19:47:53 2007 New Revision: 125140 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=125140 Log: 2007-05-28 Andrew Pinski <andrew_pinski@playstation.sony.com> PR tree-opt/32100 * fold-const.c (tree_expr_nonnegative_warnv_p): Don't return true when truth_value_p is true and the type is of signed:1. 2007-05-28 Andrew Pinski <andrew_pinski@playstation.sony.com> PR tree-opt/32100 * gcc.c-torture/execute/vrp-7.c: New test. Added: branches/gcc-4_2-branch/gcc/testsuite/gcc.c-torture/execute/vrp-7.c - copied unchanged from r125139, trunk/gcc/testsuite/gcc.c-torture/execute/vrp-7.c Modified: branches/gcc-4_2-branch/gcc/ChangeLog branches/gcc-4_2-branch/gcc/fold-const.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
Fixed.