[llvm-dev] incorrect reg class assigned after isel

Jonas Paulsson via llvm-dev llvm-dev at lists.llvm.org
Fri Oct 23 06:11:12 PDT 2015


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
}



More information about the llvm-dev mailing list