[llvm] r346381 - [sancov] Put .SCOV* sections into the right comdat groups on COFF

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 7 16:57:34 PST 2018


Author: rnk
Date: Wed Nov  7 16:57:33 2018
New Revision: 346381

URL: http://llvm.org/viewvc/llvm-project?rev=346381&view=rev
Log:
[sancov] Put .SCOV* sections into the right comdat groups on COFF

Avoids linker errors about relocations against discarded sections.

This was uncovered during the Chromium clang roll here:
https://chromium-review.googlesource.com/c/chromium/src/+/1321863#message-717516acfcf829176f6a2f50980f7a4bdd66469a

After this change, Chromium's libGLESv2 links successfully for me.

Reviewers: metzman, hans, morehouse

Differential Revision: https://reviews.llvm.org/D54232

Added:
    llvm/trunk/test/Instrumentation/SanitizerCoverage/coff-comdat.ll
Modified:
    llvm/trunk/include/llvm/Transforms/Instrumentation.h
    llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
    llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
    llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=346381&r1=346380&r2=346381&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
+++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Wed Nov  7 16:57:33 2018
@@ -24,6 +24,7 @@
 
 namespace llvm {
 
+class Triple;
 class FunctionPass;
 class ModulePass;
 class OptimizationRemarkEmitter;
@@ -45,7 +46,8 @@ GlobalVariable *createPrivateGlobalForSt
 // Returns F.getComdat() if it exists.
 // Otherwise creates a new comdat, sets F's comdat, and returns it.
 // Returns nullptr on failure.
-Comdat *GetOrCreateFunctionComdat(Function &F, const std::string &ModuleId);
+Comdat *GetOrCreateFunctionComdat(Function &F, Triple &T,
+                                  const std::string &ModuleId);
 
 // Insert GCOV profiling instrumentation
 struct GCOVOptions {

Modified: llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp?rev=346381&r1=346380&r2=346381&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Wed Nov  7 16:57:33 2018
@@ -743,7 +743,8 @@ void HWAddressSanitizer::createFrameGlob
   appendToCompilerUsed(M, GV);
   // Put GV into the F's Comadat so that if F is deleted GV can be deleted too.
   if (&F != HwasanCtorFunction)
-    if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId))
+    if (auto Comdat =
+            GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
       GV->setComdat(Comdat);
 }
 

Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=346381&r1=346380&r2=346381&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Wed Nov  7 16:57:33 2018
@@ -14,6 +14,7 @@
 
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm-c/Initialization.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
@@ -70,19 +71,31 @@ GlobalVariable *llvm::createPrivateGloba
   return GV;
 }
 
-Comdat *llvm::GetOrCreateFunctionComdat(Function &F,
+Comdat *llvm::GetOrCreateFunctionComdat(Function &F, Triple &T,
                                         const std::string &ModuleId) {
   if (auto Comdat = F.getComdat()) return Comdat;
   assert(F.hasName());
   Module *M = F.getParent();
   std::string Name = F.getName();
-  if (F.hasLocalLinkage()) {
+
+  // Make a unique comdat name for internal linkage things on ELF. On COFF, the
+  // name of the comdat group identifies the leader symbol of the comdat group.
+  // The linkage of the leader symbol is considered during comdat resolution,
+  // and internal symbols with the same name from different objects will not be
+  // merged.
+  if (T.isOSBinFormatELF() && F.hasLocalLinkage()) {
     if (ModuleId.empty())
       return nullptr;
     Name += ModuleId;
   }
-  F.setComdat(M->getOrInsertComdat(Name));
-  return F.getComdat();
+
+  // Make a new comdat for the function. Use the "no duplicates" selection kind
+  // for non-weak symbols if the object file format supports it.
+  Comdat *C = M->getOrInsertComdat(Name);
+  if (T.isOSBinFormatCOFF() && !F.isWeakForLinker())
+    C->setSelectionKind(Comdat::NoDuplicates);
+  F.setComdat(C);
+  return C;
 }
 
 /// initializeInstrumentation - Initialize all passes in the TransformUtils

Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=346381&r1=346380&r2=346381&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Wed Nov  7 16:57:33 2018
@@ -577,8 +577,9 @@ GlobalVariable *SanitizerCoverageModule:
       *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
       Constant::getNullValue(ArrayTy), "__sancov_gen_");
 
-  if (TargetTriple.isOSBinFormatELF())
-    if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId))
+  if (TargetTriple.supportsCOMDAT())
+    if (auto Comdat =
+            GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
       Array->setComdat(Comdat);
   Array->setSection(getSectionName(Section));
   Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize()

Added: llvm/trunk/test/Instrumentation/SanitizerCoverage/coff-comdat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coff-comdat.ll?rev=346381&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coff-comdat.ll (added)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coff-comdat.ll Wed Nov  7 16:57:33 2018
@@ -0,0 +1,85 @@
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
+
+; Make sure we use the right comdat groups for COFF to avoid relocations
+; against discarded sections. Internal linkage functions are also different from
+; ELF. We don't add a module unique identifier.
+
+; Test based on this source:
+; int baz(int);
+; static int __attribute__((noinline)) bar(int x) {
+;   if (x)
+;     return baz(x);
+;   return 0;
+; }
+; int foo(int x) {
+;   if (baz(0))
+;     x = bar(x);
+;   return x;
+; }
+
+; Both new comdats should no duplicates on COFF.
+
+; CHECK: $foo = comdat noduplicates
+; CHECK: $bar = comdat noduplicates
+
+; Tables for 'foo' should be in the 'foo' comdat.
+
+; CHECK: @__sancov_gen_{{.*}} = private global [1 x i8] zeroinitializer, section ".SCOV$CM", comdat($foo), align 1
+
+; CHECK: @__sancov_gen_{{.*}} = private constant [2 x i64*]
+; CHECK-SAME: [i64* bitcast (i32 (i32)* @foo to i64*), i64* inttoptr (i64 1 to i64*)],
+; CHECK-SAME: section ".SCOVP$M", comdat($foo), align 8
+
+; Tables for 'bar' should be in the 'bar' comdat.
+
+; CHECK: @__sancov_gen_{{.*}} = private global [1 x i8] zeroinitializer, section ".SCOV$CM", comdat($bar), align 1
+
+; CHECK: @__sancov_gen_{{.*}} = private constant [2 x i64*]
+; CHECK-SAME: [i64* bitcast (i32 (i32)* @bar to i64*), i64* inttoptr (i64 1 to i64*)],
+; CHECK-SAME: section ".SCOVP$M", comdat($bar), align 8
+
+; 'foo' and 'bar' should be in their new comdat groups.
+
+; CHECK: define dso_local i32 @foo(i32 %x){{.*}} comdat {
+; CHECK: define internal fastcc i32 @bar(i32 %x){{.*}} comdat {
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.14.26433"
+
+; Function Attrs: nounwind uwtable
+define dso_local i32 @foo(i32 %x) local_unnamed_addr #0 {
+entry:
+  %call = tail call i32 @baz(i32 0) #3
+  %tobool = icmp eq i32 %call, 0
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  %call1 = tail call fastcc i32 @bar(i32 %x)
+  br label %if.end
+
+if.end:                                           ; preds = %entry, %if.then
+  %x.addr.0 = phi i32 [ %call1, %if.then ], [ %x, %entry ]
+  ret i32 %x.addr.0
+}
+
+declare dso_local i32 @baz(i32) local_unnamed_addr #1
+
+; Function Attrs: noinline nounwind uwtable
+define internal fastcc i32 @bar(i32 %x) unnamed_addr #2 {
+entry:
+  %tobool = icmp eq i32 %x, 0
+  br i1 %tobool, label %return, label %if.then
+
+if.then:                                          ; preds = %entry
+  %call = tail call i32 @baz(i32 %x) #3
+  br label %return
+
+return:                                           ; preds = %entry, %if.then
+  %retval.0 = phi i32 [ %call, %if.then ], [ 0, %entry ]
+  ret i32 %retval.0
+}
+
+attributes #0 = { nounwind uwtable }
+attributes #1 = { "asdf" }
+attributes #2 = { noinline nounwind uwtable }
+attributes #3 = { nounwind }




More information about the llvm-commits mailing list