[Mlir-commits] [mlir] [mlir] Add option to add comdat to all linkonce functions (PR #65270)

David Truby llvmlistbot at llvm.org
Mon Sep 4 08:30:16 PDT 2023


https://github.com/DavidTruby created https://github.com/llvm/llvm-project/pull/65270:

This adds an option to the FuncToLLVM pass to add an Any comdat to each linkonce
and linkonce_odr function when lowering. These comdats are necessary on Windows
to allow the default system linker to link binaries containing these functions.

>From a28350de1a2682a94819526e9c0b10be299aece4 Mon Sep 17 00:00:00 2001
From: David Truby <david at truby.dev>
Date: Mon, 4 Sep 2023 16:06:24 +0100
Subject: [PATCH] [mlir] Add option to add comdat to all linkonce functions

This adds an option to the FuncToLLVM pass to add an Any comdat to each linkonce
and linkonce_odr function when lowering. These comdats are necessary on Windows
to allow the default system linker to link binaries containing these functions.
---
 .../Conversion/LLVMCommon/LoweringOptions.h   |  1 +
 mlir/include/mlir/Conversion/Passes.td        |  7 +++--
 .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td       |  2 +-
 mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 27 +++++++++++++++++++
 .../FuncToLLVM/add-linkonce-comdat.mlir       | 17 ++++++++++++
 5 files changed, 51 insertions(+), 3 deletions(-)
 create mode 100644 mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir

diff --git a/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h b/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h
index cc4e17e9527f01e..677fdbb3e973df2 100644
--- a/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h
+++ b/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h
@@ -34,6 +34,7 @@ class LowerToLLVMOptions {
 
   bool useBarePtrCallConv = false;
   bool useOpaquePointers = true;
+  bool addComdatToLinkonceFuncs = false;
 
   enum class AllocLowering {
     /// Use malloc for heap allocations.
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index eaf016bde69e3be..6bcffa32a7010be 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -381,6 +381,9 @@ def ConvertFuncToLLVMPass : Pass<"convert-func-to-llvm", "ModuleOp"> {
     Option<"useOpaquePointers", "use-opaque-pointers", "bool",
                        /*default=*/"true", "Generate LLVM IR using opaque pointers "
                        "instead of typed pointers">,
+    Option<"addComdatToLinkonceFuncs", "add-comdat-to-linkonce-funcs", "bool",
+                       /*default=*/"false", "Add an any comdat selector to Linkonce "
+                       "functions">,
   ];
 }
 
@@ -760,12 +763,12 @@ def ConvertMemRefToSPIRV : Pass<"convert-memref-to-spirv"> {
 def ConvertNVVMToLLVMPass : Pass<"convert-nvvm-to-llvm"> {
   let summary = "Convert NVVM dialect to LLVM dialect";
   let description = [{
-    This pass generates inline assembly for the NVVM ops which is not 
+    This pass generates inline assembly for the NVVM ops which is not
     implemented in LLVM core.
   }];
   let dependentDialects = [
     "NVVM::NVVMDialect",
-  ];  
+  ];
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 2443b23e42e43ce..d4a9e911f36b145 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -35,7 +35,7 @@ def CConvAttr : LLVM_Attr<"CConv", "cconv"> {
 
 def ComdatAttr : LLVM_Attr<"Comdat", "comdat"> {
   let parameters = (ins "comdat::Comdat":$comdat);
-  let assemblyFormat = "$comdat";
+  let assemblyFormat = "`<` $comdat `>`";
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index 1db463c0ab7163b..580b4796fbe55f9 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -328,6 +328,25 @@ static void modifyFuncOpToUseBarePtrCallingConv(
 
 namespace {
 
+template <typename Op>
+void addComdat(Op &op, mlir::PatternRewriter &rewriter,
+               mlir::ModuleOp &module) {
+  const char *comdatName = "__llvm_comdat";
+  mlir::LLVM::ComdatOp comdatOp =
+      module.lookupSymbol<mlir::LLVM::ComdatOp>(comdatName);
+  if (!comdatOp) {
+    comdatOp =
+        rewriter.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
+  }
+  mlir::OpBuilder::InsertionGuard guard(rewriter);
+  rewriter.setInsertionPointToEnd(&comdatOp.getBody().back());
+  auto selectorOp = rewriter.create<mlir::LLVM::ComdatSelectorOp>(
+      comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
+  op.setComdatAttr(mlir::SymbolRefAttr::get(
+      rewriter.getContext(), comdatName,
+      mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr())));
+}
+
 struct FuncOpConversionBase : public ConvertOpToLLVMPattern<func::FuncOp> {
 protected:
   using ConvertOpToLLVMPattern<func::FuncOp>::ConvertOpToLLVMPattern;
@@ -461,6 +480,13 @@ struct FuncOpConversionBase : public ConvertOpToLLVMPattern<func::FuncOp> {
                                          "region types conversion failed");
     }
 
+    if (getTypeConverter()->getOptions().addComdatToLinkonceFuncs &&
+        (newFuncOp.getLinkage() == LLVM::Linkage::Linkonce ||
+         newFuncOp.getLinkage() == LLVM::Linkage::LinkonceODR)) {
+      auto module = newFuncOp->getParentOfType<mlir::ModuleOp>();
+      addComdat(newFuncOp, rewriter, module);
+    }
+
     return newFuncOp;
   }
 };
@@ -764,6 +790,7 @@ struct ConvertFuncToLLVMPass
       options.overrideIndexBitwidth(indexBitwidth);
     options.dataLayout = llvm::DataLayout(this->dataLayout);
     options.useOpaquePointers = useOpaquePointers;
+    options.addComdatToLinkonceFuncs = addComdatToLinkonceFuncs;
 
     LLVMTypeConverter typeConverter(&getContext(), options,
                                     &dataLayoutAnalysis);
diff --git a/mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir b/mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir
new file mode 100644
index 000000000000000..95cd8b6dd79de65
--- /dev/null
+++ b/mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir
@@ -0,0 +1,17 @@
+// RUN: mlir-opt -convert-func-to-llvm='add-comdat-to-linkonce-funcs=1' -split-input-file -verify-diagnostics %s | FileCheck %s
+
+// CHECK-DAG: llvm.func linkonce @linkonce() comdat(@__llvm_comdat::@linkonce)
+func.func @linkonce() attributes {llvm.linkage = #llvm.linkage<linkonce>} {
+  return
+}
+
+// CHECK-DAG: llvm.comdat @__llvm_comdat {
+// CHECK: llvm.comdat_selector @linkonce any
+// CHECK: llvm.comdat_selector @linkonce_odr any
+// CHECK: }
+
+
+// CHECK-DAG: llvm.func linkonce_odr @linkonce_odr() comdat(@__llvm_comdat::@linkonce_odr)
+func.func @linkonce_odr() attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
+  return
+}



More information about the Mlir-commits mailing list