From d7eff11900eb5eae01a16b8facf33e770553a76e Mon Sep 17 00:00:00 2001 From: Nick Sarnie Date: Thu, 13 Nov 2025 13:46:11 -0800 Subject: [PATCH] [SPIRV] Add support for CodeSectionINTEL addrspace in legalizer Signed-off-by: Nick Sarnie --- 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 +}