Juan Manuel Martinez =?utf-8?q?Caamaño?=,
Juan Manuel Martinez =?utf-8?q?Caamaño?Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Juan Manuel Martinez Caamaño (jmmartinez)

<details>
<summary>Changes</summary>

When compiling with `-fembed-bitcode-marker`, Clang inserts a placeholder
for the bitcode. This placeholder is a `[0 x i8]` array, which we cannot
represent in SPIRV.

For AMD flavored SPIRV, we extend the `llvm.embedded.module` global to a
`zeroinitializer [1 x i8]` array.

To achieve this, this patch adds a new pass, `SPIRVPrepareGlobals`, that we can 
use to write global variable's _non-trivial-to-lower-IR_ -&gt; 
_trivial-to-lower-IR_ mappings.

This is a second attempt at https://github.com/llvm/llvm-project/pull/162082, 
but cleaner.

In the translator something similar is done for every 0-element array since 
https://github.com/KhronosGroup/SPIRV-LLVM-Translator/pull/2743 . But I don't 
think we want to do this mapping for all cases.

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


7 Files Affected:

- (modified) llvm/lib/Target/SPIRV/CMakeLists.txt (+1) 
- (modified) llvm/lib/Target/SPIRV/SPIRV.h (+2) 
- (added) llvm/lib/Target/SPIRV/SPIRVPrepareGlobals.cpp (+68) 
- (modified) llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp (+2) 
- (added) llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll (+24) 
- (added) llvm/test/CodeGen/SPIRV/fembed-bitcode.ll (+32) 
- (modified) llvm/test/CodeGen/SPIRV/llc-pipeline.ll (+2) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt 
b/llvm/lib/Target/SPIRV/CMakeLists.txt
index eab7b213756b3..79b76165cd57a 100644
--- a/llvm/lib/Target/SPIRV/CMakeLists.txt
+++ b/llvm/lib/Target/SPIRV/CMakeLists.txt
@@ -41,6 +41,7 @@ add_llvm_target(SPIRVCodeGen
   SPIRVPreLegalizerCombiner.cpp
   SPIRVPostLegalizer.cpp
   SPIRVPrepareFunctions.cpp
+  SPIRVPrepareGlobals.cpp
   SPIRVRegisterBankInfo.cpp
   SPIRVRegisterInfo.cpp
   SPIRVRegularizer.cpp
diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h
index efd49b930aa34..fa85ee781c249 100644
--- a/llvm/lib/Target/SPIRV/SPIRV.h
+++ b/llvm/lib/Target/SPIRV/SPIRV.h
@@ -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,
@@ -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
diff --git a/llvm/lib/Target/SPIRV/SPIRVPrepareGlobals.cpp 
b/llvm/lib/Target/SPIRV/SPIRVPrepareGlobals.cpp
new file mode 100644
index 0000000000000..c44c53129f1e0
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVPrepareGlobals.cpp
@@ -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
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp 
b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 2951a4bc695e2..10bbca225b20a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -59,6 +59,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void 
LLVMInitializeSPIRVTarget() {
   initializeSPIRVEmitIntrinsicsPass(PR);
   initializeSPIRVEmitNonSemanticDIPass(PR);
   initializeSPIRVPrepareFunctionsPass(PR);
+  initializeSPIRVPrepareGlobalsPass(PR);
   initializeSPIRVStripConvergentIntrinsicsPass(PR);
 }
 
@@ -172,6 +173,7 @@ void SPIRVPassConfig::addIRPasses() {
 
   addPass(createSPIRVRegularizerPass());
   addPass(createSPIRVPrepareFunctionsPass(TM));
+  addPass(createSPIRVPrepareGlobalsPass());
 }
 
 void SPIRVPassConfig::addISelPrepare() {
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..72caa68b52930
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode-marker.ll
@@ -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
+
[email protected] = private addrspace(1) constant [0 x i8] 
zeroinitializer, section ".llvmbc", align 1
[email protected] = 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
+}
diff --git a/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll 
b/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll
new file mode 100644
index 0000000000000..1e7106e0674c5
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/fembed-bitcode.ll
@@ -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 embeded module and cmdline
+
[email protected] = private addrspace(1) constant [4 x i8] c"BC\C0\DE", 
section ".llvmbc", align 1
[email protected] = private addrspace(1) constant [5 x i8] c"-cc1\00", section 
".llvmcmd", align 1
[email protected] = 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
+}
diff --git a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll 
b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
index 3fff2a8a24a73..6db375445e4a3 100644
--- a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
+++ b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
@@ -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
@@ -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

``````````

</details>


https://github.com/llvm/llvm-project/pull/166950
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
  • [llvm-branch-commits... Juan Manuel Martinez Caamaño via llvm-branch-commits
    • [llvm-branch-co... via llvm-branch-commits

Reply via email to