[llvm] add support for the SPV_KHR_linkonce_odr extension (PR #81512)

Vyacheslav Levytskyy via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 12 10:49:01 PST 2024


https://github.com/VyacheslavLevytskyy updated https://github.com/llvm/llvm-project/pull/81512

>From 41b1ca1263ac2afe8cd4298be6fd6561c4cfa382 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 12 Feb 2024 10:35:20 -0800
Subject: [PATCH 1/2] add support for the SPV_KHR_linkonce_odr extension

---
 llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp     | 17 ++++++++++++-----
 .../Target/SPIRV/SPIRVInstructionSelector.cpp   |  5 ++++-
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp   |  6 ++++++
 llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp        |  5 +++++
 llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td  |  1 +
 llvm/test/CodeGen/SPIRV/LinkOnceODR.ll          | 11 ++++++++++-
 6 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index 8ac498e1556bec..fd287f2a944d36 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -332,6 +332,10 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
   if (F.hasName())
     buildOpName(FuncVReg, F.getName(), MIRBuilder);
 
+  // Get access to information about available extensions
+  const auto *ST =
+      static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
+
   // Handle entry points and function linkage.
   if (isEntryPoint(F)) {
     const auto &STI = MIRBuilder.getMF().getSubtarget<SPIRVSubtarget>();
@@ -342,15 +346,18 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
     addStringImm(F.getName(), MIB);
   } else if (F.getLinkage() == GlobalValue::LinkageTypes::ExternalLinkage ||
              F.getLinkage() == GlobalValue::LinkOnceODRLinkage) {
-    auto LnkTy = F.isDeclaration() ? SPIRV::LinkageType::Import
-                                   : SPIRV::LinkageType::Export;
+    SPIRV::LinkageType::LinkageType LnkTy = F.isDeclaration()
+                     ? SPIRV::LinkageType::Import
+                     : (F.getLinkage() == GlobalValue::LinkOnceODRLinkage &&
+                                ST->canUseExtension(
+                                    SPIRV::Extension::SPV_KHR_linkonce_odr)
+                            ? SPIRV::LinkageType::LinkOnceODR
+                            : SPIRV::LinkageType::Export);
     buildOpDecorate(FuncVReg, MIRBuilder, SPIRV::Decoration::LinkageAttributes,
                     {static_cast<uint32_t>(LnkTy)}, F.getGlobalIdentifier());
   }
 
   // Handle function pointers decoration
-  const auto *ST =
-      static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
   bool hasFunctionPointers =
       ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
   if (hasFunctionPointers) {
@@ -393,7 +400,7 @@ void SPIRVCallLowering::produceIndirectPtrTypes(
     // SPIR-V pointer to function type:
     SPIRVType *IndirectFuncPtrTy = GR->getOrCreateSPIRVPointerType(
         SpirvFuncTy, MIRBuilder, SPIRV::StorageClass::Function);
-    // Correct the Calee type
+    // Correct the Callee type
     GR->assignSPIRVTypeToVReg(IndirectFuncPtrTy, IC.Callee, MF);
   }
 }
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 52eeb8a523e6f6..ed2c9ab4d4362a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1601,7 +1601,10 @@ bool SPIRVInstructionSelector::selectGlobalValue(
   SPIRV::LinkageType::LinkageType LnkType =
       (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
           ? SPIRV::LinkageType::Import
-          : SPIRV::LinkageType::Export;
+          : (GV->getLinkage() == GlobalValue::LinkOnceODRLinkage &&
+                     STI.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr)
+                 ? SPIRV::LinkageType::LinkOnceODR
+                 : SPIRV::LinkageType::Export);
 
   Register Reg = GR.buildGlobalVariable(ResVReg, ResType, GlobalIdent, GV,
                                         Storage, Init, GlobalVar->isConstant(),
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index a18aae1761c834..cb2320a98b344b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -647,6 +647,12 @@ static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
     auto BuiltIn = static_cast<SPIRV::BuiltIn::BuiltIn>(BuiltInOp);
     Reqs.addRequirements(getSymbolicOperandRequirements(
         SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
+  } else if (Dec == SPIRV::Decoration::LinkageAttributes) {
+    int64_t LinkageOp = MI.getOperand(DecIndex + 2).getImm();
+    SPIRV::LinkageType::LinkageType LnkType =
+        static_cast<SPIRV::LinkageType::LinkageType>(LinkageOp);
+    if (LnkType == SPIRV::LinkageType::LinkOnceODR)
+      Reqs.addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
   }
 }
 
diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
index effedc2f17d351..6bcd8d4d514182 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
@@ -54,6 +54,11 @@ cl::list<SPIRV::Extension::Extension> Extensions(
                    "SPV_KHR_bit_instructions",
                    "This enables bit instructions to be used by SPIR-V modules "
                    "without requiring the Shader capability"),
+        clEnumValN(SPIRV::Extension::SPV_KHR_linkonce_odr,
+                   "SPV_KHR_linkonce_odr",
+                   "Allows to use the LinkOnceODR linkage type that is to let "
+                   "a function or global variable to be merged with other functions "
+                   "or global variables of the same name when linkage occurs."),
         clEnumValN(SPIRV::Extension::SPV_INTEL_function_pointers,
                    "SPV_INTEL_function_pointers",
                    "Allows translation of function pointers")));
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index 5d252275ac709b..ed05013642ac21 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -1040,6 +1040,7 @@ multiclass LinkageTypeOperand<bits<32> value, list<Capability> reqCapabilities>
 
 defm Export : LinkageTypeOperand<0, [Linkage]>;
 defm Import : LinkageTypeOperand<1, [Linkage]>;
+defm LinkOnceODR : LinkageTypeOperand<2, [Linkage]>;
 
 //===----------------------------------------------------------------------===//
 // Multiclass used to define AccessQualifier enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/LinkOnceODR.ll b/llvm/test/CodeGen/SPIRV/LinkOnceODR.ll
index 3fb49ac241c6e6..1ea6f62f3ba04b 100644
--- a/llvm/test/CodeGen/SPIRV/LinkOnceODR.ll
+++ b/llvm/test/CodeGen/SPIRV/LinkOnceODR.ll
@@ -1,5 +1,14 @@
-;; No extension -> no LinkOnceODR
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-extensions=SPV_KHR_linkonce_odr %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV-EXT
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown --spirv-extensions=SPV_KHR_linkonce_odr %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-SPIRV-EXT: Capability Linkage
+; CHECK-SPIRV-EXT: Extension "SPV_KHR_linkonce_odr"
+; CHECK-SPIRV-EXT-DAG: OpDecorate %[[#]] LinkageAttributes "GV" LinkOnceODR
+; CHECK-SPIRV-EXT-DAG: OpDecorate %[[#]] LinkageAttributes "square" LinkOnceODR
+
+; No extension -> no LinkOnceODR
 ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ; CHECK-SPIRV-NOT: OpExtension "SPV_KHR_linkonce_odr"
 ; CHECK-SPIRV-NOT: OpDecorate %[[#]] LinkageAttributes "GV" LinkOnceODR 

>From df2a57dd4c613bd750981332f2514138ca357c7c Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 12 Feb 2024 10:48:50 -0800
Subject: [PATCH 2/2] apply clang-format suggestions

---
 llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 15 ++++++++-------
 llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp    | 10 +++++-----
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index fd287f2a944d36..baeed2ad895a4b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -346,13 +346,14 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
     addStringImm(F.getName(), MIB);
   } else if (F.getLinkage() == GlobalValue::LinkageTypes::ExternalLinkage ||
              F.getLinkage() == GlobalValue::LinkOnceODRLinkage) {
-    SPIRV::LinkageType::LinkageType LnkTy = F.isDeclaration()
-                     ? SPIRV::LinkageType::Import
-                     : (F.getLinkage() == GlobalValue::LinkOnceODRLinkage &&
-                                ST->canUseExtension(
-                                    SPIRV::Extension::SPV_KHR_linkonce_odr)
-                            ? SPIRV::LinkageType::LinkOnceODR
-                            : SPIRV::LinkageType::Export);
+    SPIRV::LinkageType::LinkageType LnkTy =
+        F.isDeclaration()
+            ? SPIRV::LinkageType::Import
+            : (F.getLinkage() == GlobalValue::LinkOnceODRLinkage &&
+                       ST->canUseExtension(
+                           SPIRV::Extension::SPV_KHR_linkonce_odr)
+                   ? SPIRV::LinkageType::LinkOnceODR
+                   : SPIRV::LinkageType::Export);
     buildOpDecorate(FuncVReg, MIRBuilder, SPIRV::Decoration::LinkageAttributes,
                     {static_cast<uint32_t>(LnkTy)}, F.getGlobalIdentifier());
   }
diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
index 6bcd8d4d514182..354cd5d9b297e7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
@@ -54,11 +54,11 @@ cl::list<SPIRV::Extension::Extension> Extensions(
                    "SPV_KHR_bit_instructions",
                    "This enables bit instructions to be used by SPIR-V modules "
                    "without requiring the Shader capability"),
-        clEnumValN(SPIRV::Extension::SPV_KHR_linkonce_odr,
-                   "SPV_KHR_linkonce_odr",
-                   "Allows to use the LinkOnceODR linkage type that is to let "
-                   "a function or global variable to be merged with other functions "
-                   "or global variables of the same name when linkage occurs."),
+        clEnumValN(
+            SPIRV::Extension::SPV_KHR_linkonce_odr, "SPV_KHR_linkonce_odr",
+            "Allows to use the LinkOnceODR linkage type that is to let "
+            "a function or global variable to be merged with other functions "
+            "or global variables of the same name when linkage occurs."),
         clEnumValN(SPIRV::Extension::SPV_INTEL_function_pointers,
                    "SPV_INTEL_function_pointers",
                    "Allows translation of function pointers")));



More information about the llvm-commits mailing list