[llvm] [SPIR-V] Fix wrong element inferred for long vectors when using ByteAdressBuffer (PR #222220)

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 08:55:52 PDT 2026


https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/222220

>From b90fd54b10b79817983aeafd882596584abc89c0 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <hi at farzon.org>
Date: Tue, 8 Sep 2026 22:10:09 -0400
Subject: [PATCH 1/5] [SPIR-V] Fix wrong element inferred for long vectors when
 using ByteAdressBuffer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

fixes #222214

On the offload tests we recently switch the long vector tests from using
StructuredBuffer element loads and stores to ByteAddressBuffer vector loads and stores
With StructuredBuffer you can see we use the right type for the vector
https://hlsl.godbolt.org/z/jYhd57jvn

However with ByteAddressBuffer instead of a float vector we are infering incorrectly an int vector https://hlsl.godbolt.org/z/KMnxfv8z6

This was a bug in the post legalizer and it seems somewhat specific to SPV_EXT_long_vector and its impact on ByteAddressBuffer because we are hitting a fallback that  mis-infers a vector’s scalar element type from an unrelated def in post-legalization use tracking.

It also seems G_UNMERGE_VALUES is a big reason why we are getting here. So to avoid itwe restrict result-type inference to the actual result def for single-def instructions.
---
 llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp  | 23 ++++++++++---------
 .../SPV_EXT_long_vector/vector-arithmetic.ll  | 20 ++++++++++++++++
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index 8136b054f007b..86f0dc11b5825 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -101,17 +101,18 @@ static SPIRVTypeInst deduceTypeFromResultRegister(MachineInstr *Use,
                                                   Register UseRegister,
                                                   SPIRVGlobalRegistry *GR,
                                                   MachineIRBuilder &MIB) {
-  for (const MachineOperand &MO : Use->defs()) {
-    if (!MO.isReg())
-      continue;
-    if (SPIRVTypeInst OpType = GR->getSPIRVTypeForVReg(MO.getReg())) {
-      if (SPIRVTypeInst CompType = GR->getScalarOrVectorComponentType(OpType)) {
-        const LLT &ResLLT = MIB.getMRI()->getType(UseRegister);
-        if (ResLLT.isVector())
-          return GR->getOrCreateSPIRVVectorType(
-              CompType, ResLLT.getNumElements(), MIB, false);
-        return CompType;
-      }
+
+  if (Use->getNumDefs() != 1 || !Use->getOperand(0).isReg())
+    return nullptr;
+
+  Register DefReg = Use->getOperand(0).getReg();
+  if (SPIRVTypeInst OpType = GR->getSPIRVTypeForVReg(DefReg)) {
+    if (SPIRVTypeInst CompType = GR->getScalarOrVectorComponentType(OpType)) {
+      const LLT &ResLLT = MIB.getMRI()->getType(UseRegister);
+      if (ResLLT.isVector())
+        return GR->getOrCreateSPIRVVectorType(CompType, ResLLT.getNumElements(),
+                                              MIB, false);
+      return CompType;
     }
   }
   return nullptr;
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll
index 4c3b08bc69a21..9c8d6fcfcd290 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll
@@ -8,10 +8,13 @@
 ; CHECK-DAG: %[[#c17:]] = OpConstant %[[#int]] 17
 ; CHECK-DAG: %[[#v17f32:]] = OpTypeVectorIdEXT %[[#float]] %[[#c17]]
 ; CHECK-DAG: %[[#v17i32:]] = OpTypeVectorIdEXT %[[#int]] %[[#c17]]
+; CHECK-DAG: %[[#v16f32:]] = OpTypeVector %[[#float]] 16
 ; CHECK-DAG: %[[#ptr_v17i32:]] = OpTypePointer CrossWorkgroup %[[#v17i32]]
 
 @f1 = internal addrspace(1) global [4 x [17 x float] ] zeroinitializer
 @f2 = internal addrspace(1) global [4 x [17 x float] ] zeroinitializer
+ at f16_1 = internal addrspace(1) global [16 x float] zeroinitializer
+ at f16_2 = internal addrspace(1) global [16 x float] zeroinitializer
 @i1 = internal addrspace(1) global [4 x [17 x i32] ] zeroinitializer
 @i2 = internal addrspace(1) global [4 x [17 x i32] ] zeroinitializer
 
@@ -126,4 +129,21 @@ entry:
   ret void
 }
 
+; Verify long-vector transcendental type inference keeps the float element type.
+define void @test_long_vector_cosh() local_unnamed_addr #0 {
+; CHECK: OpFunction
+entry:
+  %2 = getelementptr [16 x float], ptr addrspace(1) @f16_1, i32 0, i32 0
+  %3 = load <16 x float>, ptr addrspace(1) %2, align 4
+
+  ; CHECK: %{{[0-9]+}} = OpExtInst %42 %1 cosh %{{[0-9]+}}
+  %4 = call <16 x float> @llvm.cosh.v16f32(<16 x float> %3)
+
+  ; CHECK: OpStore {{.*}} %{{[0-9]+}}
+  %5 = getelementptr [16 x float], ptr addrspace(1) @f16_2, i32 0, i32 0
+  store <16 x float> %4, ptr addrspace(1) %5, align 4
+  ret void
+}
+
 declare <17 x float> @llvm.experimental.constrained.fma.v16f32(<17 x float>, <17 x float>, <17 x float>, metadata, metadata)
+declare <16 x float> @llvm.cosh.v16f32(<16 x float>)

>From eac888bb9ee918c6ed72e812f37d9507826c876b Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Mon, 14 Sep 2026 13:05:31 -0400
Subject: [PATCH 2/5] Revert "[SPIR-V] Fix wrong element inferred for long
 vectors when using ByteAdressBuffer"

This reverts commit b35dd51ac38ebca2a8f83d63fa1abba199c70eff.

Instead we switch a llvmir bitcast to spv_bitcast.

spv_bitcast preserves a distinction that ordinary GlobalISel types cannot represent.
An ordinary LLVM bitcast i32 to float becomes a same-size GlobalISel operation. Both i32 and float use the same low-level type, s32, so legalization/coalescing can eliminate the bitcast.
The issue then surfaces when the surviving register retains the integer SPIR-V type from the shifts and ORs.

That incorrect scalar type then propagates:

```
OpTypeInt 32 --> G_BUILD_VECTOR --> %v4uint --> Cosh
```

switching to spv_bitcast. solves this bevause it forces a
buildAssignType which will preserve the type in this case

OpTypeFloat 32  --> G_BUILD_VECTOR --> %v4float --> Cosh
---
 .../Target/SPIRV/SPIRVLegalizePointerCast.cpp |  7 +++-
 llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp  | 23 ++++++------
 .../SPV_EXT_long_vector/vector-arithmetic.ll  | 20 ----------
 .../byte-address-buffer-long-vector.ll        | 37 +++++++++++++++++++
 4 files changed, 53 insertions(+), 34 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
index 0addccdff4784..3fd9880392a5a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
@@ -266,7 +266,7 @@ class SPIRVLegalizePointerCastImpl {
       return Scalar;
     if (Ty->isIntOrIntVectorTy())
       return B.CreateIntCast(Scalar, IntTy, /*isSigned=*/false);
-    return B.CreateBitCast(Scalar, IntTy);
+    return B.CreateIntrinsic(Intrinsic::spv_bitcast, {IntTy, Ty}, {Scalar});
   }
 
   Value *storeIntToScalar(IRBuilder<> &B, Value *IntVal, Type *ScalarTy) {
@@ -274,7 +274,8 @@ class SPIRVLegalizePointerCastImpl {
       return IntVal;
     if (ScalarTy->isIntOrIntVectorTy())
       return B.CreateIntCast(IntVal, ScalarTy, /*isSigned=*/false);
-    return B.CreateBitCast(IntVal, ScalarTy);
+    return B.CreateIntrinsic(Intrinsic::spv_bitcast,
+                             {ScalarTy, IntVal->getType()}, {IntVal});
   }
 
   void storeScalarToByteLayout(IRBuilder<> &B, Value *Src, Value *Dst,
@@ -283,6 +284,8 @@ class SPIRVLegalizePointerCastImpl {
     Type *I8Ty = Type::getInt8Ty(Ctx);
     const DataLayout &DL = B.GetInsertBlock()->getModule()->getDataLayout();
     Value *IntVal = scalarToStoreInt(B, Src);
+    if (IntVal != Src)
+      buildAssignType(B, IntVal->getType(), IntVal);
     unsigned NumBytes = DL.getTypeStoreSize(Src->getType());
 
     auto StoreByte = [&](unsigned I, Value *Shifted) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index 86f0dc11b5825..8136b054f007b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -101,18 +101,17 @@ static SPIRVTypeInst deduceTypeFromResultRegister(MachineInstr *Use,
                                                   Register UseRegister,
                                                   SPIRVGlobalRegistry *GR,
                                                   MachineIRBuilder &MIB) {
-
-  if (Use->getNumDefs() != 1 || !Use->getOperand(0).isReg())
-    return nullptr;
-
-  Register DefReg = Use->getOperand(0).getReg();
-  if (SPIRVTypeInst OpType = GR->getSPIRVTypeForVReg(DefReg)) {
-    if (SPIRVTypeInst CompType = GR->getScalarOrVectorComponentType(OpType)) {
-      const LLT &ResLLT = MIB.getMRI()->getType(UseRegister);
-      if (ResLLT.isVector())
-        return GR->getOrCreateSPIRVVectorType(CompType, ResLLT.getNumElements(),
-                                              MIB, false);
-      return CompType;
+  for (const MachineOperand &MO : Use->defs()) {
+    if (!MO.isReg())
+      continue;
+    if (SPIRVTypeInst OpType = GR->getSPIRVTypeForVReg(MO.getReg())) {
+      if (SPIRVTypeInst CompType = GR->getScalarOrVectorComponentType(OpType)) {
+        const LLT &ResLLT = MIB.getMRI()->getType(UseRegister);
+        if (ResLLT.isVector())
+          return GR->getOrCreateSPIRVVectorType(
+              CompType, ResLLT.getNumElements(), MIB, false);
+        return CompType;
+      }
     }
   }
   return nullptr;
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll
index 9c8d6fcfcd290..4c3b08bc69a21 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_long_vector/vector-arithmetic.ll
@@ -8,13 +8,10 @@
 ; CHECK-DAG: %[[#c17:]] = OpConstant %[[#int]] 17
 ; CHECK-DAG: %[[#v17f32:]] = OpTypeVectorIdEXT %[[#float]] %[[#c17]]
 ; CHECK-DAG: %[[#v17i32:]] = OpTypeVectorIdEXT %[[#int]] %[[#c17]]
-; CHECK-DAG: %[[#v16f32:]] = OpTypeVector %[[#float]] 16
 ; CHECK-DAG: %[[#ptr_v17i32:]] = OpTypePointer CrossWorkgroup %[[#v17i32]]
 
 @f1 = internal addrspace(1) global [4 x [17 x float] ] zeroinitializer
 @f2 = internal addrspace(1) global [4 x [17 x float] ] zeroinitializer
- at f16_1 = internal addrspace(1) global [16 x float] zeroinitializer
- at f16_2 = internal addrspace(1) global [16 x float] zeroinitializer
 @i1 = internal addrspace(1) global [4 x [17 x i32] ] zeroinitializer
 @i2 = internal addrspace(1) global [4 x [17 x i32] ] zeroinitializer
 
@@ -129,21 +126,4 @@ entry:
   ret void
 }
 
-; Verify long-vector transcendental type inference keeps the float element type.
-define void @test_long_vector_cosh() local_unnamed_addr #0 {
-; CHECK: OpFunction
-entry:
-  %2 = getelementptr [16 x float], ptr addrspace(1) @f16_1, i32 0, i32 0
-  %3 = load <16 x float>, ptr addrspace(1) %2, align 4
-
-  ; CHECK: %{{[0-9]+}} = OpExtInst %42 %1 cosh %{{[0-9]+}}
-  %4 = call <16 x float> @llvm.cosh.v16f32(<16 x float> %3)
-
-  ; CHECK: OpStore {{.*}} %{{[0-9]+}}
-  %5 = getelementptr [16 x float], ptr addrspace(1) @f16_2, i32 0, i32 0
-  store <16 x float> %4, ptr addrspace(1) %5, align 4
-  ret void
-}
-
 declare <17 x float> @llvm.experimental.constrained.fma.v16f32(<17 x float>, <17 x float>, <17 x float>, metadata, metadata)
-declare <16 x float> @llvm.cosh.v16f32(<16 x float>)
diff --git a/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
new file mode 100644
index 0000000000000..05cc2fbd0d3a1
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
@@ -0,0 +1,37 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[FLOAT:[0-9]+]] = OpTypeFloat 32
+; CHECK-DAG: %[[UINT:[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: %[[V4FLOAT:[0-9]+]] = OpTypeVector %[[FLOAT]] 4
+; CHECK: OpBitcast %[[FLOAT]]
+; CHECK: OpCompositeConstruct %[[V4FLOAT]]
+; CHECK: OpExtInst %[[V4FLOAT]] {{.*}} {{[Cc]osh}}
+; CHECK: OpBitcast %[[UINT]]
+
+ at .str = private unnamed_addr constant [4 x i8] c"In0\00", align 1
+ at .str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1
+
+declare token @llvm.experimental.convergence.entry()
+
+define void @main() local_unnamed_addr #0 {
+entry:
+  %convergence = tail call token @llvm.experimental.convergence.entry()
+  %input = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_0t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
+  %output = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_1t(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
+  %input.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_0t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 0) %input, i32 0) [ "convergencectrl"(token %convergence) ]
+  %value = load <16 x float>, ptr addrspace(11) %input.ptr, align 4
+  %result = tail call <16 x float> @llvm.cosh.v16f32(<16 x float> %value)
+  %output.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_1t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 1) %output, i32 0) [ "convergencectrl"(token %convergence) ]
+  store <16 x float> %result, ptr addrspace(11) %output.ptr, align 4
+  ret void
+}
+
+declare <16 x float> @llvm.cosh.v16f32(<16 x float>)
+
+declare target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_0t(i32, i32, i32, i32, ptr)
+declare target("spirv.VulkanBuffer", [0 x i8], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_1t(i32, i32, i32, i32, ptr)
+declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_0t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 0), i32)
+declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_1t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 1), i32)
+
+attributes #0 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

>From 24a8f63b90ea0e95adcff8c63f718a065238c40c Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Mon, 14 Sep 2026 14:59:49 -0400
Subject: [PATCH 3/5] update the test to have stricker checks and less naming
 noise.

---
 .../byte-address-buffer-long-vector.ll        | 25 ++++++++++---------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
index 05cc2fbd0d3a1..040c4b04cd68f 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
@@ -1,13 +1,14 @@
 ; RUN: llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val --target-env vulkan1.3 %}
 
+; CHECK-DAG: %[[GLSLEXT:[0-9]+]] = OpExtInstImport "GLSL.std.450"
 ; CHECK-DAG: %[[FLOAT:[0-9]+]] = OpTypeFloat 32
 ; CHECK-DAG: %[[UINT:[0-9]+]] = OpTypeInt 32 0
 ; CHECK-DAG: %[[V4FLOAT:[0-9]+]] = OpTypeVector %[[FLOAT]] 4
 ; CHECK: OpBitcast %[[FLOAT]]
-; CHECK: OpCompositeConstruct %[[V4FLOAT]]
-; CHECK: OpExtInst %[[V4FLOAT]] {{.*}} {{[Cc]osh}}
-; CHECK: OpBitcast %[[UINT]]
+; CHECK-COUNT-4: OpCompositeConstruct %[[V4FLOAT]]
+; CHECK-COUNT-4: OpExtInst %[[V4FLOAT]] %[[GLSLEXT]] {{Cosh}}
+
 
 @.str = private unnamed_addr constant [4 x i8] c"In0\00", align 1
 @.str.2 = private unnamed_addr constant [4 x i8] c"Out\00", align 1
@@ -17,21 +18,21 @@ declare token @llvm.experimental.convergence.entry()
 define void @main() local_unnamed_addr #0 {
 entry:
   %convergence = tail call token @llvm.experimental.convergence.entry()
-  %input = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_0t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
-  %output = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_1t(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
-  %input.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_0t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 0) %input, i32 0) [ "convergencectrl"(token %convergence) ]
+  %input = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding.t0(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
+  %output = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 1) @llvm.spv.resource.handlefrombinding.t1(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
+  %input.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.t0(target("spirv.VulkanBuffer", [0 x i8], 12, 0) %input, i32 0) [ "convergencectrl"(token %convergence) ]
   %value = load <16 x float>, ptr addrspace(11) %input.ptr, align 4
   %result = tail call <16 x float> @llvm.cosh.v16f32(<16 x float> %value)
-  %output.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_1t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 1) %output, i32 0) [ "convergencectrl"(token %convergence) ]
+  %output.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer.t1(target("spirv.VulkanBuffer", [0 x i8], 12, 1) %output, i32 0) [ "convergencectrl"(token %convergence) ]
   store <16 x float> %result, ptr addrspace(11) %output.ptr, align 4
   ret void
 }
 
 declare <16 x float> @llvm.cosh.v16f32(<16 x float>)
 
-declare target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_0t(i32, i32, i32, i32, ptr)
-declare target("spirv.VulkanBuffer", [0 x i8], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i8_12_1t(i32, i32, i32, i32, ptr)
-declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_0t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 0), i32)
-declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i8_12_1t.i32(target("spirv.VulkanBuffer", [0 x i8], 12, 1), i32)
+declare target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding.t0(i32, i32, i32, i32, ptr)
+declare target("spirv.VulkanBuffer", [0 x i8], 12, 1) @llvm.spv.resource.handlefrombinding.t1(i32, i32, i32, i32, ptr)
+declare ptr addrspace(11) @llvm.spv.resource.getpointer.t0(target("spirv.VulkanBuffer", [0 x i8], 12, 0), i32)
+declare ptr addrspace(11) @llvm.spv.resource.getpointer.t1(target("spirv.VulkanBuffer", [0 x i8], 12, 1), i32)
 
 attributes #0 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

>From a03e719d2a57dee0521cd2dfacab3da21e13b439 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Tue, 15 Sep 2026 23:59:05 -0400
Subject: [PATCH 4/5] remove unused check-dag for uint since we are not
 checking OpBitwiseOr anymore

---
 .../CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll    | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
index 040c4b04cd68f..9e5bdaef0cd3a 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
@@ -3,7 +3,6 @@
 
 ; CHECK-DAG: %[[GLSLEXT:[0-9]+]] = OpExtInstImport "GLSL.std.450"
 ; CHECK-DAG: %[[FLOAT:[0-9]+]] = OpTypeFloat 32
-; CHECK-DAG: %[[UINT:[0-9]+]] = OpTypeInt 32 0
 ; CHECK-DAG: %[[V4FLOAT:[0-9]+]] = OpTypeVector %[[FLOAT]] 4
 ; CHECK: OpBitcast %[[FLOAT]]
 ; CHECK-COUNT-4: OpCompositeConstruct %[[V4FLOAT]]

>From e67b731048d26ba7a900432ccb8e18076147a431 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Wed, 16 Sep 2026 11:55:33 -0400
Subject: [PATCH 5/5] switch test to show that we now use the spv bitcast
 instrinsic

---
 llvm/test/CodeGen/SPIRV/passes/SPIRVLegalizePointerCast.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/SPIRV/passes/SPIRVLegalizePointerCast.ll b/llvm/test/CodeGen/SPIRV/passes/SPIRVLegalizePointerCast.ll
index 114c8938d9971..80efa749a4260 100644
--- a/llvm/test/CodeGen/SPIRV/passes/SPIRVLegalizePointerCast.ll
+++ b/llvm/test/CodeGen/SPIRV/passes/SPIRVLegalizePointerCast.ll
@@ -257,7 +257,7 @@ define void @byteBufferLoadFloat() {
 ; CHECK-LABEL: define void @byteBufferLoadFloat(
 ; CHECK-NOT: call {{.*}}@llvm.spv.ptrcast
 ; CHECK: load i8, ptr addrspace(11)
-; CHECK: bitcast i32 {{.*}} to float
+; CHECK: call float @llvm.spv.bitcast.f32.i32(i32 {{.*}})
 ; CHECK: store float {{.*}}, ptr addrspace(10) @outF
 entry:
   %handle = tail call target("spirv.VulkanBuffer", [0 x i8], 12, 0) @llvm.spv.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)



More information about the llvm-commits mailing list