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 PR54109


This fixes another case where re-constructing ARRAY_REFs that were
not in the IL produced by the frontend produces bogus IL.  This
time an ICE only, but in other cases this results in wrong-code
because of constraints we impose on ARRAY_REFs in data-dependence
analysis for example.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-08-10  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/54109
	* tree-ssa-forwprop.c
	(forward_propagate_addr_into_variable_array_index): Remove.
	(forward_propagate_addr_expr_1): Adjust.

	* gcc.dg/torture/pr54109.c: New testcase.
	* gcc.dg/tree-ssa/forwprop-1.c: Adjust.
	* gcc.dg/tree-ssa/forwprop-2.c: Likewise.

Index: trunk/gcc/testsuite/gcc.dg/torture/pr54109.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/torture/pr54109.c	2012-08-09 16:21:12.145568259 +0200
***************
*** 0 ****
--- 1,29 ----
+ /* { dg-do compile } */
+ 
+ typedef struct
+ {
+   unsigned long bits[4];
+ } nodemask_t;
+ 
+ struct cpuset
+ {
+   long flags;
+   nodemask_t mems_allowed;
+   struct cpuset *parent;
+ } b;
+ 
+ void func1(unsigned long *p1, int p2)
+ {
+   p1[p2 - 1] = 0;
+ }
+ 
+ void func2(nodemask_t *p1, int p2)
+ {
+   func1(p1->bits, p2);
+ }
+ 
+ void func3(void)
+ {
+   /* This accesses b.flags.  */
+   func2(&b.mems_allowed, 0);
+ }
Index: trunk/gcc/tree-ssa-forwprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-forwprop.c	2012-08-09 16:20:28.000000000 +0200
--- trunk/gcc/tree-ssa-forwprop.c	2012-08-09 16:21:12.147568259 +0200
*************** tidy_after_forward_propagate_addr (gimpl
*** 697,824 ****
       recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
  }
  
- /* DEF_RHS contains the address of the 0th element in an array.
-    USE_STMT uses type of DEF_RHS to compute the address of an
-    arbitrary element within the array.  The (variable) byte offset
-    of the element is contained in OFFSET.
- 
-    We walk back through the use-def chains of OFFSET to verify that
-    it is indeed computing the offset of an element within the array
-    and extract the index corresponding to the given byte offset.
- 
-    We then try to fold the entire address expression into a form
-    &array[index].
- 
-    If we are successful, we replace the right hand side of USE_STMT
-    with the new address computation.  */
- 
- static bool
- forward_propagate_addr_into_variable_array_index (tree offset,
- 						  tree def_rhs,
- 						  gimple_stmt_iterator *use_stmt_gsi)
- {
-   tree index, tunit;
-   gimple offset_def, use_stmt = gsi_stmt (*use_stmt_gsi);
-   tree new_rhs, tmp;
- 
-   if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == ARRAY_REF)
-     tunit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)));
-   else if (TREE_CODE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))) == ARRAY_TYPE)
-     tunit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TREE_TYPE (def_rhs))));
-   else
-     return false;
-   if (!host_integerp (tunit, 1))
-     return false;
- 
-   /* Get the offset's defining statement.  */
-   offset_def = SSA_NAME_DEF_STMT (offset);
- 
-   /* Try to find an expression for a proper index.  This is either a
-      multiplication expression by the element size or just the ssa name we came
-      along in case the element size is one. In that case, however, we do not
-      allow multiplications because they can be computing index to a higher
-      level dimension (PR 37861). */
-   if (integer_onep (tunit))
-     {
-       if (is_gimple_assign (offset_def)
- 	  && gimple_assign_rhs_code (offset_def) == MULT_EXPR)
- 	return false;
- 
-       index = offset;
-     }
-   else
-     {
-       /* The statement which defines OFFSET before type conversion
-          must be a simple GIMPLE_ASSIGN.  */
-       if (!is_gimple_assign (offset_def))
- 	return false;
- 
-       /* The RHS of the statement which defines OFFSET must be a
- 	 multiplication of an object by the size of the array elements.
- 	 This implicitly verifies that the size of the array elements
- 	 is constant.  */
-      if (gimple_assign_rhs_code (offset_def) == MULT_EXPR
- 	 && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
- 	 && tree_int_cst_equal (gimple_assign_rhs2 (offset_def), tunit))
-        {
- 	 /* The first operand to the MULT_EXPR is the desired index.  */
- 	 index = gimple_assign_rhs1 (offset_def);
-        }
-      /* If we have idx * tunit + CST * tunit re-associate that.  */
-      else if ((gimple_assign_rhs_code (offset_def) == PLUS_EXPR
- 	       || gimple_assign_rhs_code (offset_def) == MINUS_EXPR)
- 	      && TREE_CODE (gimple_assign_rhs1 (offset_def)) == SSA_NAME
- 	      && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
- 	      && (tmp = div_if_zero_remainder (EXACT_DIV_EXPR,
- 					       gimple_assign_rhs2 (offset_def),
- 					       tunit)) != NULL_TREE)
-        {
- 	 gimple offset_def2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (offset_def));
- 	 if (is_gimple_assign (offset_def2)
- 	     && gimple_assign_rhs_code (offset_def2) == MULT_EXPR
- 	     && TREE_CODE (gimple_assign_rhs2 (offset_def2)) == INTEGER_CST
- 	     && tree_int_cst_equal (gimple_assign_rhs2 (offset_def2), tunit))
- 	   {
- 	     index = fold_build2 (gimple_assign_rhs_code (offset_def),
- 				  TREE_TYPE (offset),
- 				  gimple_assign_rhs1 (offset_def2), tmp);
- 	   }
- 	 else
- 	   return false;
-        }
-      else
- 	return false;
-     }
- 
-   /* Replace the pointer addition with array indexing.  */
-   index = force_gimple_operand_gsi (use_stmt_gsi, index, true, NULL_TREE,
- 				    true, GSI_SAME_STMT);
-   if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == ARRAY_REF)
-     {
-       new_rhs = unshare_expr (def_rhs);
-       TREE_OPERAND (TREE_OPERAND (new_rhs, 0), 1) = index;
-     }
-   else
-     {
-       new_rhs = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (TREE_TYPE (def_rhs))),
- 			unshare_expr (TREE_OPERAND (def_rhs, 0)),
- 			index, integer_zero_node, NULL_TREE);
-       new_rhs = build_fold_addr_expr (new_rhs);
-       if (!useless_type_conversion_p (TREE_TYPE (gimple_assign_lhs (use_stmt)),
- 				      TREE_TYPE (new_rhs)))
- 	{
- 	  new_rhs = force_gimple_operand_gsi (use_stmt_gsi, new_rhs, true,
- 					      NULL_TREE, true, GSI_SAME_STMT);
- 	  new_rhs = fold_convert (TREE_TYPE (gimple_assign_lhs (use_stmt)),
- 				  new_rhs);
- 	}
-     }
-   gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
-   fold_stmt (use_stmt_gsi);
-   tidy_after_forward_propagate_addr (gsi_stmt (*use_stmt_gsi));
-   return true;
- }
- 
  /* NAME is a SSA_NAME representing DEF_RHS which is of the form
     ADDR_EXPR <whatever>.
  
--- 697,702 ----
*************** forward_propagate_addr_expr_1 (tree name
*** 1111,1129 ****
        return true;
      }
  
-   /* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
-      converting a multiplication of an index by the size of the
-      array elements, then the result is converted into the proper
-      type for the arithmetic.  */
-   if (TREE_CODE (rhs2) == SSA_NAME
-       && (TREE_CODE (array_ref) != ARRAY_REF
- 	  || integer_zerop (TREE_OPERAND (array_ref, 1)))
-       && useless_type_conversion_p (TREE_TYPE (name), TREE_TYPE (def_rhs))
-       /* Avoid problems with IVopts creating PLUS_EXPRs with a
- 	 different type than their operands.  */
-       && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
-     return forward_propagate_addr_into_variable_array_index (rhs2, def_rhs,
- 							     use_stmt_gsi);
    return false;
  }
  
--- 989,994 ----
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/forwprop-1.c	2010-07-01 10:55:03.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-1.c	2012-08-09 16:25:48.666558686 +0200
***************
*** 1,8 ****
  /* { dg-do compile } */
  /* { dg-options "-O2 -fdump-tree-forwprop1" }  */
  
! /* We should be able to optimize this to b->t[i] = 1 during
!    early optimizations.  */
  
  struct a
  {
--- 1,7 ----
  /* { dg-do compile } */
  /* { dg-options "-O2 -fdump-tree-forwprop1" }  */
  
! /* We may not optimize this to b->t[i] = 1.  */
  
  struct a
  {
*************** void f(struct a * b, __SIZE_TYPE__ i)
*** 15,19 ****
    c[i] = 1;
  }
  
! /* { dg-final { scan-tree-dump-times "t\\\[i.*\\\].* = 1;" 1 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- 14,18 ----
    c[i] = 1;
  }
  
! /* { dg-final { scan-tree-dump-times "\\\[\[^\n\r\]*\\\] = 1;" 0 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/forwprop-2.c	2010-07-01 10:55:03.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-2.c	2012-08-09 16:26:38.180557015 +0200
***************
*** 1,8 ****
  /* { dg-do compile } */
  /* { dg-options "-O2 -fdump-tree-forwprop1" }  */
  
! /* We should be able to optimize this to b->t[i] = 1 during
!    early optimizations.  */
  
  struct a
  {
--- 1,7 ----
  /* { dg-do compile } */
  /* { dg-options "-O2 -fdump-tree-forwprop1" }  */
  
! /* We may not optimize this to b->t[i] = 1.  */
  
  struct a
  {
*************** void f(__SIZE_TYPE__ i)
*** 17,21 ****
    c[i] = 1;
  }
  
! /* { dg-final { scan-tree-dump-times "t\\\[i.*\\\].* = 1;" 1 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop?" } } */
--- 16,20 ----
    c[i] = 1;
  }
  
! /* { dg-final { scan-tree-dump-times "\\\[\[^\n\r\]*\\\] = 1;" 0 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop?" } } */


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