[llvm] c452e7e - [GISel][Inlineasm] Don't assert on multi-register inline asm inputs (#200612)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 01:05:52 PDT 2026


Author: Ilpo Ruotsalainen
Date: 2026-06-30T10:05:47+02:00
New Revision: c452e7edd9e9fec10bab4c9de09846529454dcab

URL: https://github.com/llvm/llvm-project/commit/c452e7edd9e9fec10bab4c9de09846529454dcab
DIFF: https://github.com/llvm/llvm-project/commit/c452e7edd9e9fec10bab4c9de09846529454dcab.diff

LOG: [GISel][Inlineasm] Don't assert on multi-register inline asm inputs (#200612)

`lowerInlineAsm()` asserts that the number of registers allocated for an
input operand equals the number of source vregs, then separately bails
for `NumRegs > 1`. The assert is wrong: the counts legitimately differ
when a value is passed in a register pair/tuple (e.g. i128 in a RISC-V
"R" GPR pair, or i512 to an AArch64 ld64b operand), crashing
assertions-enabled builds instead of falling back to SelectionDAG.

Replace the assert and the `NumRegs > 1` check with a single guard
requiring exactly one source vreg in one register; anything else is
rejected so it falls back instead of asserting. The supported path is
unchanged.

https://godbolt.org/z/v6WTaYEsd

Added: 
    

Modified: 
    llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
    llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
    llvm/test/CodeGen/RISCV/GlobalISel/riscv-unsupported.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
index 3efa6ecaa9dc0..b5bbcc193b6b7 100644
--- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -551,11 +551,7 @@ bool InlineAsmLowering::lowerInlineAsm(
 
       unsigned NumRegs = OpInfo.Regs.size();
       ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
-      assert(NumRegs == SourceRegs.size() &&
-             "Expected the number of input registers to match the number of "
-             "source registers");
-
-      if (NumRegs > 1) {
+      if (NumRegs != 1 || SourceRegs.size() != 1) {
         LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
                              "not supported yet\n");
         return false;

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
index bffce0e5d0161..55755ff4ef1a3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
@@ -143,6 +143,14 @@ entry:
   ret i32 %asmresult1
 }
 
+; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: call{{.*}} (in function: inline_asm_multi_reg_input)
+; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for inline_asm_multi_reg_input
+; FALLBACK-WITH-REPORT-OUT-LABEL: inline_asm_multi_reg_input
+define i128 @inline_asm_multi_reg_input(i128 %x) {
+  %r = call i128 asm sideeffect "/* $0 $1 */", "=&r,r"(i128 %x)
+  ret i128 %r
+}
+
 attributes #1 = { "target-features"="+sve" }
 attributes #2 = { "target-features"="+ls64" }
 

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/riscv-unsupported.ll b/llvm/test/CodeGen/RISCV/GlobalISel/riscv-unsupported.ll
index 073b5186aad71..d41405e924217 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/riscv-unsupported.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/riscv-unsupported.ll
@@ -14,3 +14,10 @@ define void @test_byval_param(ptr %x) {
   call void @test_byval_arg(ptr byval(%byval.class) %x)
   ret void
 }
+
+define i128 @inline_asm_multi_reg_input(i128 %x) {
+; CHECK: remark: {{.*}} unable to translate instruction: call
+; CHECK-LABEL: warning: Instruction selection used fallback path for inline_asm_multi_reg_input
+  %r = call i128 asm sideeffect "/* $0 $1 */", "=&r,r"(i128 %x)
+  ret i128 %r
+}


        


More information about the llvm-commits mailing list