Skip to content

[SPIR-V] Add spv.gep support for ptrcast legal #134388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 8, 2025

Conversation

Keenuts
Copy link
Contributor

@Keenuts Keenuts commented Apr 4, 2025

Adds support the the spv.gep intrinsic to the spv ptrcast legalization step. Those intrinsics are generated by the backend thus not directly visible in the tests.
This is a pre-requisite to implement addrspacecast legalization for logical SPIR-V.

Adds support the the spv.gep intrinsic to the spv ptrcast legalization
step. Those intrinsics are generated by the backend thus not
directly visible in the tests.
This is a pre-requisite to implement addrspacecast legalization for
logical SPIR-V.
@llvmbot
Copy link
Member

llvmbot commented Apr 4, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Nathan Gauër (Keenuts)

Changes

Adds support the the spv.gep intrinsic to the spv ptrcast legalization step. Those intrinsics are generated by the backend thus not directly visible in the tests.
This is a pre-requisite to implement addrspacecast legalization for logical SPIR-V.


Full diff: https://github.com/llvm/llvm-project/pull/134388.diff

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp (+6)
  • (added) llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-struct.ll (+47)
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
index 560869f9fe62a..5ba4fbb02560d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
@@ -170,6 +170,12 @@ class SPIRVLegalizePointerCast : public FunctionPass {
           DeadInstructions.push_back(Intrin);
           continue;
         }
+
+        if (Intrin->getIntrinsicID() == Intrinsic::spv_gep) {
+          GR->replaceAllUsesWith(CastedOperand, OriginalOperand,
+                                 /* DeleteOld= */ false);
+          continue;
+        }
       }
 
       llvm_unreachable("Unsupported ptrcast user. Please fix.");
diff --git a/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-struct.ll b/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-struct.ll
new file mode 100644
index 0000000000000..b0a68a30e29be
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-struct.ll
@@ -0,0 +1,47 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - | FileCheck %s --match-full-lines
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG:       %[[#uint:]] = OpTypeInt 32 0
+; CHECK-DAG:     %[[#uint64:]] = OpTypeInt 64 0
+; CHECK-DAG:    %[[#uint_pp:]] = OpTypePointer Private %[[#uint]]
+; CHECK-DAG:     %[[#uint_0:]] = OpConstant %[[#uint]] 0
+; CHECK-DAG:     %[[#uint_1:]] = OpConstant %[[#uint]] 1
+; CHECK-DAG:    %[[#uint_10:]] = OpConstant %[[#uint]] 10
+; CHECK-DAG:    %[[#t_array:]] = OpTypeArray %[[#uint]] %[[#uint_10]]
+; CHECK-DAG:       %[[#t_s1:]] = OpTypeStruct %[[#t_array]]
+; CHECK-DAG:       %[[#t_s2_s_a_s:]] = OpTypeStruct %[[#uint]] %[[#uint]]
+; CHECK-DAG:       %[[#t_s2_s_a:]] = OpTypeArray %[[#t_s2_s_a_s]] %[[#uint_10]]
+; CHECK-DAG:       %[[#t_s2_s:]] = OpTypeStruct %[[#t_s2_s_a]]
+; CHECK-DAG:       %[[#t_s2:]] = OpTypeStruct %[[#t_s2_s]] %[[#uint]]
+; CHECK-DAG:     %[[#null_s1:]] = OpConstantNull %[[#t_s1]]
+; CHECK-DAG:     %[[#null_s2:]] = OpConstantNull %[[#t_s2]]
+; CHECK-DAG:  %[[#ptr_s1:]] = OpTypePointer Private %[[#t_s1]]
+; CHECK-DAG:  %[[#ptr_s2:]] = OpTypePointer Private %[[#t_s2]]
+
+%S1 = type { [10 x i32] }
+%S2 = type { { [10 x { i32, i32 } ] }, i32 }
+
+; CHECK-DAG: %[[#global1:]] = OpVariable %[[#ptr_s1]] Private %[[#null_s1]]
+@global1 = internal addrspace(10) global %S1 zeroinitializer
+; CHECK-DAG: %[[#global2:]] = OpVariable %[[#ptr_s2]] Private %[[#null_s2]]
+@global2 = internal addrspace(10) global %S2 zeroinitializer
+
+define spir_func noundef i32 @foo(i64 noundef %index) local_unnamed_addr {
+; CHECK: %[[#index:]] = OpFunctionParameter %[[#uint64]]
+entry:
+; CHECK: %[[#ptr:]] = OpInBoundsAccessChain %[[#uint_pp]] %[[#global1]] %[[#uint_0]] %[[#index]]
+  %ptr = getelementptr inbounds %S1, ptr addrspace(10) @global1, i64 0, i32 0, i64 %index
+; CHECK: %[[#val:]] = OpLoad %[[#uint]] %[[#ptr]] Aligned 4
+  %val = load i32, ptr addrspace(10) %ptr
+  ret i32 %val
+}
+
+define spir_func noundef i32 @bar(i64 noundef %index) local_unnamed_addr {
+; CHECK: %[[#index:]] = OpFunctionParameter %[[#uint64]]
+entry:
+; CHECK: %[[#ptr:]] = OpInBoundsAccessChain %[[#uint_pp]] %[[#global2]] %[[#uint_0]] %[[#uint_0]] %[[#index]] %[[#uint_1]]
+  %ptr = getelementptr inbounds %S2, ptr addrspace(10) @global2, i64 0, i32 0, i32 0, i64 %index, i32 1
+; CHECK: %[[#val:]] = OpLoad %[[#uint]] %[[#ptr]] Aligned 4
+  %val = load i32, ptr addrspace(10) %ptr
+  ret i32 %val
+}

@Keenuts Keenuts merged commit 739062d into llvm:main Apr 8, 2025
14 checks passed
@Keenuts Keenuts deleted the ptrcast-legal branch April 8, 2025 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants