From 2cb721d203110602dbe178a784af79d75f337287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= Date: Mon, 6 Oct 2025 14:20:17 +0200 Subject: [PATCH 1/4] Pre-Commit tests: [SPIRV] Support -fembed-bitcode=marker for non-shader modules --- .../SPIRV/fembed-bitcode-marker-shader.ll | 21 ++++++++++++++++ .../CodeGen/SPIRV/fembed-bitcode-marker.ll | 11 ++++++++ llvm/test/CodeGen/SPIRV/fembed-bitcode.ll | 25 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll create mode 100644 llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll create mode 100644 llvm/test/CodeGen/SPIRV/fembed-bitcode.ll diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll new file mode 100644 index 0000000000000..20ac543486766 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll @@ -0,0 +1,21 @@ +; RUN: llc -verify-machineinstrs -mtriple=spirv-vulkan-unknown %s -o - | FileCheck %s + +@llvm.embedded.module = private constant [0 x i8] zeroinitializer, section ".llvmbc", align 1 +@llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 +@llvm.compiler.used = appending global [2 x ptr] [ptr @llvm.embedded.module, ptr @llvm.cmdline], section "llvm.metadata" + +; CHECK-DAG: OpName [[FOO:%[0-9]+]] "foo" +; CHECK-DAG: OpName [[MODULE:%[0-9]+]] "llvm.embedded.module" +; CHECK-DAG: [[INT8:%[0-9]+]] = OpTypeInt 8 0 +; CHECK-DAG: [[RUNTIME_ARRAY_INT8x1:%[0-9]+]] = OpTypeRuntimeArray [[INT8]] +; CHECK-DAG: [[POINTER:%[0-9]+]] = OpTypePointer Function [[RUNTIME_ARRAY_INT8x1]] +; CHECK-DAG: [[EMBEDDED_MODULE_INIT:%[0-9]+]] = OpConstantNull [[RUNTIME_ARRAY_INT8x1]] +; CHECK: [[FOO]] = OpFunction {{.*}} None {{.*}} +; CHECK-DAG: {{%[0-9]+}} = OpVariable [[POINTER]] Function [[EMBEDDED_MODULE_INIT]] + +define void @foo() #1 { +entry: + ret void +} + +attributes #1 = { "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" } diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll new file mode 100644 index 0000000000000..6bc9beec1e9e3 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll @@ -0,0 +1,11 @@ +; XFAIL: * +; RUN: llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s + +@llvm.embedded.module = private constant [0 x i8] zeroinitializer, section ".llvmbc", align 1 +@llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 +@llvm.compiler.used = appending global [2 x ptr] [ptr @llvm.embedded.module, ptr @llvm.cmdline], section "llvm.metadata" + +define spir_kernel void @foo() { +entry: + ret void +} diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll new file mode 100644 index 0000000000000..0044e09aceaab --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll @@ -0,0 +1,25 @@ +; RUN: llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s + +@llvm.embedded.module = private constant [4 x i8] c"BC\C0\DE", section ".llvmbc", align 1 +@llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 +@llvm.compiler.used = appending global [2 x ptr] [ptr @llvm.embedded.module, ptr @llvm.cmdline], section "llvm.metadata" + +; CHECK-DAG: OpName [[FOO:%[0-9]+]] "foo" +; CHECK-DAG: OpName [[MODULE:%[0-9]+]] "llvm.embedded.module" +; CHECK-DAG: [[INT8:%[0-9]+]] = OpTypeInt 8 0 +; CHECK-DAG: [[INT32:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: [[CONST_4_32:%[0-9]+]] = OpConstant [[INT32]] 4 +; CHECK-DAG: [[ARRAY_INT8x4:%[0-9]+]] = OpTypeArray [[INT8]] [[CONST_4_32]] +; CHECK-DAG: [[POINTER:%[0-9]+]] = OpTypePointer Function [[ARRAY_INT8x4]] +; CHECK-DAG: [[CONST_B_8:%[0-9]+]] = OpConstant [[INT8]] 66 +; CHECK-DAG: [[CONST_C_8:%[0-9]+]] = OpConstant [[INT8]] 67 +; CHECK-DAG: [[CONST_0xC0_8:%[0-9]+]] = OpConstant [[INT8]] 192 +; CHECK-DAG: [[CONST_0xDE_8:%[0-9]+]] = OpConstant [[INT8]] 222 +; CHECK-DAG: [[EMBEDDED_MODULE_INIT:%[0-9]+]] = OpConstantComposite [[ARRAY_INT8x4]] [[CONST_B_8]] [[CONST_C_8]] [[CONST_0xC0_8]] [[CONST_0xDE_8]] +; CHECK: [[FOO]] = OpFunction {{.*}} None {{.*}} +; CHECK-DAG: {{%[0-9]+}} = OpVariable [[POINTER]] Function [[EMBEDDED_MODULE_INIT]] + +define spir_kernel void @foo() { +entry: + ret void +} From 806bb398c21045ed3f27bb328f89392e05efb0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= Date: Tue, 7 Oct 2025 10:14:27 +0200 Subject: [PATCH 2/4] [Review] Add spirv-val call to tests --- llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll | 1 + llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll | 1 + llvm/test/CodeGen/SPIRV/fembed-bitcode.ll | 1 + 3 files changed, 3 insertions(+) diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll index 20ac543486766..811a4be7726af 100644 --- a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mtriple=spirv-vulkan-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} @llvm.embedded.module = private constant [0 x i8] zeroinitializer, section ".llvmbc", align 1 @llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll index 6bc9beec1e9e3..b727e5dd84545 100644 --- a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll @@ -1,5 +1,6 @@ ; XFAIL: * ; RUN: llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} @llvm.embedded.module = private constant [0 x i8] zeroinitializer, section ".llvmbc", align 1 @llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll index 0044e09aceaab..fa6ef86288d7c 100644 --- a/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} @llvm.embedded.module = private constant [4 x i8] c"BC\C0\DE", section ".llvmbc", align 1 @llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 From 7e22ddd11fbd9cfb8fd0f0da01b6e33ad1496cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= Date: Mon, 6 Oct 2025 13:48:36 +0200 Subject: [PATCH 3/4] [SPIRV] Support -fembed-bitcode=marker for non-shader modules -fembed-bitcode=marker gets lowered as a [0 x i8] zeroinitialized global variable. This is interpreted as a runtime-array and is not supported in non-shaders. To work around this, we replace the [0 x i8] by a zeroinitialized single-element array. --- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 36 +++++++++++++++++++ .../CodeGen/SPIRV/fembed-bitcode-marker.ll | 12 ++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index e16c8f0fc302e..08dce614504f1 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -236,6 +236,8 @@ class SPIRVEmitIntrinsics Instruction *buildLogicalAccessChainFromGEP(GetElementPtrInst &GEP); + bool promoteEmbddedBitcodeMarker(Module &M) const; + public: static char ID; SPIRVEmitIntrinsics(SPIRVTargetMachine *TM = nullptr) @@ -3005,9 +3007,43 @@ void SPIRVEmitIntrinsics::parseFunDeclarations(Module &M) { } } +bool SPIRVEmitIntrinsics::promoteEmbddedBitcodeMarker(Module &M) const { + const SPIRVSubtarget *STI = TM->getSubtargetImpl(); + if (STI->isShader()) + return false; + + GlobalVariable *EmbeddedBitcode = M.getNamedGlobal("llvm.embedded.module"); + if (!EmbeddedBitcode) + return false; + + ArrayType *AT = cast(EmbeddedBitcode->getValueType()); + if (AT->getNumElements() != 0) + return false; + + // When compiling with -fembed-bitcode=marker, LLVM generates a [0 x i8] + // zeroinitialized global variable containing the bitcode. This results in an + // assert outside of shaders. As a workaround, we replace this global with a + // zeroinitialized [1 x i8]. + ArrayType *AT1 = ArrayType::get(AT->getElementType(), 1); + Constant *ZeroInit = Constant::getNullValue(AT1); + GlobalVariable *NewEmbeddedBitcode = new GlobalVariable( + AT1, EmbeddedBitcode->isConstant(), EmbeddedBitcode->getLinkage(), + ZeroInit, "", EmbeddedBitcode->getThreadLocalMode(), + EmbeddedBitcode->getAddressSpace(), + EmbeddedBitcode->isExternallyInitialized()); + NewEmbeddedBitcode->setSection(NewEmbeddedBitcode->getSection()); + NewEmbeddedBitcode->takeName(EmbeddedBitcode); + + M.insertGlobalVariable(NewEmbeddedBitcode); + EmbeddedBitcode->replaceAllUsesWith(NewEmbeddedBitcode); + EmbeddedBitcode->eraseFromParent(); + return true; +} + bool SPIRVEmitIntrinsics::runOnModule(Module &M) { bool Changed = false; + Changed |= promoteEmbddedBitcodeMarker(M); parseFunDeclarations(M); insertConstantsForFPFastMathDefault(M); diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll index b727e5dd84545..1b0c13f36fc56 100644 --- a/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll +++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll @@ -1,4 +1,3 @@ -; XFAIL: * ; RUN: llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s ; RUN: %if spirv-tools %{ llc -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} @@ -6,6 +5,17 @@ @llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1 @llvm.compiler.used = appending global [2 x ptr] [ptr @llvm.embedded.module, ptr @llvm.cmdline], section "llvm.metadata" +; CHECK-DAG: OpName [[FOO:%[0-9]+]] "foo" +; CHECK-DAG: OpName [[MODULE:%[0-9]+]] "llvm.embedded.module" +; CHECK-DAG: [[INT8:%[0-9]+]] = OpTypeInt 8 0 +; CHECK-DAG: [[INT32:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: [[CONST_1_32:%[0-9]+]] = OpConstant [[INT32]] 1 +; CHECK-DAG: [[ARRAY_INT8x1:%[0-9]+]] = OpTypeArray [[INT8]] [[CONST_1_32]] +; CHECK-DAG: [[POINTER:%[0-9]+]] = OpTypePointer Function [[ARRAY_INT8x1]] +; CHECK-DAG: [[EMBEDDED_MODULE_INIT:%[0-9]+]] = OpConstantNull [[ARRAY_INT8x1]] +; CHECK: [[FOO]] = OpFunction {{.*}} None {{.*}} +; CHECK-DAG: {{%[0-9]+}} = OpVariable [[POINTER]] Function [[EMBEDDED_MODULE_INIT]] + define spir_kernel void @foo() { entry: ret void From 5c2271caae04cd5b55ee797fe590156ad6b6f041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= Date: Tue, 7 Oct 2025 10:04:46 +0200 Subject: [PATCH 4/4] [Review] Fix names --- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index 08dce614504f1..647502155f4e2 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -236,7 +236,7 @@ class SPIRVEmitIntrinsics Instruction *buildLogicalAccessChainFromGEP(GetElementPtrInst &GEP); - bool promoteEmbddedBitcodeMarker(Module &M) const; + bool promoteEmbeddedBitcodeMarkear(Module &M) const; public: static char ID; @@ -3007,7 +3007,7 @@ void SPIRVEmitIntrinsics::parseFunDeclarations(Module &M) { } } -bool SPIRVEmitIntrinsics::promoteEmbddedBitcodeMarker(Module &M) const { +bool SPIRVEmitIntrinsics::promoteEmbeddedBitcodeMarkear(Module &M) const { const SPIRVSubtarget *STI = TM->getSubtargetImpl(); if (STI->isShader()) return false; @@ -3016,18 +3016,18 @@ bool SPIRVEmitIntrinsics::promoteEmbddedBitcodeMarker(Module &M) const { if (!EmbeddedBitcode) return false; - ArrayType *AT = cast(EmbeddedBitcode->getValueType()); - if (AT->getNumElements() != 0) + ArrayType *ArrTy = cast(EmbeddedBitcode->getValueType()); + if (ArrTy->getNumElements() != 0) return false; // When compiling with -fembed-bitcode=marker, LLVM generates a [0 x i8] // zeroinitialized global variable containing the bitcode. This results in an // assert outside of shaders. As a workaround, we replace this global with a // zeroinitialized [1 x i8]. - ArrayType *AT1 = ArrayType::get(AT->getElementType(), 1); - Constant *ZeroInit = Constant::getNullValue(AT1); + ArrayType *ArrTyOneElt = ArrayType::get(ArrTy->getElementType(), 1); + Constant *ZeroInit = Constant::getNullValue(ArrTyOneElt); GlobalVariable *NewEmbeddedBitcode = new GlobalVariable( - AT1, EmbeddedBitcode->isConstant(), EmbeddedBitcode->getLinkage(), + ArrTyOneElt, EmbeddedBitcode->isConstant(), EmbeddedBitcode->getLinkage(), ZeroInit, "", EmbeddedBitcode->getThreadLocalMode(), EmbeddedBitcode->getAddressSpace(), EmbeddedBitcode->isExternallyInitialized()); @@ -3043,7 +3043,7 @@ bool SPIRVEmitIntrinsics::promoteEmbddedBitcodeMarker(Module &M) const { bool SPIRVEmitIntrinsics::runOnModule(Module &M) { bool Changed = false; - Changed |= promoteEmbddedBitcodeMarker(M); + Changed |= promoteEmbeddedBitcodeMarkear(M); parseFunDeclarations(M); insertConstantsForFPFastMathDefault(M);