https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109031
Roger Sayle <roger at nextmovesoftware dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED CC| |roger at nextmovesoftware dot com Assignee|unassigned at gcc dot gnu.org |roger at nextmovesoftware dot com Keywords| |patch --- Comment #28 from Roger Sayle <roger at nextmovesoftware dot com> --- Doh! My apologies for this breakage. I'm currently testing the following fix: diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc index f93d8dc..2f67581 100644 --- a/gcc/tree-chrec.cc +++ b/gcc/tree-chrec.cc @@ -623,7 +623,9 @@ chrec_apply (unsigned var, else if (operand_equal_p (CHREC_LEFT (chrec), chrecr) && TREE_CODE (x) == PLUS_EXPR && integer_all_onesp (TREE_OPERAND (x, 1)) - && !POINTER_TYPE_P (type)) + && !POINTER_TYPE_P (type) + && TYPE_PRECISION (TREE_TYPE (x)) + >= TYPE_PRECISION (type)) { /* We know the number of iterations can't be negative. So {a, +, a} (x-1) -> "a*x". */ The integer_all_onesp test is only equivalent to -1 when the TREE_TYPE (x) is the same width or wider than type. In this case, TREE_TYPE (x) is unsigned char and x is "zero+255", so performed in the wrong type (zero+255+1) becomes zero instead of zero+256.