Mark matching input constraint to mem operand as not supported.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This fixes assert and makes this test mentioned in D82651 to fallback for aarch64.
This seem to have different handling on different targets. I don't know what is the best way to handle this since it looks to me that custom handling has to be done in different places
Just adding same flag and register as MatchedOperand works for this example but from this comment
// We need to make sure that this one operand does not end up in XZR, thus // require the address to be in a PointerRegClass register.
in AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand an extra copy to a register with PointerRegClass needs to be done. Something like:
--- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp @@ -356,7 +356,11 @@ bool InlineAsmLowering::lowerInlineAsm( assert( SourceRegs.size() == 1 && "Expected the memory output to fit into a single virtual register"); - Inst.addReg(SourceRegs[0]); + const TargetRegisterClass *TRC = + MF.getSubtarget().getRegisterInfo()->getPointerRegClass(MF); + Register Tmp = MRI->createVirtualRegister(TRC); + MIRBuilder.buildCopy(Tmp, SourceRegs[0]); + Inst.addReg(Tmp); } else { // Otherwise, this outputs to a register (directly for C_Register / // C_RegisterClass. Find a register that we can use. @@ -406,6 +410,19 @@ bool InlineAsmLowering::lowerInlineAsm( InstFlagIdx += getNumOpRegs(*Inst, InstFlagIdx) + 1; assert(getNumOpRegs(*Inst, InstFlagIdx) == 1 && "Wrong flag"); + unsigned MatchedOperandFlag = Inst->getOperand(InstFlagIdx).getImm(); + if (InlineAsm::isMemKind(MatchedOperandFlag)) { + Inst.addImm(MatchedOperandFlag); + Inst.addReg(Inst->getOperand(InstFlagIdx + 1).getReg()); + break; + } + + if (!InlineAsm::isRegDefKind(MatchedOperandFlag) && + !InlineAsm::isRegDefEarlyClobberKind(MatchedOperandFlag)) { + LLVM_DEBUG(dbgs() << "Unknown matching constraint\n"); + return false; + } + // We want to tie input to register in next operand. unsigned DefRegIdx = InstFlagIdx + 1; Register Def = Inst->getOperand(DefRegIdx).getReg();
but target should create copy / add immediate and register to Inst.
getPointerRegClass is terrible, but also shouldn't be necessary in GlobalISel since pointer types aren't lost
llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp | ||
---|---|---|
417 | I don't think this case is covered in the test? |
I don't think this case is covered in the test?