[llvm] [SelectionDAG] Fix assertion failure on inline asm register type mismatch (PR #166615)

Ahmed Nour via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 5 10:54:47 PST 2025


https://github.com/ahmednoursphinx updated https://github.com/llvm/llvm-project/pull/166615

>From 684e005c76d7db5500fb0925547b58327c993d84 Mon Sep 17 00:00:00 2001
From: ahmed <ahmednour.mohamed2012 at gmail.com>
Date: Wed, 5 Nov 2025 20:52:13 +0200
Subject: [PATCH 1/2] [SelectionDAG] Fix assertion failure on inline asm
 register type mismatch

---
 .../SelectionDAG/SelectionDAGBuilder.cpp      | 12 ++++++++++-
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  2 ++
 .../inline-asm-y-constraint-size-mismatch.ll  | 20 +++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/X86/inline-asm-y-constraint-size-mismatch.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index fa0c899dfcc27..9a6a76f73f8fe 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -365,7 +365,17 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
 
     assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
     NumParts = NumRegs; // Silence a compiler warning.
-    assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+    
+    // Check if the register type matches the part type
+    if (RegisterVT != PartVT) {
+      diagnosePossiblyInvalidConstraint(
+          *DAG.getContext(), V,
+          "register type (" + EVT(RegisterVT).getEVTString() +
+              ") doesn't match operand type (" + EVT(PartVT).getEVTString() +
+              ")");
+      return DAG.getUNDEF(ValueVT);
+    }
+    
     assert(RegisterVT.getSizeInBits() ==
            Parts[0].getSimpleValueType().getSizeInBits() &&
            "Part type sizes don't match!");
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6edf0185df813..bf432f1d56d4a 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -61825,6 +61825,8 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
       break;
     case 'y':   // MMX_REGS if MMX allowed.
       if (!Subtarget.hasMMX()) break;
+      // MMX registers are 64-bit only
+      if (VT.getSizeInBits() != 64) break;
       return std::make_pair(0U, &X86::VR64RegClass);
     case 'v':
     case 'x':   // SSE_REGS if SSE1 allowed or AVX_REGS if AVX allowed
diff --git a/llvm/test/CodeGen/X86/inline-asm-y-constraint-size-mismatch.ll b/llvm/test/CodeGen/X86/inline-asm-y-constraint-size-mismatch.ll
new file mode 100644
index 0000000000000..9f4ed28a4d312
--- /dev/null
+++ b/llvm/test/CodeGen/X86/inline-asm-y-constraint-size-mismatch.ll
@@ -0,0 +1,20 @@
+; RUN: not llc -mtriple=x86_64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
+
+; Test that using MMX register constraint 'y' (64-bit) with a 256-bit vector
+; produces a proper error message instead of an assertion failure.
+
+; CHECK: error: couldn't allocate output register for constraint 'y'
+
+define <8 x i32> @test_mmx_constraint_size_mismatch() {
+entry:
+  %out = tail call <8 x i32> asm "something $0", "=y"()
+  ret <8 x i32> %out
+}
+
+; Also test with a different vector size
+define <4 x i32> @test_mmx_constraint_128bit() {
+entry:
+  %out = tail call <4 x i32> asm "something $0", "=y"()
+  ret <4 x i32> %out
+}
+

>From 36a7461181238819e0775958493cff4305e235de Mon Sep 17 00:00:00 2001
From: ahmed <ahmednour.mohamed2012 at gmail.com>
Date: Wed, 5 Nov 2025 20:54:34 +0200
Subject: [PATCH 2/2] chore: Fix formatting

---
 .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp   | 14 +++++++-------
 llvm/lib/Target/X86/X86ISelLowering.cpp            |  3 ++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9a6a76f73f8fe..ecdc3750e6e02 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -365,17 +365,17 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
 
     assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
     NumParts = NumRegs; // Silence a compiler warning.
-    
+
     // Check if the register type matches the part type
     if (RegisterVT != PartVT) {
-      diagnosePossiblyInvalidConstraint(
-          *DAG.getContext(), V,
-          "register type (" + EVT(RegisterVT).getEVTString() +
-              ") doesn't match operand type (" + EVT(PartVT).getEVTString() +
-              ")");
+      diagnosePossiblyInvalidConstraint(*DAG.getContext(), V,
+                                        "register type (" +
+                                            EVT(RegisterVT).getEVTString() +
+                                            ") doesn't match operand type (" +
+                                            EVT(PartVT).getEVTString() + ")");
       return DAG.getUNDEF(ValueVT);
     }
-    
+
     assert(RegisterVT.getSizeInBits() ==
            Parts[0].getSimpleValueType().getSizeInBits() &&
            "Part type sizes don't match!");
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index bf432f1d56d4a..2a02f12b18181 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -61826,7 +61826,8 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
     case 'y':   // MMX_REGS if MMX allowed.
       if (!Subtarget.hasMMX()) break;
       // MMX registers are 64-bit only
-      if (VT.getSizeInBits() != 64) break;
+      if (VT.getSizeInBits() != 64)
+        break;
       return std::make_pair(0U, &X86::VR64RegClass);
     case 'v':
     case 'x':   // SSE_REGS if SSE1 allowed or AVX_REGS if AVX allowed



More information about the llvm-commits mailing list