https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119235
Bug ID: 119235
Summary: Argument pointer survives LRA with -m31 -mzarch
Product: gcc
Version: unknown
Status: UNCONFIRMED
Keywords: build
Severity: normal
Priority: P3
Component: target
Assignee: stefansf at gcc dot gnu.org
Reporter: stefansf at gcc dot gnu.org
Target Milestone: ---
Target: s390-*-*
Building gcc with Ada support for -m31 -mzarch -march={zEC12,z10} fails with
Entering /gcc/build/gcc/ada/rts_32
...
/gcc/build/./gcc/xgcc -B/gcc/build/./gcc/ -B/gcc/dst/s390x-ibm-linux-gnu/bin/
-B/gcc/dst/s390x-ibm-linux-gnu/lib/ -isystem
/gcc/dst/s390x-ibm-linux-gnu/include -isystem
/gcc/dst/s390x-ibm-linux-gnu/sys-include -c -g -O2 -m31 -W -Wall -gnatpg
-nostdinc -m31 a-textio.adb -o a-textio.o
/tmp/cckRZsAA.s: Assembler messages:
/tmp/cckRZsAA.s:7015: Error: bad expression
/tmp/cckRZsAA.s:7015: Error: junk at end of line: `ap'
The file contains
lgr %r0,%ap
This all boils down to the fact that during combine we accept an insn where %ap
is accessed in a mode different than Pmode which in turn lra cannot eliminate.
Trying 12, 13 -> 14:
12: zero_extract(r75:DI,0x20,0)=r60:SI#0
REG_DEAD r60:SI
13: strict_low_part(r75:DI#4)=%ap:SI
14: [%fp:SI-0x8]=r75:DI
REG_DEAD r75:DI
Failed to match this instruction:
(set (mem/c:DI (plus:SI (reg/f:SI 34 %fp)
(const_int -8 [0xfffffffffffffff8])) [0 MEM <vector(2) UNSIGNED_32>
[(void *)&FRAME.222]+0 S8 A64])
(ior:DI (ashift:DI (subreg:DI (reg/f:SI 60 [ ada__text_io__current_in.224_1
]) 0)
(const_int 32 [0x20]))
(zero_extend:DI (reg/f:SI 32 %ap))))
Successfully matched this instruction:
(set (mem/c:DI (plus:SI (reg/f:SI 34 %fp)
(const_int -8 [0xfffffffffffffff8])) [0 MEM <vector(2) UNSIGNED_32>
[(void *)&FRAME.222]+0 S8 A64])
(ior:DI (and:DI (reg:DI 32 %ap)
(const_int 4294967295 [0xffffffff]))
(ashift:DI (subreg:DI (reg/f:SI 60 [ ada__text_io__current_in.224_1 ])
0)
(const_int 32 [0x20]))))
allowing combination of insns 12, 13 and 14
I don't see a reason why we should access a virtual FP/AP/RA register in modes
different than Pmode. Thus, I will give the following patch a try:
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 29aef501fdd..3e8d7cfffd8 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -11138,8 +11138,8 @@ s390_hard_regno_mode_ok (unsigned int regno,
machine_mode mode)
}
break;
case ADDR_REGS:
- if (FRAME_REGNO_P (regno) && mode == Pmode)
- return true;
+ if (FRAME_REGNO_P (regno))
+ return mode == Pmode;
/* fallthrough */
case GENERAL_REGS: