https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106883
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bill.schmidt at fastmail dot com --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- So the difficulty with addressing this is trying to do better than rewriting all expressions SLSR emits using unsigned arithmetic. Your particular testcase before computes -1*s and 1*s while the transform does -1*s + (1*s - -1*s), aka -1*s + 2*s where 2*s overflows because the difference of two signed values a and -a cannot necessarily be represented in a signed value. I _think_ this can solely happen for '2', but not say y1 = c + 2; x1 = s * y1; y2 = y1 + 4; x2 = s * y2; thus a difference of 4*s (?) SLSR says at the top /* Information about a strength reduction candidate. Each statement in the candidate table represents an expression of one of the following forms (the special case of CAND_REF will be described later): (CAND_MULT) S1: X = (B + i) * S (CAND_ADD) S1: X = B + (i * S) Here X and B are SSA names, i is an integer constant, and S is either an SSA name or a constant. We call B the "base," i the "index", and S the "stride." Any statement S0 that dominates S1 and is of the form: (CAND_MULT) S0: Y = (B + i') * S (CAND_ADD) S0: Y = B + (i' * S) is called a "basis" for S1. In both cases, S1 may be replaced by S1': X = Y + (i - i') * S, where (i - i') * S is folded to the extent possible. which is what happens here - but SLSR covers more cases that might be also problematical. For the testcase at hand the s_3(D) * 2 stmt is inserted in insert_initializers while the s * y2 multiplication is adjusted in replace_rhs_if_not_dup. I think both need rewriting to unsigned or alternatively SLSR should give up for signed arithmetic. As said, it would be nice to not needing to always do this. Which means possibly having insert_initializers create an unsigned initializer and replace_rhs_if_not_dup (and elsewhere) deal with type mismatches by promoting the replaced computation as well. But it's going to be quite some work to go through all this, so I fear cutting of SLSR for arithmetic with undefined overflow behavior might be easier. Given there's no "real" issue exposed by this bug I've deprioritized this given the possible bad effect on code generation either change will have. The pass is essentially unmaintained at the moment.