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).

Reply via email to