[PATCH] Fix chrec_evaluate with pointer addition (PR tree-optimization/34063)
Jakub Jelinek
jakub@redhat.com
Tue Nov 13 12:21:00 GMT 2007
Hi!
On the following testcase ICEs because POINTER_PLUS_EXPR is created
with an integer as first argument and pointer as second.
I believe this is caused by chrec_evaluate, which in this case
puts CHREC_RIGHT based expression first and CHREC_LEFT based expression
second, so assuming for pointer operations GCC keeps pointers even in CHRECs
always in CHREC_LEFT operands this is enough to fix it
(bootstrapped/regtested on x86_64-linux).
If my assumption is false and CHRECs contain POINTER_TYPE trees at random
places, then it should be probably chrec_fold_plus or chrec_fold_plus_1
which will swap the arguments to POINTER_PLUS_EXPR if needed.
Ok for trunk?
2007-11-13 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/34063
* tree-chrec.c (chrec_evaluate): Put CHREC_LEFT based argument
as first chrec_fold_plus operand rather than second.
* g++.dg/tree-ssa/pr34063.C: New test.
--- gcc/tree-chrec.c.jj 2007-08-15 15:36:32.000000000 +0200
+++ gcc/tree-chrec.c 2007-11-13 11:17:42.000000000 +0100
@@ -522,13 +522,13 @@ chrec_evaluate (unsigned var, tree chrec
if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
&& CHREC_VARIABLE (chrec) == var)
{
- arg0 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1);
- if (arg0 == chrec_dont_know)
+ arg1 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1);
+ if (arg1 == chrec_dont_know)
return chrec_dont_know;
binomial_n_k = tree_fold_binomial (type, n, k);
if (!binomial_n_k)
return chrec_dont_know;
- arg1 = fold_build2 (MULT_EXPR, type,
+ arg0 = fold_build2 (MULT_EXPR, type,
CHREC_LEFT (chrec), binomial_n_k);
return chrec_fold_plus (type, arg0, arg1);
}
--- gcc/testsuite/g++.dg/tree-ssa/pr34063.C.jj 2007-11-13 11:21:20.000000000 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr34063.C 2007-11-13 11:20:46.000000000 +0100
@@ -0,0 +1,25 @@
+// { PR tree-optimization/34063 }
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct S
+{
+ double e[9];
+
+ double const &
+ operator() (int r, int c) const
+ {
+ return e[r * 3 + c];
+ }
+};
+
+void
+foo()
+{
+ S r;
+ double *p;
+ for (int j = 0; j < 3; j++)
+ for (int k = 0; k < 3; k++)
+ for (int l = k + 1; l < 3; l++)
+ *p++ = r (k, 0) * r (l, j) + r (k, j) * r (l, 0);
+}
Jakub
More information about the Gcc-patches
mailing list