https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124528

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
compute_overall_effect_of_inner_loop computes this as

(int) ((unsigned int) -m_6(D) * (unsigned int) n_3(D) + 100)

there's no folded_casts because the CHREC is just {100, +, -m_6(D)}_1.

One would argue this is already wrong and should be

{100, +, (int)-(unsigned)m_6(D)}.

This is done in scev_dfs::add_to_evolution which performs

  if (code == MINUS_EXPR)
    to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
                                  ? build_real (type, dconstm1)
                                  : build_int_cst_type (type, -1));

a fix would be

diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 223015c4a8d..dbe62f717bf 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -880,9 +880,23 @@ scev_dfs::add_to_evolution (tree chrec_before, enum
tree_code code,
     }

   if (code == MINUS_EXPR)
-    to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
-                                 ? build_real (type, dconstm1)
-                                 : build_int_cst_type (type, -1));
+    {
+      if (!INTEGRAL_TYPE_P (type)
+         || (!TYPE_UNSIGNED (type)
+             && !expr_not_equal_to (to_add,
+                                    wi::to_wide (TYPE_MIN_VALUE (type)))))
+       {
+         tree utype = unsigned_type_for (type);
+         to_add = chrec_convert_rhs (utype, to_add);
+         to_add = chrec_fold_multiply (utype, to_add,
+                                       build_int_cst_type (utype, -1));
+         to_add = chrec_convert_rhs (type, to_add);
+       }
+      else
+       to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
+                                     ? build_real (type, dconstm1)
+                                     : build_int_cst_type (type, -1));
+    }

   res = add_to_evolution_1 (chrec_before, to_add, at_stmt);

Reply via email to