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