[llvm] 4a358b8 - [SPIR-V] Fix wrong element inferred for long vectors when using ByteAdressBuffer (#222220)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 20:00:15 PDT 2026
Author: Farzon Lotfi
Date: 2026-09-21T23:00:09-04:00
New Revision: 4a358b89216a4fa56b08355d2b00f694657f64ba
URL: https://github.com/llvm/llvm-project/commit/4a358b89216a4fa56b08355d2b00f694657f64ba
DIFF: https://github.com/llvm/llvm-project/commit/4a358b89216a4fa56b08355d2b00f694657f64ba.diff
LOG: [SPIR-V] Fix wrong element inferred for long vectors when using ByteAdressBuffer (#222220)
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
The Fix is to use spv_bitcast instead of an llvm ir bitcast. 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. switching to
spv_bitcast solves this because it forces a `buildAssignType` which will
preserve the type and allows us to distinguish ints from floats.
Added:
llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
Modified:
llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
llvm/test/CodeGen/SPIRV/passes/SPIRVLegalizePointerCast.ll
Removed:
################################################################################
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/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)
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..f1fbc1fe83b5f
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/pointers/byte-address-buffer-long-vector.ll
@@ -0,0 +1,32 @@
+; 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 --target-env vulkan1.3 %}
+
+; CHECK-DAG: %[[GLSLEXT:[0-9]+]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[FLOAT:[0-9]+]] = OpTypeFloat 32
+; CHECK-DAG: %[[V4FLOAT:[0-9]+]] = OpTypeVector %[[FLOAT]] 4
+; CHECK-LABEL: %[[#]] = OpFunction %[[#]] DontInline %[[#]] ; -- Begin function main
+; CHECK: OpBitcast %[[FLOAT]]
+; CHECK-COUNT-4: OpCompositeConstruct %[[V4FLOAT]]
+; CHECK-COUNT-4: OpExtInst %[[V4FLOAT]] %[[GLSLEXT]] {{Cosh}}
+
+
+ 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(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(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
+ %input.ptr = call ptr addrspace(11) @llvm.spv.resource.getpointer(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(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
+}
+
+
+attributes #0 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
More information about the llvm-commits
mailing list