Skip to content
Merged
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
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ add_llvm_target(SPIRVCodeGen
SPIRVPreLegalizerCombiner.cpp
SPIRVPostLegalizer.cpp
SPIRVPrepareFunctions.cpp
SPIRVPrepareGlobals.cpp
SPIRVRegisterBankInfo.cpp
SPIRVRegisterInfo.cpp
SPIRVRegularizer.cpp
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRV.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FunctionPass *createSPIRVPreLegalizerCombiner();
FunctionPass *createSPIRVPreLegalizerPass();
FunctionPass *createSPIRVPostLegalizerPass();
ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);
ModulePass *createSPIRVPrepareGlobalsPass();
MachineFunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM);
InstructionSelector *
createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
Expand All @@ -51,6 +52,7 @@ void initializeSPIRVLegalizePointerCastPass(PassRegistry &);
void initializeSPIRVRegularizerPass(PassRegistry &);
void initializeSPIRVMergeRegionExitTargetsPass(PassRegistry &);
void initializeSPIRVPrepareFunctionsPass(PassRegistry &);
void initializeSPIRVPrepareGlobalsPass(PassRegistry &);
void initializeSPIRVStripConvergentIntrinsicsPass(PassRegistry &);
void initializeSPIRVLegalizeImplicitBindingPass(PassRegistry &);
} // namespace llvm
Expand Down
68 changes: 68 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVPrepareGlobals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//===-- SPIRVPrepareGlobals.cpp - Prepare IR SPIRV globals ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// The pass transforms IR globals that cannot be trivially mapped to SPIRV
// into something that is trival to lower.
//
//===----------------------------------------------------------------------===//

#include "SPIRV.h"

#include "llvm/IR/Module.h"

using namespace llvm;

namespace {

struct SPIRVPrepareGlobals : public ModulePass {
static char ID;
SPIRVPrepareGlobals() : ModulePass(ID) {}

StringRef getPassName() const override {
return "SPIRV prepare global variables";
}

bool runOnModule(Module &M) override;
};

bool tryExtendLLVMBitcodeMarker(GlobalVariable &Bitcode) {
assert(Bitcode.getName() == "llvm.embedded.module");

ArrayType *AT = cast<ArrayType>(Bitcode.getValueType());
if (AT->getNumElements() != 0)
return false;

ArrayType *AT1 = ArrayType::get(AT->getElementType(), 1);
Constant *OneEltInit = Constant::getNullValue(AT1);
Bitcode.replaceInitializer(OneEltInit);
return true;
}

bool SPIRVPrepareGlobals::runOnModule(Module &M) {
const bool IsAMD = M.getTargetTriple().getVendor() == Triple::AMD;
if (!IsAMD)
return false;

bool Changed = false;
if (GlobalVariable *Bitcode = M.getNamedGlobal("llvm.embedded.module"))
Changed |= tryExtendLLVMBitcodeMarker(*Bitcode);

return Changed;
}
char SPIRVPrepareGlobals::ID = 0;

} // namespace

INITIALIZE_PASS(SPIRVPrepareGlobals, "prepare-globals",
"SPIRV prepare global variables", false, false)

namespace llvm {
ModulePass *createSPIRVPrepareGlobalsPass() {
return new SPIRVPrepareGlobals();
}
} // namespace llvm
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTarget() {
initializeSPIRVEmitIntrinsicsPass(PR);
initializeSPIRVEmitNonSemanticDIPass(PR);
initializeSPIRVPrepareFunctionsPass(PR);
initializeSPIRVPrepareGlobalsPass(PR);
initializeSPIRVStripConvergentIntrinsicsPass(PR);
}

Expand Down Expand Up @@ -172,6 +173,7 @@ void SPIRVPassConfig::addIRPasses() {

addPass(createSPIRVRegularizerPass());
addPass(createSPIRVPrepareFunctionsPass(TM));
addPass(createSPIRVPrepareGlobalsPass());
}

void SPIRVPassConfig::addISelPrepare() {
Expand Down
24 changes: 24 additions & 0 deletions llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; Expanding the bitcode marker works only for AMD at the moment.
; RUN: not llc -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o -
; RUN: llc -verify-machineinstrs -mtriple=spirv64-amd-amdhsa %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -mtriple=spirv64-amd-amdhsa %s -o - -filetype=obj | spirv-val %}
;
; Verify that we lower the embedded bitcode

@llvm.embedded.module = private addrspace(1) constant [0 x i8] zeroinitializer, section ".llvmbc", align 1
@llvm.compiler.used = appending addrspace(1) global [1 x ptr addrspace(4)] [ptr addrspace(4) addrspacecast (ptr addrspace(1) @llvm.embedded.module to ptr addrspace(4))], section "llvm.metadata"

; CHECK: OpName %[[#LLVM_EMBEDDED_MODULE:]] "llvm.embedded.module"
; CHECK: OpDecorate %[[#LLVM_EMBEDDED_MODULE]] Constant
; CHECK: %[[#UCHAR:]] = OpTypeInt 8 0
; CHECK: %[[#UINT:]] = OpTypeInt 32 0
; CHECK: %[[#ONE:]] = OpConstant %[[#UINT]] 1
; CHECK: %[[#UCHAR_ARR_1:]] = OpTypeArray %[[#UCHAR]] %[[#ONE]]
; CHECK: %[[#UCHAR_ARR_1_PTR:]] = OpTypePointer CrossWorkgroup %[[#UCHAR_ARR_1]]
; CHECK: %[[#CONST_UCHAR_ARR_1:]] = OpConstantNull %[[#UCHAR_ARR_1]]
; CHECK: %[[#LLVM_EMBEDDED_MODULE]] = OpVariable %[[#UCHAR_ARR_1_PTR]] CrossWorkgroup %[[#CONST_UCHAR_ARR_1]]

define spir_kernel void @foo() {
entry:
ret void
}
32 changes: 32 additions & 0 deletions llvm/test/CodeGen/SPIRV/fembed-bitcode.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
; 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 %}
; RUN: llc -verify-machineinstrs -mtriple=spirv64-amd-amdhsa %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -mtriple=spirv64-amd-amdhsa %s -o - -filetype=obj | spirv-val %}
;
; Verify that we can lower the embedded module and cmdline.

@llvm.embedded.module = private addrspace(1) constant [4 x i8] c"BC\C0\DE", section ".llvmbc", align 1
@llvm.cmdline = private addrspace(1) constant [5 x i8] c"-cc1\00", section ".llvmcmd", align 1
@llvm.compiler.used = appending addrspace(1) global [2 x ptr addrspace(4)] [ptr addrspace(4) addrspacecast (ptr addrspace(1) @llvm.embedded.module to ptr addrspace(4)), ptr addrspace(4) addrspacecast (ptr addrspace(1) @llvm.cmdline to ptr addrspace(4))], section "llvm.metadata"

; CHECK: OpName %[[#LLVM_EMBEDDED_MODULE:]] "llvm.embedded.module"
; CHECK: OpName %[[#LLVM_CMDLINE:]] "llvm.cmdline"
; CHECK: OpDecorate %[[#LLVM_EMBEDDED_MODULE]] Constant
; CHECK: OpDecorate %[[#LLVM_CMDLINE]] Constant
; CHECK: %[[#UCHAR:]] = OpTypeInt 8 0
; CHECK: %[[#UINT:]] = OpTypeInt 32 0
; CHECK: %[[#FIVE:]] = OpConstant %[[#UINT]] 5
; CHECK: %[[#UCHAR_ARR_5:]] = OpTypeArray %[[#UCHAR]] %[[#FIVE]]
; CHECK: %[[#FOUR:]] = OpConstant %[[#UINT]] 4
; CHECK: %[[#UCHAR_ARR_4:]] = OpTypeArray %[[#UCHAR]] %[[#FOUR]]
; CHECK: %[[#UCHAR_ARR_5_PTR:]] = OpTypePointer CrossWorkgroup %[[#UCHAR_ARR_5]]
; CHECK: %[[#UCHAR_ARR_4_PTR:]] = OpTypePointer CrossWorkgroup %[[#UCHAR_ARR_4]]
; CHECK: %[[#CONST_UCHAR_ARR_4:]] = OpConstantComposite %[[#UCHAR_ARR_4]]
; CHECK: %[[#LLVM_EMBEDDED_MODULE]] = OpVariable %[[#UCHAR_ARR_4_PTR]] CrossWorkgroup %[[#CONST_UCHAR_ARR_4]]
; CHECK: %[[#CONST_UCHAR_ARR_5:]] = OpConstantComposite %[[#UCHAR_ARR_5]]
; CHECK: %[[#LLVM_CMDLINE]] = OpVariable %[[#UCHAR_ARR_5_PTR]] CrossWorkgroup %[[#CONST_UCHAR_ARR_5]]

define spir_kernel void @foo() {
entry:
ret void
}
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/SPIRV/llc-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
; SPIRV-O0-NEXT: Expand reduction intrinsics
; SPIRV-O0-NEXT: SPIR-V Regularizer
; SPIRV-O0-NEXT: SPIRV prepare functions
; SPIRV-O0-NEXT: SPIRV prepare global variables
; SPIRV-O0-NEXT: FunctionPass Manager
; SPIRV-O0-NEXT: Lower invoke and unwind, for unwindless code generators
; SPIRV-O0-NEXT: Remove unreachable blocks from the CFG
Expand Down Expand Up @@ -130,6 +131,7 @@
; SPIRV-Opt-NEXT: Expand reduction intrinsics
; SPIRV-Opt-NEXT: SPIR-V Regularizer
; SPIRV-Opt-NEXT: SPIRV prepare functions
; SPIRV-Opt-NEXT: SPIRV prepare global variables
; SPIRV-Opt-NEXT: FunctionPass Manager
; SPIRV-Opt-NEXT: Dominator Tree Construction
; SPIRV-Opt-NEXT: Natural Loop Information
Expand Down
Loading