[llvm] [SPIR-V] Prevent type change of GEP results in type inference (PR #129250)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 28 06:16:36 PST 2025
https://github.com/VyacheslavLevytskyy created https://github.com/llvm/llvm-project/pull/129250
The following reproducer demonstrates the issue with invalid definition of GEP results during type inference
```
define spir_kernel void @foo(i1 %fl, i64 %idx, ptr addrspace(1) %dest, ptr addrspace(3) %src) {
%p1 = getelementptr inbounds i8, ptr addrspace(1) %dest, i64 %idx
%res = tail call spir_func target("spirv.Event") @_Z22__spirv_GroupAsyncCopyjPU3AS1iPU3AS3Kimm9ocl_event(i32 2, ptr addrspace(1) %p1, ptr addrspace(3) %src, i64 128, i64 1, target("spirv.Event") zeroinitializer)
ret void
}
declare dso_local spir_func target("spirv.Event") @_Z22__spirv_GroupAsyncCopyjPU3AS1iPU3AS3Kimm9ocl_event(i32, ptr addrspace(1), ptr addrspace(3), i64, i64, target("spirv.Event"))
```
Here `OpGroupAsyncCopy` expects i32* arguments and type inference fails to set a correct type of the GEP result `%p1`, because it is an argument of `OpGroupAsyncCopy`.
This PR fixes the issue by preventing type change of GEP results in type inference.
>From 3aa9980ed41d2841d61ac1698d1e8a560779a27f Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Fri, 28 Feb 2025 06:13:22 -0800
Subject: [PATCH] Prevent type change of GEP results in type inference
---
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 4 ++++
.../SPIRV/pointers/ptr-access-chain-type.ll | 24 +++++++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 llvm/test/CodeGen/SPIRV/pointers/ptr-access-chain-type.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 5dfba8427258f..bedd454b34a36 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -2307,6 +2307,7 @@ bool SPIRVEmitIntrinsics::processFunctionPointers(Module &M) {
// Apply types parsed from demangled function declarations.
void SPIRVEmitIntrinsics::applyDemangledPtrArgTypes(IRBuilder<> &B) {
+ DenseMap<Function *, CallInst *> Ptrcasts;
for (auto It : FDeclPtrTys) {
Function *F = It.first;
for (auto *U : F->users()) {
@@ -2326,6 +2327,9 @@ void SPIRVEmitIntrinsics::applyDemangledPtrArgTypes(IRBuilder<> &B) {
B.SetCurrentDebugLocation(DebugLoc());
buildAssignPtr(B, ElemTy, Arg);
}
+ } else if (isa<GetElementPtrInst>(Param)) {
+ replaceUsesOfWithSpvPtrcast(Param, normalizeType(ElemTy), CI,
+ Ptrcasts);
} else if (isa<Instruction>(Param)) {
GR->addDeducedElementType(Param, normalizeType(ElemTy));
// insertAssignTypeIntrs() will complete buildAssignPtr()
diff --git a/llvm/test/CodeGen/SPIRV/pointers/ptr-access-chain-type.ll b/llvm/test/CodeGen/SPIRV/pointers/ptr-access-chain-type.ll
new file mode 100644
index 0000000000000..d69959609c9dc
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/pointers/ptr-access-chain-type.ll
@@ -0,0 +1,24 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#Char:]] = OpTypeInt 8 0
+; CHECK-DAG: %[[#Long:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#CharPtr:]] = OpTypePointer CrossWorkgroup %[[#Char]]
+; CHECK-DAG: %[[#LongPtr:]] = OpTypePointer CrossWorkgroup %[[#Long]]
+; CHECK-DAG: %[[#LongPtrWG:]] = OpTypePointer Workgroup %[[#Long]]
+; CHECK: OpFunction
+; CHECK: OpFunctionParameter
+; CHECK: %[[#Dest:]] = OpFunctionParameter %[[#CharPtr]]
+; CHECK: %[[#Src:]] = OpFunctionParameter %[[#LongPtrWG]]
+; CHECK: %[[#InDest:]] = OpInBoundsPtrAccessChain %[[#CharPtr]] %[[#Dest]] %[[#]]
+; CHECK: %[[#InDestCasted:]] = OpBitcast %[[#LongPtr]] %[[#InDest]]
+; CHECK: OpGroupAsyncCopy %[[#]] %[[#]] %[[#InDestCasted]] %[[#Src]] %[[#]] %[[#]] %[[#]]
+
+define spir_kernel void @foo(i64 %idx, ptr addrspace(1) %dest, ptr addrspace(3) %src) {
+ %p1 = getelementptr inbounds i8, ptr addrspace(1) %dest, i64 %idx
+ %res = tail call spir_func target("spirv.Event") @_Z22__spirv_GroupAsyncCopyjPU3AS1iPU3AS3Kimm9ocl_event(i32 2, ptr addrspace(1) %p1, ptr addrspace(3) %src, i64 128, i64 1, target("spirv.Event") zeroinitializer)
+ ret void
+}
+
+; For this test case the mangling is important.
+declare dso_local spir_func target("spirv.Event") @_Z22__spirv_GroupAsyncCopyjPU3AS1iPU3AS3Kimm9ocl_event(i32, ptr addrspace(1), ptr addrspace(3), i64, i64, target("spirv.Event"))
More information about the llvm-commits
mailing list