Index: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -321,6 +321,7 @@ cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0)); +static const char *const kMsanModuleCtorName = "msan.module_ctor"; static const char *const kMsanInitName = "__msan_init"; namespace { @@ -586,6 +587,8 @@ /// An empty volatile inline asm that prevents callback merge. InlineAsm *EmptyAsm; + + Function *MsanCtorFunction; }; /// A legacy function pass for msan instrumentation. @@ -839,6 +842,8 @@ } /// Module-level initialization. +/// +/// inserts a call to __msan_init to the module's constructor list. void MemorySanitizer::initializeModule(Module &M) { auto &DL = M.getDataLayout(); @@ -913,7 +918,22 @@ OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000); if (!CompileKernel) { - getOrCreateInitFunction(M, kMsanInitName); + std::tie(MsanCtorFunction, std::ignore) = + getOrCreateSanitizerCtorAndInitFunctions( + M, kMsanModuleCtorName, kMsanInitName, + /*InitArgTypes=*/{}, + /*InitArgs=*/{}, + // This callback is invoked when the functions are created the first + // time. Hook them into the global ctors list in that case: + [&](Function *Ctor, Function *) { + if (!ClWithComdat) { + appendToGlobalCtors(M, Ctor, 0); + return; + } + Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName); + Ctor->setComdat(MsanCtorComdat); + appendToGlobalCtors(M, Ctor, 0, Ctor); + }); if (TrackOrigins) M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] { @@ -4458,6 +4478,8 @@ } bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) { + if (!CompileKernel && (&F == MsanCtorFunction)) + return false; MemorySanitizerVisitor Visitor(F, *this, TLI); // Clear out readonly/readnone attributes. Index: llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll +++ llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll @@ -0,0 +1,18 @@ +; MSan converts 2-element global_ctors to 3-element when adding the new entry. +; RUN: opt < %s -msan-with-comdat -S -passes=msan 2>&1 | FileCheck %s +; RUN: opt < %s -msan -msan-with-comdat -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK: $msan.module_ctor = comdat any +; CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }] + +@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }] + +define internal void @f() { +entry: + ret void +} + +; CHECK: define internal void @msan.module_ctor() comdat { Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll +++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll @@ -9,7 +9,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @__msan_init, i8* null } +; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @msan.module_ctor, i8* null } ; Check the presence and the linkage type of __msan_track_origins and ; other interface symbols. @@ -991,4 +991,5 @@ ; CHECK-NEXT: ret i8* -; CHECK: declare void @__msan_init() +; CHECK-LABEL: define internal void @msan.module_ctor() { +; CHECK: call void @__msan_init() Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll +++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll @@ -1,6 +1,9 @@ ; Make sure MSan doesn't insert shadow checks for @llvm.is.constant.* arguments. +; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: -check-prefixes=CHECK %s ; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck -check-prefixes=CHECK %s ; RUN: opt < %s -msan -S | FileCheck -check-prefixes=CHECK %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"