[llvm] [SPIR-V] Fix crash on switch with odd-width condition type (PR #208026)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 01:38:01 PDT 2026


https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/208026

>From ed8bec0976f4a97754b85bb445b9e84f3a466574 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 7 Jul 2026 17:22:13 +0200
Subject: [PATCH 1/2] [SPIR-V] Fix crash on switch with odd-width condition
 type

getPreferredSwitchConditionType called getSimpleVT unconditionally, which asserts on extended EVTs like i31

Return i1 for non-simple types to keep CodeGenPrepare from widening the condition
---
 llvm/lib/Target/SPIRV/SPIRVISelLowering.h     |  7 ++++-
 .../SPIRV/switch-odd-width-condition.ll       | 27 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.h b/llvm/lib/Target/SPIRV/SPIRVISelLowering.h
index c86e37b2b2528..0599360cf465b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.h
+++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.h
@@ -64,9 +64,14 @@ class SPIRVTargetLowering : public TargetLowering {
   // the standard.
   void finalizeLowering(MachineFunction &MF) const override;
 
+  // Return a width no larger than the condition so CodeGenPrepare never widens
+  // it. Odd-width integers are extended EVTs, so getSimpleVT would fail, so
+  // falling back to i1.
   MVT getPreferredSwitchConditionType(LLVMContext &Context,
                                       EVT ConditionVT) const override {
-    return ConditionVT.getSimpleVT();
+    if (ConditionVT.isSimple())
+      return ConditionVT.getSimpleVT();
+    return MVT::i1;
   }
 
   bool enforcePtrTypeCompatibility(MachineInstr &I, unsigned PtrOpIdx,
diff --git a/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll b/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll
new file mode 100644
index 0000000000000..3b2b5d3d1d378
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll
@@ -0,0 +1,27 @@
+; A switch on an odd-width integer type.
+
+; RUN: llc -verify-machineinstrs -O2 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O2 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: %[[#I32:]] = OpTypeInt 32 0
+; CHECK: %[[#COND:]] = OpFunctionParameter %[[#I32]]
+; CHECK: OpSwitch %[[#COND]] %[[#]] 0 %[[#]] 1 %[[#]] 2 %[[#]]
+
+define spir_kernel void @fuzz_kernel(ptr addrspace(1) %in, ptr addrspace(1) %out, i31 %n) {
+entry:
+  switch i31 %n, label %d [
+    i31 0, label %m
+    i31 1, label %b
+    i31 2, label %c
+  ]
+b:
+  br label %m
+c:
+  br label %m
+d:
+  br label %m
+m:
+  %r = phi i31 [ 40, %d ], [ 20, %b ], [ 30, %c ], [ 1, %entry ]
+  store i31 %r, ptr addrspace(1) %out, align 4
+  ret void
+}

>From 6d7db73e485803aca99acc01bba1f933d18e57b2 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 8 Jul 2026 10:37:31 +0200
Subject: [PATCH 2/2] add test

---
 .../SPIRV/switch-odd-width-condition.ll       | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll b/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll
index 3b2b5d3d1d378..f161a5e7f8521 100644
--- a/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll
+++ b/llvm/test/CodeGen/SPIRV/switch-odd-width-condition.ll
@@ -25,3 +25,30 @@ m:
   store i31 %r, ptr addrspace(1) %out, align 4
   ret void
 }
+
+; The switch condition is also used by another instruction.
+
+; CHECK: %[[#COND2:]] = OpFunctionParameter %[[#I32]]
+; CHECK: OpSwitch %[[#COND2]] %[[#]] 0 %[[#]] 1 %[[#]] 2 %[[#]]
+
+define spir_kernel void @cond_used_elsewhere(ptr addrspace(1) %out, i31 %n) {
+entry:
+  switch i31 %n, label %d [
+    i31 0, label %a
+    i31 1, label %b
+    i31 2, label %c
+  ]
+a:
+  br label %m
+b:
+  br label %m
+c:
+  br label %m
+d:
+  br label %m
+m:
+  %r = phi i31 [ 40, %d ], [ 20, %a ], [ 30, %b ], [ 50, %c ]
+  %add = add i31 %r, %n
+  store i31 %add, ptr addrspace(1) %out, align 4
+  ret void
+}



More information about the llvm-commits mailing list