https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98334

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
This boils down to:
int
bar (int x, int y)
{
  return (int) (y - 1U) * x + x;
}

int
baz (int x, int y)
{
  return (y - 1) * x + x;
}

We do optimize the latter, but don't optimize the former into y * x.
For non-wrapping operation in bar that would be an invalid optimization,
as (int) (y - 1U) * x + x is well defined for y == INT_MIN and x == -1:
it is INT_MAX * -1 + -1, i.e. INT_MIN without overflow, but INT_MIN * -1
does overflow.
But we perhaps could and should turn that into just (int) ((y - 1U) * x),
i.e. unsigned multiplication.
We shouldn't do this until very late though, because turning signed arithmetics
into unsigned may disable other optimizations as it has no UB.

Or we could optimize this on RTL, combiner attempts:
Trying 7, 8 -> 9:
    7: {r90:SI=r93:SI-0x1;clobber flags:CC;}
      REG_DEAD r93:SI
      REG_UNUSED flags:CC
    8: {r91:SI=r90:SI*r92:SI;clobber flags:CC;}
      REG_UNUSED flags:CC
      REG_DEAD r90:SI
    9: r89:SI=r91:SI+r92:SI
      REG_DEAD r92:SI
      REG_DEAD r91:SI
Failed to match this instruction:
(set (reg:SI 89)
    (plus:SI (mult:SI (plus:SI (reg:SI 93)
                (const_int -1 [0xffffffffffffffff]))
            (reg:SI 92))
        (reg:SI 92)))
so if we hack up simplify-rtx.c to optimize that to (mult:SI (reg:SI 93)
(reg:SI 92)), it should work.

Reply via email to