[llvm] [SPIR-V] Add spv.gep support for ptrcast legal (PR #134388)
Nathan Gauër via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 4 07:36:34 PDT 2025
https://github.com/Keenuts created https://github.com/llvm/llvm-project/pull/134388
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.
>From 4f977311f67a773a2fe17304d320c450829c9e40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Fri, 4 Apr 2025 16:01:26 +0200
Subject: [PATCH] [SPIR-V] Add spv.gep support for ptrcast legal
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.
---
.../Target/SPIRV/SPIRVLegalizePointerCast.cpp | 6 +++
.../pointers/getelementptr-downcast-struct.ll | 47 +++++++++++++++++++
2 files changed, 53 insertions(+)
create mode 100644 llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-struct.ll
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]]
+ at global1 = internal addrspace(10) global %S1 zeroinitializer
+; CHECK-DAG: %[[#global2:]] = OpVariable %[[#ptr_s2]] Private %[[#null_s2]]
+ at 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
+}
More information about the llvm-commits
mailing list