[PATCH] Fix PR33563, another DSE miscompile

Richard Guenther rguenther@suse.de
Wed Sep 26 16:19:00 GMT 2007


We were not handling uses in aggregate stores.

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

Richard.

2007-09-26  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/33563
	* tree-ssa-dse.c (get_use_of_stmt_lhs): Rename to ...
	(get_kill_of_stmt_lhs): ... this.  Re-structure.  Handle
	aggregate stores.
	(dse_optimize_stmt): Call get_kill_of_stmt_lhs instead of
	get_use_of_stmt_lhs.

	* gcc.dg/torture/pr33563.c: New testcase.

Index: tree-ssa-dse.c
===================================================================
*** tree-ssa-dse.c	(revision 128810)
--- tree-ssa-dse.c	(working copy)
*************** memory_address_same (tree store1, tree s
*** 210,271 ****
  	  == NULL);
  }
  
! /* Return the use stmt for the lhs of STMT following the virtual
!    def-use chains.  Returns the MODIFY_EXPR stmt which lhs is equal to
!    the lhs of STMT or NULL_TREE if no such stmt can be found.  */
! static tree 
! get_use_of_stmt_lhs (tree stmt,
! 		     use_operand_p * first_use_p,
! 		     use_operand_p * use_p, tree * use_stmt)
  {
!   tree usevar, lhs;
!   def_operand_p def_p;
  
!   if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
!     return NULL_TREE;
  
    lhs = GIMPLE_STMT_OPERAND (stmt, 0);
  
!   /* The stmt must have a single VDEF.  */
!   def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_VDEF);
!   if (def_p == NULL_DEF_OPERAND_P)
!     return NULL_TREE;
! 
!   if (!has_single_use (DEF_FROM_PTR (def_p)))
!     return NULL_TREE;
!   /* Get the immediate use of the def.  */
!   single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt);
!   gcc_assert (*use_p != NULL_USE_OPERAND_P);
!   first_use_p = use_p;
! 
!   /* If the use is not simple, give up.  */
!   if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT
!       || get_call_expr_in (*use_stmt))
!     return NULL_TREE;
! 
    do
      {
!       /* Look at the use stmt and see if it's LHS matches
!          stmt's lhs SSA_NAME.  */
!       def_p = SINGLE_SSA_DEF_OPERAND (*use_stmt, SSA_OP_VDEF);
        if (def_p == NULL_DEF_OPERAND_P)
! 	return NULL_TREE;
  
!       usevar = GIMPLE_STMT_OPERAND (*use_stmt, 0);
!       if (operand_equal_p (usevar, lhs, 0))
! 	return *use_stmt;
! 
!       if (!has_single_use (DEF_FROM_PTR (def_p)))
! 	return NULL_TREE;
!       single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt);
!       gcc_assert (*use_p != NULL_USE_OPERAND_P);
!       if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT
! 	  || get_call_expr_in (*use_stmt))
! 	return NULL_TREE;
      }
    while (1);
- 
-   return NULL_TREE;
  }
  
  /* A helper of dse_optimize_stmt.
--- 210,271 ----
  	  == NULL);
  }
  
! /* Return true if there is a stmt that kills the lhs of STMT and is in the
!    virtual def-use chain of STMT without a use inbetween the kill and STMT.
!    Returns false if no such stmt is found.
!    *FIRST_USE_P is set to the first use of the single virtual def of
!    STMT.  *USE_P is set to the vop killed by *USE_STMT.  */
! 
! static bool
! get_kill_of_stmt_lhs (tree stmt,
! 		      use_operand_p * first_use_p,
!  		      use_operand_p * use_p, tree * use_stmt)
  {
!   tree lhs;
  
!   gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
  
    lhs = GIMPLE_STMT_OPERAND (stmt, 0);
  
!   /* We now walk the chain of single uses of the single VDEFs.
!      We succeeded finding a kill if the lhs of the use stmt is
!      equal to the original lhs.  We can keep walking to the next
!      use if there are no possible uses of the original lhs in
!      the stmt.  */
    do
      {
!       tree use_lhs, use_rhs;
!       def_operand_p def_p;
! 
!       /* The stmt must have a single VDEF.  */
!       def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_VDEF);
        if (def_p == NULL_DEF_OPERAND_P)
! 	return false;
  
!       /* Get the single immediate use of the def.  */
!       if (!single_imm_use (DEF_FROM_PTR (def_p), first_use_p, &stmt))
! 	return false;
!       first_use_p = use_p;
! 
!       /* If there are possible hidden uses, give up.  */
!       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
! 	return false;
!       use_rhs = GIMPLE_STMT_OPERAND (stmt, 1);
!       if (TREE_CODE (use_rhs) == CALL_EXPR
! 	  || (!is_gimple_min_invariant (use_rhs)
! 	      && TREE_CODE (use_rhs) != SSA_NAME))
! 	return false;
! 
!       /* If the use stmts lhs matches the original lhs we have
! 	 found the kill, otherwise continue walking.  */
!       use_lhs = GIMPLE_STMT_OPERAND (stmt, 0);
!       if (operand_equal_p (use_lhs, lhs, 0))
! 	{
! 	  *use_stmt = stmt;
! 	  return true;
! 	}
      }
    while (1);
  }
  
  /* A helper of dse_optimize_stmt.
*************** dse_optimize_stmt (struct dom_walk_data 
*** 448,455 ****
               the stores are not to the same memory location then walk the
               virtual def-use chain to get the stmt which stores to that same
               memory location.  */
!           if (get_use_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt) ==
!               NULL_TREE)
              {
                record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
                return;
--- 448,454 ----
               the stores are not to the same memory location then walk the
               virtual def-use chain to get the stmt which stores to that same
               memory location.  */
!           if (!get_kill_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt))
              {
                record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
                return;
Index: testsuite/gcc.dg/torture/pr33563.c
===================================================================
*** testsuite/gcc.dg/torture/pr33563.c	(revision 0)
--- testsuite/gcc.dg/torture/pr33563.c	(revision 0)
***************
*** 0 ****
--- 1,22 ----
+ /* { dg-do run } */
+ /* { dg-options "--param max-aliased-vops=0" } */
+ 
+ struct T
+ {
+   int a, b;
+ } t, q;
+ 
+ int main (void)
+ {
+   struct T *p;
+ 
+   t.a = 1;
+   t.b = 2;
+   q = t;
+   t.a = 3;
+ 
+   if (q.a != 1)
+     __builtin_abort ();
+ 
+   return 0;
+ }



More information about the Gcc-patches mailing list