[llvm] [SPIRV] Support -fembed-bitcode=marker for non-shader modules (PR #162082)

via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 6 05:55:25 PDT 2025


Juan Manuel Martinez =?utf-8?q?Caamaño?= <juamarti at amd.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/162082 at github.com>


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-spir-v

Author: Juan Manuel Martinez Caamaño (jmmartinez)

<details>
<summary>Changes</summary>

-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.

I'm not sure this is the way we want to support this, neither for shaders (using runtime arrays) nor for kernels (using the 1-sized zeroinitialized array).
A part of me would like to just delete the variable since we do not really need the delimiter.

Depends on https://github.com/llvm/llvm-project/pull/162081

---
Full diff: https://github.com/llvm/llvm-project/pull/162082.diff


4 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+36) 
- (added) llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll (+21) 
- (added) llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll (+21) 
- (added) llvm/test/CodeGen/SPIRV/fembed-bitcode.ll (+25) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 9f2e07508a36a..447fbb9d1ac0a 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)
@@ -3007,9 +3009,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<ArrayType>(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-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
+
+ at llvm.embedded.module = private constant [0 x i8] zeroinitializer, section ".llvmbc", align 1
+ at llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1
+ at 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..e3d21fcdc8084
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll
@@ -0,0 +1,21 @@
+; RUN: llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+
+ at llvm.embedded.module = private constant [0 x i8] zeroinitializer, section ".llvmbc", align 1
+ at llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1
+ at 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
+}
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
+
+ at llvm.embedded.module = private constant [4 x i8] c"BC\C0\DE", section ".llvmbc", align 1
+ at llvm.cmdline = private constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1
+ at 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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/162082


More information about the llvm-commits mailing list