This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]