VRP miscompiles the following testcase at -O2 (on a machine with 32-bit ints): #include <stdlib.h> void test(unsigned int a, unsigned int b) { if (a < 5) abort(); if (b < 5) abort(); if (a + b != 0) abort(); } int main() { unsigned int x = 0x80000000; test(x, x); } The t27.vrp dump shows why: ... D.1824_3: [10, 0fffffffe] EQUIVALENCES: { } (0 elements) a_4: [5, +INF] EQUIVALENCES: { a_1 } (1 elements) b_5: [5, +INF] EQUIVALENCES: { b_2 } (1 elements) Folding predicate D.1824_3 != 0 to 1 ... VRP concludes that since a >= 5 and b >= 5, a + b >= 10. However, since unsigned variables have wrapping semantics, this is incorrect. It then miscompiles test() to include an unconditional abort.
Confirmed.
Created attachment 9388 [details] Patch for a bunch of vrp problems
Subject: Bug 23128 CVSROOT: /cvs/gcc Module name: gcc Changes by: phython@gcc.gnu.org 2005-08-06 05:35:32 Modified files: gcc : ChangeLog tree-vrp.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: vrp-5.c vrp-6.c gcc/testsuite/gcc.dg/tree-ssa: vrp21.c Log message: 2005-08-05 James A. Morrison <phython@gcc.gnu.org> PR tree-optimization/23128 * tree-vrp.c (vrp_int_const_binop): Check if unsigned addition or subtraction wrap, and set TREE_OVERFLOW if they do. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.9665&r2=2.9666 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-vrp.c.diff?cvsroot=gcc&r1=2.48&r2=2.49 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5883&r2=1.5884 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/vrp-5.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/vrp-6.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp21.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed.