]> git.ipfire.org Git - thirdparty/gcc.git/commit
[rtl-optimization/116244] Don't create bogus regs in alter_subreg
authorJeff Law <jlaw@ventanamicro.com>
Mon, 12 Aug 2024 13:29:25 +0000 (07:29 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 12 Aug 2024 13:31:28 +0000 (07:31 -0600)
commite9738e77674e23f600315ca1efed7d1c7944d0cc
treebf264f58654a9b9253bd7ebbffcabe7ad7357deb
parentedc47d3ac95734b6076187d00feb6b49931ad1cc
[rtl-optimization/116244] Don't create bogus regs in alter_subreg

So this is another nasty latent bug exposed by ext-dce.

Similar to the prior m68k failure it's another problem with how we handle
paradoxical subregs on big endian targets.

In this instance when we remove the hard subregs we take something like:

(subreg:DI (reg:SI 0) 0)

And turn it into

(reg:SI -1)

Which is clearly wrong.  (reg:SI 0) is correct.

The transformation happens in alter_subreg, but I really wanted to fix this in
subreg_regno since we could have similar problems in some of the other callers
of subreg_regno.

Unfortunately reload depends on the current behavior of subreg_regno; in the
cases where the return value is an invalid register, the wrong half of a
register pair, etc the resulting bogus value is detected by reload and triggers
reloading of the inner object.  So that's the new comment in subreg_regno.

The second best place to fix is alter_subreg which is what this patch does.  If
presented with a paradoxical subreg, then the base register number should
always be REGNO (SUBREG_REG (object)).  It's just how paradoxicals are designed
to work.

I haven't tried to fix the other places that call subreg_regno.  After being
burned by reload, I'm more than a bit worried about unintended fallout.

I must admit I'm surprised we haven't stumbled over this before and that it
didn't fix any failures on the big endian embedded targets.

Boostrapped & regression tested on x86_64, also went through all the embedded
targets in my tester and bootstrapped on m68k & s390x to get some additional
big endian testing.

Pushing to the trunk.

rtl-optimization/116244
gcc/
* rtlanal.cc (subreg_regno): Update comment.
* final.cc (alter_subrg): Always use REGNO (SUBREG_REG ()) to get
the base regsiter for paradoxical subregs.

gcc/testsuite/
* g++.target/m68k/m68k.exp: New test driver.
* g++.target/m68k/pr116244.C: New test.
gcc/final.cc
gcc/rtlanal.cc
gcc/testsuite/g++.target/m68k/m68k.exp [new file with mode: 0644]
gcc/testsuite/g++.target/m68k/pr116244.C [new file with mode: 0644]