aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gimple.h11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37056.c28
-rw-r--r--gcc/tree-ssa-loop-niter.c48
5 files changed, 73 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3e43e4..f3ba567 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2008-08-07 Jan Hubicka <jh@suse.cz>
* i386.h (ix86_size_cost): Declare.
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 0c11f3e..f32600d 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1834,6 +1834,17 @@ gimple_assign_set_rhs_code (gimple s, enum tree_code code)
}
+/* 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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 356cc95..d930e38 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-08-08 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/37056
+ * gcc.c-torture/compile/pr37056.c: New testcase.
+
2008-08-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/Wcxx-compat-2.c: Check for bool/_Bool.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37056.c b/gcc/testsuite/gcc.c-torture/compile/pr37056.c
new file mode 100644
index 0000000..f9285e2
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37056.c
@@ -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;
+}
+
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 1d0605e..b8247a0 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2034,7 +2034,6 @@ static tree
get_val_for (tree x, tree base)
{
gimple stmt;
- tree nx, val, retval, rhs1, rhs2;
gcc_assert (is_gimple_min_invariant (base));
@@ -2050,33 +2049,30 @@ get_val_for (tree x, tree base)
/* 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);
+ 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
- retval = val;
-
- return retval;
+ gcc_unreachable ();
}