fold and VRP interact badly if we have a range test like if (i > 0 && i <=5) ... as we fold that to if ((unsigned int) i + 0x0ffffffff > 4) ... for which VRP fails to extract a range for i. If we write the range test so that fold doesn't see it, VRP is happy: if (i > 0) if (i <= 5) ...
I think the range folding should late in compiling after VRP2 happens. This will also help out code that is written like: if (i > 0) if (i <= 5)
I teached VRP to look for this idiom and during a C only bootstrap on i686 this triggers 28921 times.
Created attachment 12929 [details] patch This is what I currently have for this - it fails to bootstrap because it miscompares. A variant without the support for the anti-range tests if (a < 1 || a > 5) aka if ((unsigned)a - 1 > 4) bootstraps and tests ok, but the above adds useful things, so... I guess the hunk in extract_range_from_assert may do the wrong thing in some cases, but I didn't find a testcase for it.
Created attachment 13013 [details] alternate patch This patch tackes the issue by allowing a_2 = ASSERT_EXRP <a_1, (unsigned)a_1 + 5 <= 10> (and similar expressions). A variant of this patch which had not undergone a last-minute cosmetic cleanup survivied all-languages bootstrap and regtest on x86_64-unknown-linux-gnu.
Subject: Bug 30317 Author: rguenth Date: Fri Mar 28 12:20:09 2008 New Revision: 133680 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=133680 Log: 2008-03-28 Richard Guenther <rguenther@suse.de> PR tree-optimization/30317 PR tree-optimization/30911 PR tree-optimization/34793 * tree-vrp.c (set_and_canonicalize_value_range): New function. (struct assert_locus_d): New member EXPR. (register_new_assert_for): Add EXPR parameter to support ASSERT_EXPR <name, expr OP limit>. (register_edge_assert_for_1): Adjust callers. (find_assert_locations): Likewise. (process_assert_insertions_for): Build condition from expression. (extract_range_from_assert): Handle ASSERT_EXPRs of the form ASSERT_EXPR <name, expr OP limit>. (register_edge_assert_for_2): New helper registering asserts for comparisons. Recognize range tests of the form (unsigned)i - CST1 OP CST2. (register_edge_assert_for_1): Use it. (register_edge_assert_for): Likewise. * tree.def (ASSERT_EXPR): Document extra allowed conditional expressions. (needs_overflow_infinity): Integer sub-types do not need overflow infinities. (vrp_val_is_max): The extreme values of integer sub-types are those of the base type. (vrp_val_is_min): Likewise. * gcc.dg/tree-ssa/vrp35.c: New testcase. * gcc.dg/tree-ssa/vrp36.c: Likewise. * gcc.dg/tree-ssa/vrp37.c: Likewise. Added: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp37.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-vrp.c trunk/gcc/tree.def
Fixed.
*** Bug 41477 has been marked as a duplicate of this bug. ***