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

--- Comment #11 from Wilco <wdijkstr at arm dot com> ---
(In reply to Richard Henderson from comment #10)
> Created attachment 37267 [details]
> proposed patch
> 
> Andrew is exactly right re plus being special.
> 
> The pluslong hoops that are being jumped through are really the
> domain for post-reload splitters and peepholes.

Thanks for the patch, it fixes the reported issue. However it regresses the
examples that motivated the original patch:

int g3(int x, int y, int z)
{
  x += 0x15555;
  y += 0x15555;
  z += 0x15555;
  return x * y ^ z;
}

int g4(int x, int y, int z)
{
  x += 0x15555;
  return x;
}

These now produce:

g3:
        mov     w3, 21845
        mov     w4, 21845
        movk    w3, 0x1, lsl 16
        movk    w4, 0x1, lsl 16
        add     w0, w0, w3
        add     w1, w1, w4
        mov     w5, 21845
        movk    w5, 0x1, lsl 16
        mul     w0, w0, w1
        add     w2, w2, w5
        eor     w0, w0, w2
        ret

g4:
        mov     w1, 21845
        movk    w1, 0x1, lsl 16
        add     w0, w0, w1
        ret

The first case should have CSEd the complex immediate. The 2nd should have
split into 2 adds.

The idea of the original patch was to expand single-instruction adds, so any
complex immediates are explicit and get CSEd/lifted. Then allow combine to find
single-use single-block complex immediates that can be merged with an add and
split into a 2-instruction add expansion. This only works if you have a
define_insn_and_split for the complex immediate, with just a split combine
doesn't do it.

With your patch expand always emits add instructions with complex immediates
which then can't be optimized.

Reply via email to