[llvm] [SPIRV] Add support for CodeSectionINTEL storage class in legalizer (PR #167961)
Nick Sarnie via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 17 08:00:09 PST 2025
https://github.com/sarnex updated https://github.com/llvm/llvm-project/pull/167961
>From d7eff11900eb5eae01a16b8facf33e770553a76e Mon Sep 17 00:00:00 2001
From: Nick Sarnie <nick.sarnie at intel.com>
Date: Thu, 13 Nov 2025 13:46:11 -0800
Subject: [PATCH 1/2] [SPIRV] Add support for CodeSectionINTEL addrspace in
legalizer
Signed-off-by: Nick Sarnie <nick.sarnie at intel.com>
---
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 40 ++++++++++++-------
.../SPIRV/GlobalISel/fn-ptr-addrspacecast.ll | 9 +++++
.../CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll | 9 +++++
.../CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll | 9 +++++
.../CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll | 9 +++++
.../SPV_INTEL_function_pointers/fp_cmp.ll | 34 ++++++++++++++++
6 files changed, 96 insertions(+), 14 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll
create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll
create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index 53074ea3b2597..822fee8a9da35 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -84,17 +84,19 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
const LLT p6 = LLT::pointer(6, PSize); // SPV_INTEL_usm_storage_classes (Host)
const LLT p7 = LLT::pointer(7, PSize); // Input
const LLT p8 = LLT::pointer(8, PSize); // Output
+ const LLT p9 =
+ LLT::pointer(9, PSize); // CodeSectionINTEL, SPV_INTEL_function_pointers
const LLT p10 = LLT::pointer(10, PSize); // Private
const LLT p11 = LLT::pointer(11, PSize); // StorageBuffer
const LLT p12 = LLT::pointer(12, PSize); // Uniform
// TODO: remove copy-pasting here by using concatenation in some way.
auto allPtrsScalarsAndVectors = {
- p0, p1, p2, p3, p4, p5, p6, p7, p8,
- p10, p11, p12, s1, s8, s16, s32, s64, v2s1,
- v2s8, v2s16, v2s32, v2s64, v3s1, v3s8, v3s16, v3s32, v3s64,
- v4s1, v4s8, v4s16, v4s32, v4s64, v8s1, v8s8, v8s16, v8s32,
- v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
+ p0, p1, p2, p3, p4, p5, p6, p7, p8,
+ p9, p10, p11, p12, s1, s8, s16, s32, s64,
+ v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8, v3s16, v3s32,
+ v3s64, v4s1, v4s8, v4s16, v4s32, v4s64, v8s1, v8s8, v8s16,
+ v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
auto allVectors = {v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8,
v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32,
@@ -121,10 +123,10 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
s16, s32, s64, v2s16, v2s32, v2s64, v3s16, v3s32, v3s64,
v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64};
- auto allFloatAndIntScalarsAndPtrs = {s8, s16, s32, s64, p0, p1, p2, p3,
- p4, p5, p6, p7, p8, p10, p11, p12};
+ auto allFloatAndIntScalarsAndPtrs = {s8, s16, s32, s64, p0, p1, p2, p3, p4,
+ p5, p6, p7, p8, p9, p10, p11, p12};
- auto allPtrs = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p10, p11, p12};
+ auto allPtrs = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12};
bool IsExtendedInts =
ST.canUseExtension(
@@ -177,15 +179,22 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
getActionDefinitionsBuilder(G_UNMERGE_VALUES).alwaysLegal();
getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE})
+ .unsupportedIf(LegalityPredicates::any(typeIs(0, p9), typeIs(1, p9)))
.legalIf(all(typeInSet(0, allPtrs), typeInSet(1, allPtrs)));
- getActionDefinitionsBuilder(G_MEMSET).legalIf(
- all(typeInSet(0, allPtrs), typeInSet(1, allIntScalars)));
+ getActionDefinitionsBuilder(G_MEMSET)
+ .unsupportedIf(typeIs(0, p9))
+ .legalIf(all(typeInSet(0, allPtrs), typeInSet(1, allIntScalars)));
getActionDefinitionsBuilder(G_ADDRSPACE_CAST)
+ .unsupportedIf(
+ LegalityPredicates::any(all(typeIs(0, p9), typeIsNot(1, p9)),
+ all(typeIsNot(0, p9), typeIs(1, p9))))
.legalForCartesianProduct(allPtrs, allPtrs);
- getActionDefinitionsBuilder({G_LOAD, G_STORE}).legalIf(typeInSet(1, allPtrs));
+ getActionDefinitionsBuilder({G_LOAD, G_STORE})
+ .unsupportedIf(typeIs(1, p9))
+ .legalIf(typeInSet(1, allPtrs));
getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_ABS,
G_BITREVERSE, G_SADDSAT, G_UADDSAT, G_SSUBSAT,
@@ -247,9 +256,12 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
// ST.canDirectlyComparePointers() for pointer args is supported in
// legalizeCustom().
- getActionDefinitionsBuilder(G_ICMP).customIf(
- all(typeInSet(0, allBoolScalarsAndVectors),
- typeInSet(1, allPtrsScalarsAndVectors)));
+ getActionDefinitionsBuilder(G_ICMP)
+ .unsupportedIf(LegalityPredicates::any(
+ all(typeIs(0, p9), typeInSet(1, allPtrs), typeIsNot(1, p9)),
+ all(typeInSet(0, allPtrs), typeIsNot(0, p9), typeIs(1, p9))))
+ .customIf(all(typeInSet(0, allBoolScalarsAndVectors),
+ typeInSet(1, allPtrsScalarsAndVectors)));
getActionDefinitionsBuilder(G_FCMP).legalIf(
all(typeInSet(0, allBoolScalarsAndVectors),
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
new file mode 100644
index 0000000000000..62f9c7f06b937
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
@@ -0,0 +1,9 @@
+; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
+target triple = "spirv64-intel"
+
+define void @addrspacecast(ptr addrspace(9) %a) {
+; CHECK: unable to legalize instruction: %{{.*}}:pid(p4) = G_ADDRSPACE_CAST %{{.*}}:pid(p9)
+ %res1 = addrspacecast ptr addrspace(9) %a to ptr addrspace(4)
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll
new file mode 100644
index 0000000000000..888560d53a7ae
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll
@@ -0,0 +1,9 @@
+; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
+target triple = "spirv64-intel"
+
+define void @memset(ptr addrspace(9) %a) {
+; CHECK: unable to legalize instruction: %{{.*}}:iid(s32) = G_LOAD %{{.*}}:pid(p9)
+ %val = load i32, ptr addrspace(9) %a
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll
new file mode 100644
index 0000000000000..26566e50f1db2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll
@@ -0,0 +1,9 @@
+; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
+target triple = "spirv64-intel"
+
+define void @memcpy(ptr addrspace(9) %a) {
+; CHECK: unable to legalize instruction: G_MEMCPY %{{.*}}:pid(p9), %{{.*}}:pid(p0), %{{.*}}:iid(s64), 0
+ call void @llvm.memcpy.p9.p0.i64(ptr addrspace(9) %a, ptr null, i32 1, i1 0)
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll
new file mode 100644
index 0000000000000..3dd4ef0107495
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll
@@ -0,0 +1,9 @@
+; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
+target triple = "spirv64-intel"
+
+define void @memset(ptr addrspace(9) %a) {
+; CHECK: unable to legalize instruction: G_MEMSET %{{.*}}:pid(p9), %{{.*}}:iid(s8), %{{.*}}:iid(s64)
+ call void @llvm.memset.p9.i32(ptr addrspace(9) %a, i8 0, i32 1, i1 0)
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll
new file mode 100644
index 0000000000000..6b345f708442c
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll
@@ -0,0 +1,34 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-intel --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-intel %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability FunctionPointersINTEL
+; CHECK: OpExtension "SPV_INTEL_function_pointers"
+
+; CHECK: OpName %[[F1:.*]] "f1"
+; CHECK: OpName %[[F2:.*]] "f2"
+
+; CHECK: %[[TyBool:.*]] = OpTypeBool
+
+; CHECK %[[F1Ptr:.*]] = OpConstantFunctionPointerINTEL %{{.*}} %[[F2]]
+; CHECK %[[F2Ptr:.*]] = OpConstantFunctionPointerINTEL %{{.*}} %[[F2]]
+
+; CHECK OpPtrEqual %[[TyBool]] %[[F1Ptr]] %[[F2Ptr]]
+
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
+target triple = "spirv64-intel"
+
+define spir_func void @f1() addrspace(9) {
+entry:
+ ret void
+}
+
+define spir_func void @f2() addrspace(9) {
+entry:
+ ret void
+}
+
+define spir_kernel void @foo() addrspace(9) {
+entry:
+ %a = icmp eq ptr addrspace(9) @f1, @f2
+ ret void
+}
>From 43bd25e0f65020b071045dbd2b4b5f0f6052d210 Mon Sep 17 00:00:00 2001
From: Nick Sarnie <nick.sarnie at intel.com>
Date: Mon, 17 Nov 2025 07:59:23 -0800
Subject: [PATCH 2/2] address feedback
Signed-off-by: Nick Sarnie <nick.sarnie at intel.com>
---
.../SPIRV/GlobalISel/fn-ptr-addrspacecast.ll | 5 ++--
.../CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll | 7 +++---
.../CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll | 5 ++--
.../CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll | 5 ++--
.../CodeGen/SPIRV/GlobalISel/fn-ptr-store.ll | 8 ++++++
.../SPV_INTEL_function_pointers/fp_cmp.ll | 25 +++++++------------
6 files changed, 26 insertions(+), 29 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-store.ll
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
index 62f9c7f06b937..58638578bb3f0 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
@@ -1,6 +1,5 @@
-; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
-target triple = "spirv64-intel"
+; RUN: not llc --global-isel %s -filetype=null 2>&1 | FileCheck %s
+target triple = "spirv64"
define void @addrspacecast(ptr addrspace(9) %a) {
; CHECK: unable to legalize instruction: %{{.*}}:pid(p4) = G_ADDRSPACE_CAST %{{.*}}:pid(p9)
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll
index 888560d53a7ae..229f2234220ab 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-load.ll
@@ -1,8 +1,7 @@
-; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
-target triple = "spirv64-intel"
+; RUN: not llc --global-isel %s -filetype=null 2>&1 | FileCheck %s
+target triple = "spirv64"
-define void @memset(ptr addrspace(9) %a) {
+define void @do_load(ptr addrspace(9) %a) {
; CHECK: unable to legalize instruction: %{{.*}}:iid(s32) = G_LOAD %{{.*}}:pid(p9)
%val = load i32, ptr addrspace(9) %a
ret void
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll
index 26566e50f1db2..f72b69b4fec81 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memcpy.ll
@@ -1,6 +1,5 @@
-; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
-target triple = "spirv64-intel"
+; RUN: not llc --global-isel %s -filetype=null 2>&1 | FileCheck %s
+target triple = "spirv64"
define void @memcpy(ptr addrspace(9) %a) {
; CHECK: unable to legalize instruction: G_MEMCPY %{{.*}}:pid(p9), %{{.*}}:pid(p0), %{{.*}}:iid(s64), 0
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll
index 3dd4ef0107495..b8102582bba74 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-memset.ll
@@ -1,6 +1,5 @@
-; RUN: not llc --global-isel %s -o /dev/null 2>&1 | FileCheck %s
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
-target triple = "spirv64-intel"
+; RUN: not llc --global-isel %s -filetype=null 2>&1 | FileCheck %s
+target triple = "spirv64"
define void @memset(ptr addrspace(9) %a) {
; CHECK: unable to legalize instruction: G_MEMSET %{{.*}}:pid(p9), %{{.*}}:iid(s8), %{{.*}}:iid(s64)
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-store.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-store.ll
new file mode 100644
index 0000000000000..c00f15e82f2fe
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-store.ll
@@ -0,0 +1,8 @@
+; RUN: not llc --global-isel %s -filetype=null 2>&1 | FileCheck %s
+target triple = "spirv64"
+
+define void @do_store(ptr addrspace(9) %a) {
+; CHECK: unable to legalize instruction: G_STORE %{{.*}}:iid(s32), %{{.*}}:pid(p9)
+ store i32 5, ptr addrspace(9) %a
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll
index 6b345f708442c..da9771914b819 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_cmp.ll
@@ -1,34 +1,27 @@
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-intel --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-intel %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -verify-machineinstrs -O0 --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 %s -o - -filetype=obj | spirv-val %}
; CHECK-DAG: OpCapability FunctionPointersINTEL
; CHECK: OpExtension "SPV_INTEL_function_pointers"
; CHECK: OpName %[[F1:.*]] "f1"
-; CHECK: OpName %[[F2:.*]] "f2"
+; CHECK: OpName %[[ARG:.*]] "arg"
; CHECK: %[[TyBool:.*]] = OpTypeBool
-; CHECK %[[F1Ptr:.*]] = OpConstantFunctionPointerINTEL %{{.*}} %[[F2]]
-; CHECK %[[F2Ptr:.*]] = OpConstantFunctionPointerINTEL %{{.*}} %[[F2]]
+; CHECK: %[[F1Ptr:.*]] = OpConstantFunctionPointerINTEL %{{.*}} %[[F1]]
-; CHECK OpPtrEqual %[[TyBool]] %[[F1Ptr]] %[[F2Ptr]]
+; CHECK: OpPtrEqual %[[TyBool]] %[[F1Ptr]] %[[ARG]]
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0"
-target triple = "spirv64-intel"
+target triple = "spirv64"
define spir_func void @f1() addrspace(9) {
entry:
ret void
}
-define spir_func void @f2() addrspace(9) {
+define spir_func i1 @foo(ptr addrspace(9) %arg) addrspace(9) {
entry:
- ret void
-}
-
-define spir_kernel void @foo() addrspace(9) {
-entry:
- %a = icmp eq ptr addrspace(9) @f1, @f2
- ret void
+ %a = icmp eq ptr addrspace(9) @f1, %arg
+ ret i1 %a
}
More information about the llvm-commits
mailing list