The following is the minimal approach to fix this -Warray-bound at this stage. We're pretty bad at optimizing range tests that get optimizable during GIMPLE only (fold can handle quite some cases). Too bad to optimize this before VRP gets to warn about out-of-bound array accesses. Later reassoc handles this case, but pass reordering at this stage is not appropriate.
So the following implements range test simplifications that result in true/false to catch not executable code early. In the past I've always pondered that we need some better infrastructure for collecting and combining conditions (similar to what we have with tree-affine for affine combinations). We have multiple passes dealing with a subset of condition combinations (CFG / non-CFG, re-writing and just statically computing). Sharing this with some proper infrastructure is the way to go. I pondered to deal with this case in VRP itself but it doesn't really fit there. The patch handles slightly more cases than necessary for the PR (in particular the && variant). Bootstrap & regtest running on x86_64-unknown-linux-gnu. Richard. 2016-02-02 Richard Biener <rguent...@suse.de> PR tree-optimization/69595 * match.pd: Add range test simplifications to true/false. * gcc.dg/Warray-bounds-17.c: New testcase. Index: gcc/match.pd =================================================================== *** gcc/match.pd (revision 233067) --- gcc/match.pd (working copy) *************** DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) *** 2094,2099 **** --- 2094,2117 ---- (bit_and:c (ordered @0 @0) (ordered:c@2 @0 @1)) @2) + /* Simple range test simplifications. */ + /* A < B || A >= B -> true. */ + (for test1 (lt le ne) + test2 (ge gt eq) + (simplify + (bit_ior:c (test1 @0 @1) (test2 @0 @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || VECTOR_INTEGER_TYPE_P (TREE_TYPE (@0))) + { constant_boolean_node (true, type); }))) + /* A < B && A >= B -> false. */ + (for test1 (lt lt lt le ne eq) + test2 (ge gt eq gt eq gt) + (simplify + (bit_and:c (test1 @0 @1) (test2 @0 @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || VECTOR_INTEGER_TYPE_P (TREE_TYPE (@0))) + { constant_boolean_node (false, type); }))) + /* -A CMP -B -> B CMP A. */ (for cmp (tcc_comparison) scmp (swapped_tcc_comparison) Index: gcc/testsuite/gcc.dg/Warray-bounds-17.c =================================================================== *** gcc/testsuite/gcc.dg/Warray-bounds-17.c (revision 0) --- gcc/testsuite/gcc.dg/Warray-bounds-17.c (working copy) *************** *** 0 **** --- 1,13 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -Warray-bounds" } */ + + char *y; + void foo (int sysnum) + { + static char *x[] = {}; + int nsyscalls = sizeof x / sizeof x[0]; + if (sysnum < 0 || sysnum >= nsyscalls) + return; + else + y = x[sysnum]; /* { dg-bogus "above array bounds" } */ + }