Index: gcc/gimple-ssa-strength-reduction.c =================================================================== --- gcc/gimple-ssa-strength-reduction.c (revision 250791) +++ gcc/gimple-ssa-strength-reduction.c (working copy) @@ -2074,6 +2074,15 @@ replace_mult_candidate (slsr_cand_t c, tree basis_ { tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt)); enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt); + unsigned int prec = (POINTER_TYPE_P (target_type) + ? TYPE_PRECISION (sizetype) + : TYPE_PRECISION (target_type)); + tree maxval = (POINTER_TYPE_P (target_type) + ? TYPE_MAX_VALUE (sizetype) + : TYPE_MAX_VALUE (target_type)); + /* + wide_int maxval = wi::max_value (prec, sgn); + */ /* It is highly unlikely, but possible, that the resulting bump doesn't fit in a HWI. Abandon the replacement @@ -2082,6 +2091,20 @@ replace_mult_candidate (slsr_cand_t c, tree basis_ types but allows for safe negation without twisted logic. */ if (wi::fits_shwi_p (bump) && bump.to_shwi () != HOST_WIDE_INT_MIN + /* It is more likely that the bump doesn't fit in the target + type, so check whether constraining it to that type changes + the value. For a signed type, the value mustn't change. + For an unsigned type, the value may only change to a + congruent value (for negative bumps). */ + && (TYPE_UNSIGNED (target_type) + || wi::eq_p (bump, wi::ext (bump, prec, SIGNED))) + && (!TYPE_UNSIGNED (target_type) + || wi::eq_p (bump, wi::ext (bump, prec, UNSIGNED)) + || wi::eq_p (bump + wi::to_widest (maxval) + 1, + wi::ext (bump, prec, UNSIGNED))) + /* + || wi::eq_p (bump + maxval + 1, wi::ext (bump, prec, UNSIGNED))) + */ /* It is not useful to replace casts, copies, negates, or adds of an SSA name and a constant. */ && cand_code != SSA_NAME