Jonas Paulsson via llvm-dev
2015-Oct-23 13:11 UTC
[llvm-dev] incorrect reg class assigned after isel
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. -------------- next part -------------- define fp128 @f14(fp128 %r3) { %y = fadd fp128 %r3, %r3 ret fp128 %y }