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.
  • [Bug tree-optimization/106883]... rguenth at gcc dot gnu.org via Gcc-bugs

Reply via email to