[PATCH] D83390: [GlobalISel][InlineAsm] Extend input operands when register class size does not match type

Dominik Montada via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 05:51:05 PDT 2020


gargaroff created this revision.
gargaroff added reviewers: arsenm, kschwarz.
Herald added subscribers: llvm-commits, hiraditya, rovka, wdng.
Herald added a project: LLVM.

The InlineAsmLowering was blindly copying the input operands to the selected register class without checking if their sizes match. This resulted in illegal COPYs. Use G_ANYEXT to extend the input operand to fit the selected register class. G_ANYEXT ist used since the inline assembler is not allowed to assume anything about the upper bits of the input operands.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83390

Files:
  llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
  llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll


Index: llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
===================================================================
--- llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
+++ 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):
Index: llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
===================================================================
--- llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -525,7 +525,21 @@
 
       unsigned Flag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, NumRegs);
       Inst.addImm(Flag);
-      MIRBuilder.buildCopy(OpInfo.Regs[0], SourceRegs[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(OpInfo.Regs[0], InputReg);
       Inst.addReg(OpInfo.Regs[0]);
       break;
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D83390.276393.patch
Type: text/x-patch
Size: 2020 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200708/e2bfd2b7/attachment-0001.bin>


More information about the llvm-commits mailing list