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 PR37056, tuplification problems in tree-ssa-loop-niter.c


This fixes an oversight in tuplification of get_val_for where unary
operations (such as conversions in this particular case) were simply
stripped.  The patch below re-organizes the code and introduces a
new helper for get_gimple_rhs_class (gimple_assign_rhs_code (gs))
(which causes quite some long lines elsewhere in the compiler - a
janitorial task would be to convert them all).

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

Richard.

2008-08-08  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/37056
	* gimple.h (gimple_assign_rhs_class): New helper function.
	* tree-ssa-loop-niter.c (get_val_for): Fix tuplification, handle
	unary operations properly.

	* gcc.c-torture/compile/pr37056.c: New testcase.

Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 138834)
--- gcc/gimple.h	(working copy)
*************** gimple_assign_set_rhs_code (gimple s, en
*** 1834,1839 ****
--- 1834,1850 ----
  }
  
  
+ /* Return the gimple rhs class of the code of the expression computed on
+    the rhs of assignment statement GS.
+    This will never return GIMPLE_INVALID_RHS.  */
+ 
+ static inline enum gimple_rhs_class
+ gimple_assign_rhs_class (const_gimple gs)
+ {
+   return get_gimple_rhs_class (gimple_assign_rhs_code (gs));
+ }
+ 
+ 
  /* Return true if S is a type-cast assignment.  */
  
  static inline bool
Index: gcc/tree-ssa-loop-niter.c
===================================================================
*** gcc/tree-ssa-loop-niter.c	(revision 138834)
--- gcc/tree-ssa-loop-niter.c	(working copy)
*************** static tree
*** 2034,2040 ****
  get_val_for (tree x, tree base)
  {
    gimple stmt;
-   tree nx, val, retval, rhs1, rhs2;
  
    gcc_assert (is_gimple_min_invariant (base));
  
--- 2034,2039 ----
*************** get_val_for (tree x, tree base)
*** 2050,2082 ****
    /* STMT must be either an assignment of a single SSA name or an
       expression involving an SSA name and a constant.  Try to fold that
       expression using the value for the SSA name.  */
!   rhs1 = gimple_assign_rhs1 (stmt);
!   rhs2 = gimple_assign_rhs2 (stmt);
!   if (TREE_CODE (rhs1) == SSA_NAME)
!     nx = rhs1;
!   else if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
!     nx = rhs2;
!   else
!     gcc_unreachable ();
! 
!   /* NX is now the SSA name for which we want to discover the base value.  */
!   val = get_val_for (nx, base);
!   if (rhs2)
!     {
!       /* If this is a binary expression, fold it.  If folding is
! 	 not possible, return a tree expression with the RHS of STMT.  */
!       rhs1 = (nx == rhs1) ? val : rhs1;
!       rhs2 = (nx == rhs2) ? val : rhs2;
!       retval = fold_binary (gimple_assign_rhs_code (stmt),
! 			    gimple_expr_type (stmt), rhs1, rhs2);
!       if (retval == NULL_TREE)
! 	retval= build2 (gimple_assign_rhs_code (stmt),
! 		        gimple_expr_type (stmt), rhs1, rhs2);
      }
    else
!     retval = val;
!       
!   return retval;
  }
  
  
--- 2049,2078 ----
    /* STMT must be either an assignment of a single SSA name or an
       expression involving an SSA name and a constant.  Try to fold that
       expression using the value for the SSA name.  */
!   if (gimple_assign_ssa_name_copy_p (stmt))
!     return get_val_for (gimple_assign_rhs1 (stmt), base);
!   else if (gimple_assign_rhs_class (stmt) == GIMPLE_UNARY_RHS
! 	   && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
!     {
!       return fold_build1 (gimple_assign_rhs_code (stmt),
! 			  gimple_expr_type (stmt),
! 			  get_val_for (gimple_assign_rhs1 (stmt), base));
!     }
!   else if (gimple_assign_rhs_class (stmt) == GIMPLE_BINARY_RHS)
!     {
!       tree rhs1 = gimple_assign_rhs1 (stmt);
!       tree rhs2 = gimple_assign_rhs2 (stmt);
!       if (TREE_CODE (rhs1) == SSA_NAME)
! 	rhs1 = get_val_for (rhs1, base);
!       else if (TREE_CODE (rhs2) == SSA_NAME)
! 	rhs2 = get_val_for (rhs2, base);
!       else
! 	gcc_unreachable ();
!       return fold_build2 (gimple_assign_rhs_code (stmt),
! 			  gimple_expr_type (stmt), rhs1, rhs2);
      }
    else
!     gcc_unreachable ();
  }
  
  
Index: gcc/testsuite/gcc.c-torture/compile/pr37056.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/pr37056.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/compile/pr37056.c	(revision 0)
***************
*** 0 ****
--- 1,28 ----
+ extern void abort (void);
+ 
+ static union {
+     char buf[12 * sizeof (long long)];
+ } u;
+ 
+ int main ()
+ {
+   int off, len, i;
+   char *p, *q;
+ 
+   for (off = 0; off < (sizeof (long long)); off++)
+     for (len = 1; len < (10 * sizeof (long long)); len++)
+       {
+ 	for (i = 0; i < (12 * sizeof (long long)); i++)
+ 	  u.buf[i] = 'a';
+ 	p = (__extension__ (__builtin_constant_p ('\0') && ('\0') == '\0'
+ 			    ? ({void *__s = (u.buf + off); __s;})
+ 			    : __builtin_memset (u.buf + off, '\0', len)));
+ 	if (p != u.buf + off)
+ 	  abort ();
+ 	for (i = 0; i < off; i++, q++)
+ 	  if (*q != 'a')
+ 	    abort ();
+       }
+   return 0;
+ }
+ 


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