diff --git a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp --- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp @@ -525,8 +525,22 @@ unsigned Flag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, NumRegs); Inst.addImm(Flag); - MIRBuilder.buildCopy(OpInfo.Regs[0], SourceRegs[0]); - Inst.addReg(OpInfo.Regs[0]); + + // We might need to extend the input registers to fit the register class + Register TargetReg = OpInfo.Regs[0]; + Register InputReg = SourceRegs[0]; + + unsigned TargetSize = TRI->getRegSizeInBits(TargetReg, *MRI); + unsigned InputSize = MRI->getType(InputReg).getSizeInBits(); + + if (InputSize < TargetSize) { + Register ScratchReg = + MRI->createGenericVirtualRegister(LLT::scalar(TargetSize)); + InputReg = MIRBuilder.buildAnyExt(ScratchReg, InputReg).getReg(0); + } + + MIRBuilder.buildCopy(TargetReg, InputReg); + Inst.addReg(TargetReg); break; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll @@ -199,6 +199,18 @@ ret i8 %0 } +define void @test_input_register_extend() { + ; CHECK-LABEL: name: test_input_register_extend + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 42 + ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8) + ; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32) + ; CHECK: INLINEASM &"mov x0, $0", 1 /* sideeffect attdialect */, 9 /* reguse */, [[COPY]] + ; CHECK: RET_ReallyLR + call void asm sideeffect "mov x0, $0", "r"(i8 42) + ret void +} + define i32 @test_memory_constraint(i32* %a) nounwind { ; CHECK-LABEL: name: test_memory_constraint ; CHECK: bb.1 (%ir-block.0):