http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58417
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
So we want the evolution of sum_11 in the following loop (for a use on the
exit edge):
# i_18 = PHI <i_13(4), 1(2)>
# sum_19 = PHI <sum_11(4), 0(2)>
# prevsum_21 = PHI <prevsum_12(4), 0(2)>
foo (sum_19);
_7 = i_18 + -1;
_8 = (long long int) _7;
_9 = arr[i_18];
_10 = _8 * _9;
sum_11 = _10 - prevsum_21;
prevsum_12 = prevsum_21 + _9;
i_13 = i_18 + 1;
if (i_13 <= 5)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
goto <bb 3>;
and we compute
_10 = {0, +, _9}_1
_prevsum_21 = {0, +, _9}_1
but that is really meaningless as _9 is not a loop invariant which means that
this two very CHRECs are not "valid" as far as I understand, not valid to
operate on at least.
Thus the following asserts should IMHO hold (and trigger on the testcase
and many others)
Index: gcc/tree-chrec.c
===================================================================
--- gcc/tree-chrec.c (revision 202644)
+++ gcc/tree-chrec.c (working copy)
@@ -268,9 +268,14 @@ chrec_fold_plus_1 (enum tree_code code,
switch (TREE_CODE (op0))
{
case POLYNOMIAL_CHREC:
+ gcc_checking_assert
+ (!chrec_contains_symbols_defined_in_loop (op0, CHREC_VARIABLE (op0)));
switch (TREE_CODE (op1))
{
case POLYNOMIAL_CHREC:
+ gcc_checking_assert
+ (!chrec_contains_symbols_defined_in_loop (op1,
+ CHREC_VARIABLE (op1)));
return chrec_fold_plus_poly_poly (code, type, op0, op1);
CASE_CONVERT:
@@ -298,6 +303,9 @@ chrec_fold_plus_1 (enum tree_code code,
switch (TREE_CODE (op1))
{
case POLYNOMIAL_CHREC:
+ gcc_checking_assert
+ (!chrec_contains_symbols_defined_in_loop (op1,
+ CHREC_VARIABLE (op1)));
if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
return build_polynomial_chrec
(CHREC_VARIABLE (op1),
@@ -396,9 +404,14 @@ chrec_fold_multiply (tree type,
switch (TREE_CODE (op0))
{
case POLYNOMIAL_CHREC:
+ gcc_checking_assert
+ (!chrec_contains_symbols_defined_in_loop (op0, CHREC_VARIABLE (op0)));
switch (TREE_CODE (op1))
{
case POLYNOMIAL_CHREC:
+ gcc_checking_assert
+ (!chrec_contains_symbols_defined_in_loop (op1,
+ CHREC_VARIABLE (op1)));
return chrec_fold_multiply_poly_poly (type, op0, op1);
CASE_CONVERT:
@@ -431,6 +444,9 @@ chrec_fold_multiply (tree type,
switch (TREE_CODE (op1))
{
case POLYNOMIAL_CHREC:
+ gcc_checking_assert
+ (!chrec_contains_symbols_defined_in_loop (op1,
+ CHREC_VARIABLE (op1)));
return build_polynomial_chrec
(CHREC_VARIABLE (op1),
chrec_fold_multiply (type, CHREC_LEFT (op1), op0),
as of the recursion we can fix that by making the cache used to guard against
the recursion global (and maybe use instantiate_parameters instead of
resolve_mixers).