Hi,
I have a problem with a small test-case that needs to return an fp128 by storing it to memory, and would appreciate any help.
LowerReturn() builds an ISD::store, which later gets morphed to SystemZ::STX. The register class for this opcode is a sub-set of the i64 reg-class - without R0, which is not used as an address register. The reg class does not get constrained, so it remains GR64Bit, instead of ADDR64Bit, which is wrong.
I am not sure what the proper handling is:
Adding the SystemZ::ADDR64BitRegClass in TargetLowering did not seem to help.
I thought somewhere MRI->constrainRegClass() was supposed to be called at any register operand that have a too big RC (as in this case), or an extra COPY into the smaller RC should be emitted. To me, this should be done by the method that morphs the node, or at a later point during instruction emission.
/Jonas
test case:
/llc -verify-machineinstrs -mtriple=s390x-linux-gnu rc_fail.ll
*** IR Dump After Module Verifier ***
define fp128 @f14(fp128 %r3) {
%y = fadd fp128 %r3, %r3
ret fp128 %y
}
=== f14
Initial selection DAG: BB#0 'f14:'
SelectionDAG has 13 nodes:
t0: ch = EntryToken
t4: i64,ch = CopyFromReg t0, Register:i64 %vreg1
t6: f128,ch = load<LD16[<unknown>](align=8)> t0, t4, undef:i64
t10: i64 = Constant<0>
t2: i64,ch = CopyFromReg t0, Register:i64 %vreg0
t8: ch = CopyToReg t0, Register:i64 %vreg2, t2
t9: f128 = fadd t6, t6
t11: ch = store<ST16[<unknown>](align=8)> t8, t9, Register:i64 %vreg2, undef:i64
t12: ch = SystemZISD::RET_FLAG t11
Optimized legalized selection DAG: BB#0 'f14:'
SelectionDAG has 12 nodes:
t0: ch = EntryToken
t4: i64,ch = CopyFromReg t0, Register:i64 %vreg1
t6: f128,ch = load<LD16[<unknown>](align=8)> t0, t4, undef:i64
t2: i64,ch = CopyFromReg t0, Register:i64 %vreg0
t8: ch = CopyToReg t0, Register:i64 %vreg2, t2
t9: f128 = fadd t6, t6
t11: ch = store<ST16[<unknown>](align=8)> t8, t9, Register:i64 %vreg2, undef:i64
t12: ch = SystemZISD::RET_FLAG t11
Morphed node: t11: ch = STX<Mem:ST16[<unknown>](align=8)> t9, Register:i64 %vreg2, TargetConstant:i64<0>, Register:i64 %noreg, t8
# After Instruction Selection
# Machine code for function f14: SSA
Function Live Ins: %R2D in %vreg0, %R3D in %vreg1
BB#0: derived from LLVM BB %0
Live Ins: %R2D %R3D
%vreg1<def> = COPY %R3D; ADDR64Bit:%vreg1
%vreg0<def> = COPY %R2D; GR64Bit:%vreg0
%vreg3<def> = LX %vreg1, 0, %noreg; mem:LD16[<unknown>](align=8) FP128Bit:%vreg3 ADDR64Bit:%vreg1
%vreg4<def,tied1> = AXBR %vreg3<tied0>, %vreg3, %CC<imp-def,dead>; FP128Bit:%vreg4,%vreg3,%vreg3
%vreg2<def> = COPY %vreg0; GR64Bit:%vreg2,%vreg0
STX %vreg4<kill>, %vreg2, 0, %noreg; mem:ST16[<unknown>](align=8) FP128Bit:%vreg4 GR64Bit:%vreg2
Return
# End machine code for function f14.
*** Bad machine code: Illegal virtual register for instruction ***
- function: f14
- basic block: BB#0 (0x43aad40)
- instruction: STX- operand 1: %vreg2
Expected a ADDR64Bit register, but got a GR64Bit register
LLVM ERROR: Found 1 machine code errors.
rc_fail.ll (78 Bytes)