forked from OSchip/llvm-project
[GlobalISel][InlineAsm] Fix buildCopy for inputs
Check that input size matches size of destination reg class. Attempt to extend input size when needed. Differential Revision: https://reviews.llvm.org/D83384
This commit is contained in:
parent
9df6afbb5c
commit
fd85b40aee
|
@ -237,6 +237,39 @@ static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx) {
|
|||
return InlineAsm::getNumOperandRegisters(Flag);
|
||||
}
|
||||
|
||||
static bool buildAnyextOrCopy(Register Dst, Register Src,
|
||||
MachineIRBuilder &MIRBuilder) {
|
||||
const TargetRegisterInfo *TRI =
|
||||
MIRBuilder.getMF().getSubtarget().getRegisterInfo();
|
||||
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
|
||||
|
||||
auto SrcTy = MRI->getType(Src);
|
||||
if (!SrcTy.isValid()) {
|
||||
LLVM_DEBUG(dbgs() << "Source type for copy is not valid\n");
|
||||
return false;
|
||||
}
|
||||
unsigned SrcSize = TRI->getRegSizeInBits(Src, *MRI);
|
||||
unsigned DstSize = TRI->getRegSizeInBits(Dst, *MRI);
|
||||
|
||||
if (DstSize < SrcSize) {
|
||||
LLVM_DEBUG(dbgs() << "Input can't fit in destination reg class\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to anyext small scalar sources.
|
||||
if (DstSize > SrcSize) {
|
||||
if (!SrcTy.isScalar()) {
|
||||
LLVM_DEBUG(dbgs() << "Can't extend non-scalar input to size of"
|
||||
"destination register class\n");
|
||||
return false;
|
||||
}
|
||||
Src = MIRBuilder.buildAnyExt(LLT::scalar(DstSize), Src).getReg(0);
|
||||
}
|
||||
|
||||
MIRBuilder.buildCopy(Dst, Src);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InlineAsmLowering::lowerInlineAsm(
|
||||
MachineIRBuilder &MIRBuilder, const CallBase &Call,
|
||||
std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
|
||||
|
@ -427,7 +460,8 @@ bool InlineAsmLowering::lowerInlineAsm(
|
|||
ArrayRef<Register> SrcRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
|
||||
assert(SrcRegs.size() == 1 && "Single register is expected here");
|
||||
Register Tmp = MRI->createVirtualRegister(RC);
|
||||
MIRBuilder.buildCopy(Tmp, SrcRegs[0]);
|
||||
if (!buildAnyextOrCopy(Tmp, SrcRegs[0], MIRBuilder))
|
||||
return false;
|
||||
|
||||
// Add Flag and input register operand (Tmp) to Inst. Tie Tmp to Def.
|
||||
unsigned UseFlag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, 1);
|
||||
|
@ -525,7 +559,8 @@ bool InlineAsmLowering::lowerInlineAsm(
|
|||
|
||||
unsigned Flag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, NumRegs);
|
||||
Inst.addImm(Flag);
|
||||
MIRBuilder.buildCopy(OpInfo.Regs[0], SourceRegs[0]);
|
||||
if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
|
||||
return false;
|
||||
Inst.addReg(OpInfo.Regs[0]);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -211,3 +211,35 @@ define i32 @test_memory_constraint(i32* %a) nounwind {
|
|||
%1 = tail call i32 asm "ldr $0, $1", "=r,*m"(i32* %a)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
define i16 @test_anyext_input() {
|
||||
; CHECK-LABEL: name: test_anyext_input
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
|
||||
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
|
||||
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 655370 /* regdef:GPR32common */, def %0, 9 /* reguse */, [[COPY]]
|
||||
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %0
|
||||
; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
|
||||
; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
|
||||
; CHECK: $w0 = COPY [[ANYEXT1]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%1 = call i16 asm sideeffect "", "=r,r"(i16 1)
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @test_anyext_input_with_matching_constraint() {
|
||||
; CHECK-LABEL: name: test_anyext_input_with_matching_constraint
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
|
||||
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
|
||||
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 655370 /* regdef:GPR32common */, def %0, 2147483657 /* reguse tiedto:$0 */, [[COPY]](tied-def 3)
|
||||
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %0
|
||||
; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
|
||||
; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
|
||||
; CHECK: $w0 = COPY [[ANYEXT1]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%1 = call i16 asm sideeffect "", "=r,0"(i16 1)
|
||||
ret i16 %1
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue