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

Ilpo Ruotsalainen via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 19:55:57 PDT 2026


https://github.com/lonemeow updated https://github.com/llvm/llvm-project/pull/200612

>From 5706d66e75475f13c1354023ee256e30fcb08be9 Mon Sep 17 00:00:00 2001
From: Ilpo Ruotsalainen <lonewolf at iki.fi>
Date: Sat, 30 May 2026 13:58:01 -0700
Subject: [PATCH] [GISel][Inlineasm] Don't assert on multi-register inline asm
 inputs

lowerInlineAsm asserted that the number of registers allocated for an
input operand equals the number of source vregs, then separately bailed
for NumRegs > 1. The assert is wrong: the counts legitimately differ when
a value is split across a register pair (e.g. an i128 in a GPR pair),
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.
---
 llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp       | 6 +-----
 llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll  | 8 ++++++++
 llvm/test/CodeGen/RISCV/GlobalISel/riscv-unsupported.ll | 7 +++++++
 3 files changed, 16 insertions(+), 5 deletions(-)

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