This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR37056, tuplification problems in tree-ssa-loop-niter.c
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 8 Aug 2008 13:26:02 +0200 (CEST)
- Subject: [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;
+ }
+