This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR56273
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 11 Feb 2013 14:02:39 +0100 (CET)
- Subject: [PATCH] Fix PR56273
This is another -Warray-bounds false-positive triggered by more
aggressive loop unrolling. Fortunately VRP has everything available
to compute correct bounds - if it were not for VRP itself pessimizing
itself (it runs twice after all) by folding predicates from
a < C to a != C (and similar transforms). While the folded variant
is better for code-gen it's worse for analysis. Thus the following
patch defers that to the 2nd run of VRP.
Bootstrapped and tested on x86_64-unknown-linux-gnu, testing in progress.
Richard.
2013-02-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/56273
* tree-vrp.c (simplify_cond_using_ranges): Disable for the
first VRP run.
(check_array_ref): Fix missing newline in dumps.
(search_for_addr_array): Likewise.
* g++.dg/warn/Warray-bounds-6.C: New testcase.
* gcc.dg/tree-ssa/pr21559.c: Adjust.
* gcc.dg/tree-ssa/vrp17.c: Likewise.
* gcc.dg/tree-ssa/vrp18.c: Likewise.
* gcc.dg/tree-ssa/vrp23.c: Likewise.
* gcc.dg/tree-ssa/vrp24.c: Likewise.
Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c (revision 195938)
--- gcc/tree-vrp.c (working copy)
*************** check_array_ref (location_t location, tr
*** 6027,6032 ****
--- 6022,6028 ----
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
+ fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
"array subscript is above array bounds");
*************** check_array_ref (location_t location, tr
*** 6039,6044 ****
--- 6035,6041 ----
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
+ fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
"array subscript is below array bounds");
*************** search_for_addr_array (tree t, location_
*** 6112,6117 ****
--- 6109,6115 ----
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
+ fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
"array subscript is below array bounds");
*************** search_for_addr_array (tree t, location_
*** 6125,6130 ****
--- 6123,6129 ----
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
+ fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
"array subscript is above array bounds");
*************** test_for_singularity (enum tree_code con
*** 8499,8507 ****
return NULL;
}
! /* Simplify a conditional using a relational operator to an equality
! test if the range information indicates only one value can satisfy
! the original conditional. */
static bool
simplify_cond_using_ranges (gimple stmt)
--- 8498,8505 ----
return NULL;
}
! /* Simplify the conditional stmt STMT using final range information.
! Return true if we simplified the statement. */
static bool
simplify_cond_using_ranges (gimple stmt)
*************** simplify_cond_using_ranges (gimple stmt)
*** 8510,8516 ****
tree op1 = gimple_cond_rhs (stmt);
enum tree_code cond_code = gimple_cond_code (stmt);
! if (cond_code != NE_EXPR
&& cond_code != EQ_EXPR
&& TREE_CODE (op0) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
--- 8508,8520 ----
tree op1 = gimple_cond_rhs (stmt);
enum tree_code cond_code = gimple_cond_code (stmt);
! /* Simplify a conditional using a relational operator to an equality
! test if the range information indicates only one value can satisfy
! the original conditional.
! Do that only in the second VRP pass as otherwise assertions derived
! from this predicate are weakened. */
! if (!first_pass_instance
! && cond_code != NE_EXPR
&& cond_code != EQ_EXPR
&& TREE_CODE (op0) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
Index: gcc/testsuite/g++.dg/warn/Warray-bounds-6.C
===================================================================
*** gcc/testsuite/g++.dg/warn/Warray-bounds-6.C (revision 0)
--- gcc/testsuite/g++.dg/warn/Warray-bounds-6.C (working copy)
***************
*** 0 ****
--- 1,30 ----
+ // { dg-do compile }
+ // { dg-options "-O3 -Warray-bounds" }
+
+ struct type {
+ bool a, b;
+ bool get_b() { return b; }
+ };
+
+ type stuff[9u];
+
+ void bar();
+
+ void foo() {
+
+ for(unsigned i = 0u; i < 9u; i++) {
+
+ if(!stuff[i].a) {
+ continue;
+ }
+
+ bar();
+
+ for(unsigned j = i + 1u; j < 9u; j++) {
+ if(stuff[j].a && stuff[j].get_b()) { // { dg-bogus "array bounds" }
+ return;
+ }
+ }
+
+ }
+ }
Index: gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/pr21559.c (revision 195938)
--- gcc/testsuite/gcc.dg/tree-ssa/pr21559.c (working copy)
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
static int blocksize = 4096;
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp-details" } */
static int blocksize = 4096;
*************** void foo (void)
*** 32,38 ****
/* First, we should simplify the bits < 0 test within the loop. */
! /* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
/* Second, we should thread the edge out of the loop via the break
statement. We also realize that the final bytes == 0 test is useless,
--- 32,38 ----
/* First, we should simplify the bits < 0 test within the loop. */
! /* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp2" } } */
/* Second, we should thread the edge out of the loop via the break
statement. We also realize that the final bytes == 0 test is useless,
*************** void foo (void)
*** 40,43 ****
/* { dg-final { scan-tree-dump-times "Threaded jump" 3 "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
!
--- 40,43 ----
/* { dg-final { scan-tree-dump-times "Threaded jump" 3 "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp2" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp17.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp17.c (revision 195938)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp17.c (working copy)
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
extern void abort (void) __attribute__ ((__noreturn__));
union tree_node;
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp2" } */
extern void abort (void) __attribute__ ((__noreturn__));
union tree_node;
*************** gimplify_for_stmt (tree stmt)
*** 27,32 ****
abort ();
}
! /* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 27,32 ----
abort ();
}
! /* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp2" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp18.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp18.c (revision 195938)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp18.c (working copy)
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
static int blocksize = 4096;
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp2" } */
static int blocksize = 4096;
*************** void foo (void)
*** 30,34 ****
eof_reached = 1;
}
! /* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 30,34 ----
eof_reached = 1;
}
! /* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp2" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp23.c (revision 195938)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp23.c (working copy)
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
blah (int code1, int code2)
{
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp2-details" } */
blah (int code1, int code2)
{
*************** L8:
*** 40,45 ****
/* The n_sets > 0 test can be simplified into n_sets == 1 since the
only way to reach the test is when n_sets <= 1, and the only value
which satisfies both conditions is n_sets == 1. */
! /* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp1" } } */
!
--- 40,44 ----
/* The n_sets > 0 test can be simplified into n_sets == 1 since the
only way to reach the test is when n_sets <= 1, and the only value
which satisfies both conditions is n_sets == 1. */
! /* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp2" } } */
! /* { dg-final { cleanup-tree-dump "vrp2" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp24.c (revision 195938)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp24.c (working copy)
***************
*** 1,6 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
!
struct rtx_def;
typedef struct rtx_def *rtx;
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp2-details" } */
struct rtx_def;
typedef struct rtx_def *rtx;
*************** L7:
*** 86,91 ****
The second n_sets > 0 test can also be simplified into n_sets == 1
as the only way to reach the tests is when n_sets <= 1 and the only
value which satisfies both conditions is n_sets == 1. */
! /* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp1" } } */
! /* { dg-final { cleanup-tree-dump "vrp1" } } */
!
--- 85,89 ----
The second n_sets > 0 test can also be simplified into n_sets == 1
as the only way to reach the tests is when n_sets <= 1 and the only
value which satisfies both conditions is n_sets == 1. */
! /* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp2" } } */
! /* { dg-final { cleanup-tree-dump "vrp2" } } */