diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 114 |
1 files changed, 53 insertions, 61 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index d4aa31db8337..a127e81ce643 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -20,7 +20,6 @@ #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -133,7 +132,7 @@ private: unsigned Flags = 0; }; - void initialize(Module &M); + void initialize(Module &M, const TargetLibraryInfo &TLI); bool instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL); bool instrumentAtomic(Instruction *I, const DataLayout &DL); bool instrumentMemIntrinsic(Instruction *I); @@ -196,13 +195,14 @@ PreservedAnalyses ModuleThreadSanitizerPass::run(Module &M, insertModuleCtor(M); return PreservedAnalyses::none(); } -void ThreadSanitizer::initialize(Module &M) { +void ThreadSanitizer::initialize(Module &M, const TargetLibraryInfo &TLI) { const DataLayout &DL = M.getDataLayout(); - IntptrTy = DL.getIntPtrType(M.getContext()); + LLVMContext &Ctx = M.getContext(); + IntptrTy = DL.getIntPtrType(Ctx); - IRBuilder<> IRB(M.getContext()); + IRBuilder<> IRB(Ctx); AttributeList Attr; - Attr = Attr.addFnAttribute(M.getContext(), Attribute::NoUnwind); + Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind); // Initialize the callbacks. TsanFuncEntry = M.getOrInsertFunction("__tsan_func_entry", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()); @@ -261,24 +261,24 @@ void ThreadSanitizer::initialize(Module &M) { TsanUnalignedCompoundRW[i] = M.getOrInsertFunction( UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()); - Type *Ty = Type::getIntNTy(M.getContext(), BitSize); + Type *Ty = Type::getIntNTy(Ctx, BitSize); Type *PtrTy = Ty->getPointerTo(); SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load"); - { - AttributeList AL = Attr; - AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt); - TsanAtomicLoad[i] = - M.getOrInsertFunction(AtomicLoadName, AL, Ty, PtrTy, OrdTy); - } - + TsanAtomicLoad[i] = + M.getOrInsertFunction(AtomicLoadName, + TLI.getAttrList(&Ctx, {1}, /*Signed=*/true, + /*Ret=*/BitSize <= 32, Attr), + Ty, PtrTy, OrdTy); + + // Args of type Ty need extension only when BitSize is 32 or less. + using Idxs = std::vector<unsigned>; + Idxs Idxs2Or12 ((BitSize <= 32) ? Idxs({1, 2}) : Idxs({2})); + Idxs Idxs34Or1234((BitSize <= 32) ? Idxs({1, 2, 3, 4}) : Idxs({3, 4})); SmallString<32> AtomicStoreName("__tsan_atomic" + BitSizeStr + "_store"); - { - AttributeList AL = Attr; - AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt); - TsanAtomicStore[i] = M.getOrInsertFunction( - AtomicStoreName, AL, IRB.getVoidTy(), PtrTy, Ty, OrdTy); - } + TsanAtomicStore[i] = M.getOrInsertFunction( + AtomicStoreName, + TLI.getAttrList(&Ctx, Idxs2Or12, /*Signed=*/true, /*Ret=*/false, Attr), + IRB.getVoidTy(), PtrTy, Ty, OrdTy); for (unsigned Op = AtomicRMWInst::FIRST_BINOP; Op <= AtomicRMWInst::LAST_BINOP; ++Op) { @@ -301,54 +301,46 @@ void ThreadSanitizer::initialize(Module &M) { else continue; SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart); - { - AttributeList AL = Attr; - AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt); - TsanAtomicRMW[Op][i] = - M.getOrInsertFunction(RMWName, AL, Ty, PtrTy, Ty, OrdTy); - } + TsanAtomicRMW[Op][i] = M.getOrInsertFunction( + RMWName, + TLI.getAttrList(&Ctx, Idxs2Or12, /*Signed=*/true, + /*Ret=*/BitSize <= 32, Attr), + Ty, PtrTy, Ty, OrdTy); } SmallString<32> AtomicCASName("__tsan_atomic" + BitSizeStr + "_compare_exchange_val"); - { - AttributeList AL = Attr; - AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 4, Attribute::ZExt); - TsanAtomicCAS[i] = M.getOrInsertFunction(AtomicCASName, AL, Ty, PtrTy, Ty, - Ty, OrdTy, OrdTy); - } + TsanAtomicCAS[i] = M.getOrInsertFunction( + AtomicCASName, + TLI.getAttrList(&Ctx, Idxs34Or1234, /*Signed=*/true, + /*Ret=*/BitSize <= 32, Attr), + Ty, PtrTy, Ty, Ty, OrdTy, OrdTy); } TsanVptrUpdate = M.getOrInsertFunction("__tsan_vptr_update", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy()); TsanVptrLoad = M.getOrInsertFunction("__tsan_vptr_read", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()); - { - AttributeList AL = Attr; - AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt); - TsanAtomicThreadFence = M.getOrInsertFunction("__tsan_atomic_thread_fence", - AL, IRB.getVoidTy(), OrdTy); - } - { - AttributeList AL = Attr; - AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt); - TsanAtomicSignalFence = M.getOrInsertFunction("__tsan_atomic_signal_fence", - AL, IRB.getVoidTy(), OrdTy); - } + TsanAtomicThreadFence = M.getOrInsertFunction( + "__tsan_atomic_thread_fence", + TLI.getAttrList(&Ctx, {0}, /*Signed=*/true, /*Ret=*/false, Attr), + IRB.getVoidTy(), OrdTy); + + TsanAtomicSignalFence = M.getOrInsertFunction( + "__tsan_atomic_signal_fence", + TLI.getAttrList(&Ctx, {0}, /*Signed=*/true, /*Ret=*/false, Attr), + IRB.getVoidTy(), OrdTy); MemmoveFn = - M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(), + M.getOrInsertFunction("__tsan_memmove", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy); MemcpyFn = - M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(), + M.getOrInsertFunction("__tsan_memcpy", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy); - MemsetFn = - M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy); + MemsetFn = M.getOrInsertFunction( + "__tsan_memset", + TLI.getAttrList(&Ctx, {1}, /*Signed=*/true, /*Ret=*/false, Attr), + IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy); } static bool isVtableAccess(Instruction *I) { @@ -379,7 +371,7 @@ static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr) { return false; } - // Do not instrument acesses from different address spaces; we cannot deal + // Do not instrument accesses from different address spaces; we cannot deal // with them. if (Addr) { Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType()); @@ -486,7 +478,7 @@ static bool isTsanAtomic(const Instruction *I) { if (!SSID) return false; if (isa<LoadInst>(I) || isa<StoreInst>(I)) - return SSID.value() != SyncScope::SingleThread; + return *SSID != SyncScope::SingleThread; return true; } @@ -517,7 +509,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) return false; - initialize(*F.getParent()); + initialize(*F.getParent(), TLI); SmallVector<InstructionInfo, 8> AllLoadsAndStores; SmallVector<Instruction*, 8> LocalLoadsAndStores; SmallVector<Instruction*, 8> AtomicAccesses; @@ -561,12 +553,12 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, // Instrument atomic memory accesses in any case (they can be used to // implement synchronization). if (ClInstrumentAtomics) - for (auto Inst : AtomicAccesses) { + for (auto *Inst : AtomicAccesses) { Res |= instrumentAtomic(Inst, DL); } if (ClInstrumentMemIntrinsics && SanitizeFunction) - for (auto Inst : MemIntrinCalls) { + for (auto *Inst : MemIntrinCalls) { Res |= instrumentMemIntrinsic(Inst); } @@ -676,7 +668,7 @@ static ConstantInt *createOrdering(IRBuilder<> *IRB, AtomicOrdering ord) { switch (ord) { case AtomicOrdering::NotAtomic: llvm_unreachable("unexpected atomic ordering!"); - case AtomicOrdering::Unordered: LLVM_FALLTHROUGH; + case AtomicOrdering::Unordered: [[fallthrough]]; case AtomicOrdering::Monotonic: v = 0; break; // Not specified yet: // case AtomicOrdering::Consume: v = 1; break; @@ -802,7 +794,7 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) { } Value *Res = - IRB.CreateInsertValue(UndefValue::get(CASI->getType()), OldVal, 0); + IRB.CreateInsertValue(PoisonValue::get(CASI->getType()), OldVal, 0); Res = IRB.CreateInsertValue(Res, Success, 1); I->replaceAllUsesWith(Res); |