[clang] [clang][SPIRV] Coerce pointer kernel arguments to global AS (PR #185498)
Nick Sarnie via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 10 06:49:17 PDT 2026
https://github.com/sarnex updated https://github.com/llvm/llvm-project/pull/185498
>From 8235d5a551461c3a052eaa65f2d9ec2fb4006157 Mon Sep 17 00:00:00 2001
From: Nick Sarnie <nick.sarnie at intel.com>
Date: Mon, 9 Mar 2026 12:27:18 -0700
Subject: [PATCH 1/2] [clang][SPIRV] Corerce pointer kernel arguments to global
AS
Signed-off-by: Nick Sarnie <nick.sarnie at intel.com>
---
clang/lib/CodeGen/Targets/SPIR.cpp | 9 +++++----
clang/test/CodeGenSPIRV/spirv-intel-kernel.c | 18 ++++++++++++++++++
2 files changed, 23 insertions(+), 4 deletions(-)
create mode 100644 clang/test/CodeGenSPIRV/spirv-intel-kernel.c
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index 52d019b855dbc..88ac65b91d03e 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -146,11 +146,12 @@ void CommonSPIRABIInfo::setCCs() {
}
ABIArgInfo SPIRVABIInfo::classifyKernelArgumentType(QualType Ty) const {
- if (getContext().getLangOpts().isTargetDevice()) {
+ if (getContext().getLangOpts().isTargetDevice() ||
+ getTarget().getTriple().getVendor() == llvm::Triple::Intel) {
// Coerce pointer arguments with default address space to CrossWorkGroup
- // pointers for target devices as default address space kernel arguments
- // are not allowed. We use the opencl_global language address space which
- // always maps to CrossWorkGroup.
+ // pointers for target/Intel devices as default address space kernel
+ // arguments are not allowed. We use the opencl_global language address
+ // space which always maps to CrossWorkGroup.
llvm::Type *LTy = CGT.ConvertType(Ty);
auto DefaultAS = getContext().getTargetAddressSpace(LangAS::Default);
auto GlobalAS = getContext().getTargetAddressSpace(LangAS::opencl_global);
diff --git a/clang/test/CodeGenSPIRV/spirv-intel-kernel.c b/clang/test/CodeGenSPIRV/spirv-intel-kernel.c
new file mode 100644
index 0000000000000..f709df7af9903
--- /dev/null
+++ b/clang/test/CodeGenSPIRV/spirv-intel-kernel.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple spirv64-intel %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv32-intel %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: define spir_func void @func(ptr addrspace(4) noundef %{{.*}})
+void func(int* arg) {
+}
+
+// CHECK: define spir_kernel void @kernel(ptr addrspace(1) noundef %{{.*}})
+void __attribute__((device_kernel)) kernel(int* arg) {
+// CHECK: call spir_func{{.*}} void @func(ptr addrspace(4) noundef %{{.*}})
+ func(arg);
+}
+
+// CHECK: define spir_kernel void @kernel_spec(ptr addrspace(2) noundef %{{.*}})
+void __attribute__((device_kernel)) kernel_spec(__attribute__((address_space(2))) int* arg) {
+// CHECK: call spir_func{{.*}} void @func(ptr addrspace(4) noundef %{{.*}})
+ func((int*)arg);
+}
>From 291bbef531131d23fa3106e3eb8c04d9a516bae8 Mon Sep 17 00:00:00 2001
From: Nick Sarnie <nick.sarnie at intel.com>
Date: Tue, 10 Mar 2026 06:46:08 -0700
Subject: [PATCH 2/2] make generic
Signed-off-by: Nick Sarnie <nick.sarnie at intel.com>
---
clang/lib/CodeGen/Targets/SPIR.cpp | 48 ++++++++++----------
clang/test/CodeGenSPIRV/kernel-ptr-arg.c | 18 ++++++++
clang/test/CodeGenSPIRV/spirv-intel-kernel.c | 18 --------
3 files changed, 41 insertions(+), 43 deletions(-)
create mode 100644 clang/test/CodeGenSPIRV/kernel-ptr-arg.c
delete mode 100644 clang/test/CodeGenSPIRV/spirv-intel-kernel.c
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index 88ac65b91d03e..4d902fe2d6e3e 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -146,32 +146,30 @@ void CommonSPIRABIInfo::setCCs() {
}
ABIArgInfo SPIRVABIInfo::classifyKernelArgumentType(QualType Ty) const {
- if (getContext().getLangOpts().isTargetDevice() ||
- getTarget().getTriple().getVendor() == llvm::Triple::Intel) {
- // Coerce pointer arguments with default address space to CrossWorkGroup
- // pointers for target/Intel devices as default address space kernel
- // arguments are not allowed. We use the opencl_global language address
- // space which always maps to CrossWorkGroup.
- llvm::Type *LTy = CGT.ConvertType(Ty);
- auto DefaultAS = getContext().getTargetAddressSpace(LangAS::Default);
- auto GlobalAS = getContext().getTargetAddressSpace(LangAS::opencl_global);
- auto *PtrTy = llvm::dyn_cast<llvm::PointerType>(LTy);
- if (PtrTy && PtrTy->getAddressSpace() == DefaultAS) {
- LTy = llvm::PointerType::get(PtrTy->getContext(), GlobalAS);
- return ABIArgInfo::getDirect(LTy, 0, nullptr, false);
- }
+ // Coerce pointer arguments with default address space to CrossWorkGroup
+ // pointers as default address space kernel
+ // arguments are not allowed. We use the opencl_global language address
+ // space which always maps to CrossWorkGroup.
+ llvm::Type *LTy = CGT.ConvertType(Ty);
+ auto DefaultAS = getContext().getTargetAddressSpace(LangAS::Default);
+ auto GlobalAS = getContext().getTargetAddressSpace(LangAS::opencl_global);
+ auto *PtrTy = llvm::dyn_cast<llvm::PointerType>(LTy);
+ if (PtrTy && PtrTy->getAddressSpace() == DefaultAS) {
+ LTy = llvm::PointerType::get(PtrTy->getContext(), GlobalAS);
+ return ABIArgInfo::getDirect(LTy, 0, nullptr, false);
+ }
- if (isAggregateTypeForABI(Ty)) {
- // Force copying aggregate type in kernel arguments by value when
- // compiling CUDA targeting SPIR-V. This is required for the object
- // copied to be valid on the device.
- // This behavior follows the CUDA spec
- // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#global-function-argument-processing,
- // and matches the NVPTX implementation. TODO: hardcoding to 0 should be
- // revisited if HIPSPV / byval starts making use of the AS of an indirect
- // arg.
- return getNaturalAlignIndirect(Ty, /*AddrSpace=*/0, /*byval=*/true);
- }
+ if (getContext().getLangOpts().isTargetDevice() &&
+ isAggregateTypeForABI(Ty)) {
+ // Force copying aggregate type in kernel arguments by value when
+ // compiling CUDA targeting SPIR-V. This is required for the object
+ // copied to be valid on the device.
+ // This behavior follows the CUDA spec
+ // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#global-function-argument-processing,
+ // and matches the NVPTX implementation. TODO: hardcoding to 0 should be
+ // revisited if HIPSPV / byval starts making use of the AS of an indirect
+ // arg.
+ return getNaturalAlignIndirect(Ty, /*AddrSpace=*/0, /*byval=*/true);
}
return classifyArgumentType(Ty);
}
diff --git a/clang/test/CodeGenSPIRV/kernel-ptr-arg.c b/clang/test/CodeGenSPIRV/kernel-ptr-arg.c
new file mode 100644
index 0000000000000..8f6dff83fea71
--- /dev/null
+++ b/clang/test/CodeGenSPIRV/kernel-ptr-arg.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple spirv64 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv32 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: define spir_func void @func(ptr noundef %{{.*}})
+void func(int* arg) {
+}
+
+// CHECK: define spir_kernel void @kernel(ptr addrspace(1) noundef %{{.*}})
+void __attribute__((device_kernel)) kernel(int* arg) {
+// CHECK: call spir_func{{.*}} void @func(ptr noundef %{{.*}})
+ func(arg);
+}
+
+// CHECK: define spir_kernel void @kernel_spec(ptr addrspace(2) noundef %{{.*}})
+void __attribute__((device_kernel)) kernel_spec(__attribute__((address_space(2))) int* arg) {
+// CHECK: call spir_func{{.*}} void @func(ptr noundef %{{.*}})
+ func((int*)arg);
+}
diff --git a/clang/test/CodeGenSPIRV/spirv-intel-kernel.c b/clang/test/CodeGenSPIRV/spirv-intel-kernel.c
deleted file mode 100644
index f709df7af9903..0000000000000
--- a/clang/test/CodeGenSPIRV/spirv-intel-kernel.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -triple spirv64-intel %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple spirv32-intel %s -emit-llvm -o - | FileCheck %s
-
-// CHECK: define spir_func void @func(ptr addrspace(4) noundef %{{.*}})
-void func(int* arg) {
-}
-
-// CHECK: define spir_kernel void @kernel(ptr addrspace(1) noundef %{{.*}})
-void __attribute__((device_kernel)) kernel(int* arg) {
-// CHECK: call spir_func{{.*}} void @func(ptr addrspace(4) noundef %{{.*}})
- func(arg);
-}
-
-// CHECK: define spir_kernel void @kernel_spec(ptr addrspace(2) noundef %{{.*}})
-void __attribute__((device_kernel)) kernel_spec(__attribute__((address_space(2))) int* arg) {
-// CHECK: call spir_func{{.*}} void @func(ptr addrspace(4) noundef %{{.*}})
- func((int*)arg);
-}
More information about the cfe-commits
mailing list