Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ class SPIRVEmitIntrinsics

Instruction *buildLogicalAccessChainFromGEP(GetElementPtrInst &GEP);

bool promoteEmbeddedBitcodeMarkear(Module &M) const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Markear" (possible typo)


public:
static char ID;
SPIRVEmitIntrinsics(SPIRVTargetMachine *TM = nullptr)
Expand Down Expand Up @@ -3005,9 +3007,43 @@ void SPIRVEmitIntrinsics::parseFunDeclarations(Module &M) {
}
}

bool SPIRVEmitIntrinsics::promoteEmbeddedBitcodeMarkear(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 *ArrTy = cast<ArrayType>(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 *ArrTyOneElt = ArrayType::get(ArrTy->getElementType(), 1);
Constant *ZeroInit = Constant::getNullValue(ArrTyOneElt);
GlobalVariable *NewEmbeddedBitcode = new GlobalVariable(
ArrTyOneElt, 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 |= promoteEmbeddedBitcodeMarkear(M);
parseFunDeclarations(M);
insertConstantsForFPFastMathDefault(M);

Expand Down
22 changes: 22 additions & 0 deletions llvm/test/CodeGen/SPIRV/fembed-bitcode-marker-shader.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; RUN: llc -verify-machineinstrs -mtriple=spirv-vulkan-unknown %s -o - | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, add also a check with spirv-val. Applies to all tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the latest update. I'll also update the parent PR #162081

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test started failing once I added the spirv-val line. I'm checking this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that I have now more context about all of this.

The @llvm.embedded.module stuff only make sense when the spirv flavour is AMD's, and not for the others. In this case, the variables are in the constant addrspace(1) and are addrspace-casted to the generic addrspace(4) when added to llvm.compiler.used.

This is allowed only in amd's flavour but is outside of spirv standard.

I think I'm going to change my strategy:

  • I'll add an AMD specific pass that is only added to the pipeline if the vendor is AMD to put this kind of stuff over there.
  • Maybe put this kind of test not in test/CodeGen/SPIRV but in a subfolder test/CodeGen/SPIRV/amd or something like that.

What do you think ?

; RUN: %if spirv-tools %{ llc -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
; RUN: %if spirv-tools %{ llc -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; RUN: %if spirv-tools %{ llc -mtriple=spirv-vulkan-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
@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" }
22 changes: 22 additions & 0 deletions llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; 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
@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
}
26 changes: 26 additions & 0 deletions llvm/test/CodeGen/SPIRV/fembed-bitcode.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
; 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
@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
}
Loading