From 667d4f41076c8eecf56aa6a4695575183948e116 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 19 Apr 2019 01:48:36 +0000 Subject: [PATCH] MergeFunc: preserve COMDAT information when creating a thunk We would previously drop the COMDAT on the thunk we generated when replacing a function body with the forwarding thunk. This would result in a function that may have been multiply emitted and multiply merged to be emitted with the same name without the COMDAT. This is a hard error with PE/COFF where the COMDAT is used for the deduplication of Value Witness functions for Swift. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358728 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/MergeFunctions.cpp | 1 + test/Transforms/MergeFunc/comdat.ll | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/Transforms/MergeFunc/comdat.ll diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp index 1ca4ebecd08..d0c16138f9e 100644 --- a/lib/Transforms/IPO/MergeFunctions.cpp +++ b/lib/Transforms/IPO/MergeFunctions.cpp @@ -703,6 +703,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) { } else { NewG = Function::Create(G->getFunctionType(), G->getLinkage(), G->getAddressSpace(), "", G->getParent()); + NewG->setComdat(G->getComdat()); BB = BasicBlock::Create(F->getContext(), "", NewG); } diff --git a/test/Transforms/MergeFunc/comdat.ll b/test/Transforms/MergeFunc/comdat.ll new file mode 100644 index 00000000000..ce289598fa1 --- /dev/null +++ b/test/Transforms/MergeFunc/comdat.ll @@ -0,0 +1,24 @@ +; RUN: opt -S -mergefunc %s | FileCheck %s + +@symbols = linkonce_odr global <{ i8*, i8* }> <{ i8* bitcast (i32 (i32, i32)* @f to i8*), i8* bitcast (i32 (i32, i32)* @g to i8*) }> + +$f = comdat any +$g = comdat any + +define linkonce_odr hidden i32 @f(i32 %x, i32 %y) comdat { + %sum = add i32 %x, %y + %sum2 = add i32 %x, %sum + %sum3 = add i32 %x, %sum + ret i32 %sum3 +} + +define linkonce_odr hidden i32 @g(i32 %x, i32 %y) comdat { + %sum = add i32 %x, %y + %sum2 = add i32 %x, %sum + %sum3 = add i32 %x, %sum + ret i32 %sum3 +} + +; CHECK-DAG: define linkonce_odr hidden i32 @f(i32 %x, i32 %y) comdat +; CHECK-DAG: define linkonce_odr hidden i32 @g(i32, i32) comdat + -- 2.40.0