LLVM 24.0.0git
ThreadSanitizer.cpp
Go to the documentation of this file.
1//===-- ThreadSanitizer.cpp - race detector -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of ThreadSanitizer, a race detector.
10//
11// The tool is under development, for the details about previous versions see
12// http://code.google.com/p/data-race-test
13//
14// The instrumentation phase is quite simple:
15// - Insert calls to run-time library before every memory access.
16// - Optimizations may apply to avoid instrumenting some of the accesses.
17// - Insert calls at function entry/exit.
18// The rest is handled by the run-time library.
19//===----------------------------------------------------------------------===//
20
23#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/Statistic.h"
31#include "llvm/IR/DataLayout.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/IRBuilder.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/LLVMContext.h"
38#include "llvm/IR/Metadata.h"
39#include "llvm/IR/Module.h"
40#include "llvm/IR/Type.h"
42#include "llvm/Support/Debug.h"
48
49using namespace llvm;
50
51#define DEBUG_TYPE "tsan"
52
53STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
54STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
55STATISTIC(NumOmittedReadsBeforeWrite,
56 "Number of reads ignored due to following writes");
57STATISTIC(NumAccessesWithBadSize, "Number of accesses with bad size");
58STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
59STATISTIC(NumInstrumentedVtableReads, "Number of vtable ptr reads");
60STATISTIC(NumOmittedReadsFromConstantGlobals,
61 "Number of reads from constant globals");
62STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
63STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
64
65const char kTsanModuleCtorName[] = "tsan.module_ctor";
66const char kTsanInitName[] = "__tsan_init";
67
68namespace {
69
70/// ThreadSanitizer: instrument the code in module to find races.
71///
72/// Instantiating ThreadSanitizer inserts the tsan runtime library API function
73/// declarations into the module if they don't exist already. Instantiating
74/// ensures the __tsan_init function is in the list of global constructors for
75/// the module.
76struct ThreadSanitizer {
77 ThreadSanitizer(const InstrumentationOptions &Opts) : Opts(Opts) {
78 // Check options and warn user.
79 if (Opts.tsan_instrument_read_before_write &&
80 Opts.tsan_compound_read_before_write) {
81 errs()
82 << "warning: Option -tsan-compound-read-before-write has no effect "
83 "when -tsan-instrument-read-before-write is set.\n";
84 }
85 }
86
87 bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
88
89private:
90 // Internal Instruction wrapper that contains more information about the
91 // Instruction from prior analysis.
92 struct InstructionInfo {
93 // Instrumentation emitted for this instruction is for a compounded set of
94 // read and write operations in the same basic block.
95 static constexpr unsigned kCompoundRW = (1U << 0);
96
97 explicit InstructionInfo(Instruction *Inst) : Inst(Inst) {}
98
99 Instruction *Inst;
100 unsigned Flags = 0;
101 };
102
103 void initialize(Module &M, const TargetLibraryInfo &TLI);
104 bool instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL);
105 bool instrumentAtomic(Instruction *I, const DataLayout &DL);
106 bool instrumentMemIntrinsic(Instruction *I);
107 void chooseInstructionsToInstrument(SmallVectorImpl<Instruction *> &Local,
109 const DataLayout &DL);
110 bool addrPointsToConstantData(Value *Addr);
111 int getMemoryAccessFuncIndex(Type *OrigTy, Value *Addr, const DataLayout &DL);
112 void InsertRuntimeIgnores(Function &F);
113
114 const InstrumentationOptions &Opts;
115 Type *IntptrTy;
116 FunctionCallee TsanFuncEntry;
117 FunctionCallee TsanFuncExit;
118 FunctionCallee TsanIgnoreBegin;
119 FunctionCallee TsanIgnoreEnd;
120 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
121 static const size_t kNumberOfAccessSizes = 5;
124 FunctionCallee TsanUnalignedRead[kNumberOfAccessSizes];
125 FunctionCallee TsanUnalignedWrite[kNumberOfAccessSizes];
126 FunctionCallee TsanVolatileRead[kNumberOfAccessSizes];
127 FunctionCallee TsanVolatileWrite[kNumberOfAccessSizes];
128 FunctionCallee TsanUnalignedVolatileRead[kNumberOfAccessSizes];
129 FunctionCallee TsanUnalignedVolatileWrite[kNumberOfAccessSizes];
130 FunctionCallee TsanCompoundRW[kNumberOfAccessSizes];
131 FunctionCallee TsanUnalignedCompoundRW[kNumberOfAccessSizes];
132 FunctionCallee TsanAtomicLoad[kNumberOfAccessSizes];
133 FunctionCallee TsanAtomicStore[kNumberOfAccessSizes];
137 FunctionCallee TsanAtomicThreadFence;
138 FunctionCallee TsanAtomicSignalFence;
139 FunctionCallee TsanVptrUpdate;
140 FunctionCallee TsanVptrLoad;
141 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
142};
143
144void insertModuleCtor(Module &M) {
146 M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
147 /*InitArgs=*/{},
148 // This callback is invoked when the functions are created the first
149 // time. Hook them into the global ctors list in that case:
150 [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); });
151}
152} // namespace
153
156 ThreadSanitizer TSan(
157 F.getContext().getLibraryOptions().get<InstrumentationOptions>());
158 if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
160 return PreservedAnalyses::all();
161}
162
165 // Return early if nosanitize_thread module flag is present for the module.
166 if (checkIfAlreadyInstrumented(M, "nosanitize_thread"))
167 return PreservedAnalyses::all();
170}
171void ThreadSanitizer::initialize(Module &M, const TargetLibraryInfo &TLI) {
172 const DataLayout &DL = M.getDataLayout();
173 LLVMContext &Ctx = M.getContext();
174 IntptrTy = DL.getIntPtrType(Ctx);
175
176 IRBuilder<> IRB(M);
177 AttributeList Attr;
178 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
179 // Initialize the callbacks.
180 TsanFuncEntry = M.getOrInsertFunction("__tsan_func_entry", Attr,
181 IRB.getVoidTy(), IRB.getPtrTy());
182 TsanFuncExit =
183 M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy());
184 TsanIgnoreBegin = M.getOrInsertFunction("__tsan_ignore_thread_begin", Attr,
185 IRB.getVoidTy());
186 TsanIgnoreEnd =
187 M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
188 IntegerType *OrdTy = IRB.getInt32Ty();
189 for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
190 const unsigned ByteSize = 1U << i;
191 const unsigned BitSize = ByteSize * 8;
192 std::string ByteSizeStr = utostr(ByteSize);
193 std::string BitSizeStr = utostr(BitSize);
194 SmallString<32> ReadName("__tsan_read" + ByteSizeStr);
195 TsanRead[i] = M.getOrInsertFunction(ReadName, Attr, IRB.getVoidTy(),
196 IRB.getPtrTy());
197
198 SmallString<32> WriteName("__tsan_write" + ByteSizeStr);
199 TsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(),
200 IRB.getPtrTy());
201
202 SmallString<64> UnalignedReadName("__tsan_unaligned_read" + ByteSizeStr);
203 TsanUnalignedRead[i] = M.getOrInsertFunction(
204 UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
205
206 SmallString<64> UnalignedWriteName("__tsan_unaligned_write" + ByteSizeStr);
207 TsanUnalignedWrite[i] = M.getOrInsertFunction(
208 UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
209
210 SmallString<64> VolatileReadName("__tsan_volatile_read" + ByteSizeStr);
211 TsanVolatileRead[i] = M.getOrInsertFunction(
212 VolatileReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
213
214 SmallString<64> VolatileWriteName("__tsan_volatile_write" + ByteSizeStr);
215 TsanVolatileWrite[i] = M.getOrInsertFunction(
216 VolatileWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
217
218 SmallString<64> UnalignedVolatileReadName("__tsan_unaligned_volatile_read" +
219 ByteSizeStr);
220 TsanUnalignedVolatileRead[i] = M.getOrInsertFunction(
221 UnalignedVolatileReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
222
223 SmallString<64> UnalignedVolatileWriteName(
224 "__tsan_unaligned_volatile_write" + ByteSizeStr);
225 TsanUnalignedVolatileWrite[i] = M.getOrInsertFunction(
226 UnalignedVolatileWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
227
228 SmallString<64> CompoundRWName("__tsan_read_write" + ByteSizeStr);
229 TsanCompoundRW[i] = M.getOrInsertFunction(
230 CompoundRWName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
231
232 SmallString<64> UnalignedCompoundRWName("__tsan_unaligned_read_write" +
233 ByteSizeStr);
234 TsanUnalignedCompoundRW[i] = M.getOrInsertFunction(
235 UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
236
237 Type *Ty = Type::getIntNTy(Ctx, BitSize);
238 Type *PtrTy = PointerType::get(Ctx, 0);
239 SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load");
240 TsanAtomicLoad[i] =
241 M.getOrInsertFunction(AtomicLoadName,
242 TLI.getAttrList(&Ctx, {1}, /*Signed=*/true,
243 /*Ret=*/BitSize <= 32, Attr),
244 Ty, PtrTy, OrdTy);
245
246 // Args of type Ty need extension only when BitSize is 32 or less.
247 using Idxs = std::vector<unsigned>;
248 Idxs Idxs2Or12 ((BitSize <= 32) ? Idxs({1, 2}) : Idxs({2}));
249 Idxs Idxs34Or1234((BitSize <= 32) ? Idxs({1, 2, 3, 4}) : Idxs({3, 4}));
250 SmallString<32> AtomicStoreName("__tsan_atomic" + BitSizeStr + "_store");
251 TsanAtomicStore[i] = M.getOrInsertFunction(
252 AtomicStoreName,
253 TLI.getAttrList(&Ctx, Idxs2Or12, /*Signed=*/true, /*Ret=*/false, Attr),
254 IRB.getVoidTy(), PtrTy, Ty, OrdTy);
255
256 for (unsigned Op = AtomicRMWInst::FIRST_BINOP;
258 TsanAtomicRMW[Op][i] = nullptr;
259 const char *NamePart = nullptr;
260 if (Op == AtomicRMWInst::Xchg)
261 NamePart = "_exchange";
262 else if (Op == AtomicRMWInst::Add)
263 NamePart = "_fetch_add";
264 else if (Op == AtomicRMWInst::Sub)
265 NamePart = "_fetch_sub";
266 else if (Op == AtomicRMWInst::And)
267 NamePart = "_fetch_and";
268 else if (Op == AtomicRMWInst::Or)
269 NamePart = "_fetch_or";
270 else if (Op == AtomicRMWInst::Xor)
271 NamePart = "_fetch_xor";
272 else if (Op == AtomicRMWInst::Nand)
273 NamePart = "_fetch_nand";
274 else
275 continue;
276 SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart);
277 TsanAtomicRMW[Op][i] = M.getOrInsertFunction(
278 RMWName,
279 TLI.getAttrList(&Ctx, Idxs2Or12, /*Signed=*/true,
280 /*Ret=*/BitSize <= 32, Attr),
281 Ty, PtrTy, Ty, OrdTy);
282 }
283
284 SmallString<32> AtomicCASName("__tsan_atomic" + BitSizeStr +
285 "_compare_exchange_val");
286 TsanAtomicCAS[i] = M.getOrInsertFunction(
287 AtomicCASName,
288 TLI.getAttrList(&Ctx, Idxs34Or1234, /*Signed=*/true,
289 /*Ret=*/BitSize <= 32, Attr),
290 Ty, PtrTy, Ty, Ty, OrdTy, OrdTy);
291 }
292 TsanVptrUpdate =
293 M.getOrInsertFunction("__tsan_vptr_update", Attr, IRB.getVoidTy(),
294 IRB.getPtrTy(), IRB.getPtrTy());
295 TsanVptrLoad = M.getOrInsertFunction("__tsan_vptr_read", Attr,
296 IRB.getVoidTy(), IRB.getPtrTy());
297 TsanAtomicThreadFence = M.getOrInsertFunction(
298 "__tsan_atomic_thread_fence",
299 TLI.getAttrList(&Ctx, {0}, /*Signed=*/true, /*Ret=*/false, Attr),
300 IRB.getVoidTy(), OrdTy);
301
302 TsanAtomicSignalFence = M.getOrInsertFunction(
303 "__tsan_atomic_signal_fence",
304 TLI.getAttrList(&Ctx, {0}, /*Signed=*/true, /*Ret=*/false, Attr),
305 IRB.getVoidTy(), OrdTy);
306
307 MemmoveFn =
308 M.getOrInsertFunction("__tsan_memmove", Attr, IRB.getPtrTy(),
309 IRB.getPtrTy(), IRB.getPtrTy(), IntptrTy);
310 MemcpyFn =
311 M.getOrInsertFunction("__tsan_memcpy", Attr, IRB.getPtrTy(),
312 IRB.getPtrTy(), IRB.getPtrTy(), IntptrTy);
313 MemsetFn = M.getOrInsertFunction(
314 "__tsan_memset",
315 TLI.getAttrList(&Ctx, {1}, /*Signed=*/true, /*Ret=*/false, Attr),
316 IRB.getPtrTy(), IRB.getPtrTy(), IRB.getInt32Ty(), IntptrTy);
317}
318
320 if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
321 return Tag->isTBAAVtableAccess();
322 return false;
323}
324
325// Do not instrument known races/"benign races" that come from compiler
326// instrumentation. The user has no way of suppressing them.
328 // Peel off GEPs and BitCasts.
329 // Note: This also peels AddrspaceCasts, so this should not be used when
330 // checking the address space below.
331 Value *PeeledAddr = Addr->stripInBoundsOffsets();
332
333 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PeeledAddr)) {
334 if (GV->hasSection()) {
335 StringRef SectionName = GV->getSection();
336 // Check if the global is in the PGO counters section.
337 auto OF = M->getTargetTriple().getObjectFormat();
338 if (SectionName.ends_with(
339 getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false)))
340 return false;
341 }
342 }
343
344 // Do not instrument accesses from different address spaces; we cannot deal
345 // with them.
346 Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
347 if (PtrTy->getPointerAddressSpace() != 0)
348 return false;
349
350 return true;
351}
352
353bool ThreadSanitizer::addrPointsToConstantData(Value *Addr) {
354 // If this is a GEP, just analyze its pointer operand.
356 Addr = GEP->getPointerOperand();
357
359 if (GV->isConstant()) {
360 // Reads from constant globals can not race with any writes.
361 NumOmittedReadsFromConstantGlobals++;
362 return true;
363 }
364 } else if (LoadInst *L = dyn_cast<LoadInst>(Addr)) {
365 if (isVtableAccess(L)) {
366 // Reads from a vtable pointer can not race with any writes.
367 NumOmittedReadsFromVtable++;
368 return true;
369 }
370 }
371 return false;
372}
373
374// Instrumenting some of the accesses may be proven redundant.
375// Currently handled:
376// - read-before-write (within same BB, no calls between)
377// - not captured variables
378//
379// We do not handle some of the patterns that should not survive
380// after the classic compiler optimizations.
381// E.g. two reads from the same temp should be eliminated by CSE,
382// two writes should be eliminated by DSE, etc.
383//
384// 'Local' is a vector of insns within the same BB (no calls between).
385// 'All' is a vector of insns that will be instrumented.
386void ThreadSanitizer::chooseInstructionsToInstrument(
389 DenseMap<Value *, size_t> WriteTargets; // Map of addresses to index in All
390 // Iterate from the end.
391 for (Instruction *I : reverse(Local)) {
392 const bool IsWrite = isa<StoreInst>(*I);
393 Value *Addr = IsWrite ? cast<StoreInst>(I)->getPointerOperand()
394 : cast<LoadInst>(I)->getPointerOperand();
395
396 if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr))
397 continue;
398
399 if (!IsWrite) {
400 const auto WriteEntry = WriteTargets.find(Addr);
401 if (!Opts.tsan_instrument_read_before_write &&
402 WriteEntry != WriteTargets.end()) {
403 auto &WI = All[WriteEntry->second];
404 // If we distinguish volatile accesses and if either the read or write
405 // is volatile, do not omit any instrumentation.
406 const bool AnyVolatile = Opts.tsan_distinguish_volatile &&
407 (cast<LoadInst>(I)->isVolatile() ||
408 cast<StoreInst>(WI.Inst)->isVolatile());
409 if (!AnyVolatile) {
410 // We will write to this temp, so no reason to analyze the read.
411 // Mark the write instruction as compound.
412 WI.Flags |= InstructionInfo::kCompoundRW;
413 NumOmittedReadsBeforeWrite++;
414 continue;
415 }
416 }
417
418 if (addrPointsToConstantData(Addr)) {
419 // Addr points to some constant data -- it can not race with any writes.
420 continue;
421 }
422 }
423
424 const AllocaInst *AI = findAllocaForValue(Addr);
425 // Instead of Addr, we should check whether its base pointer is captured.
426 if (AI && !PointerMayBeCaptured(AI, /*ReturnCaptures=*/true) &&
427 Opts.tsan_omit_by_pointer_capturing) {
428 // The variable is addressable but not captured, so it cannot be
429 // referenced from a different thread and participate in a data race
430 // (see llvm/Analysis/CaptureTracking.h for details).
431 NumOmittedNonCaptured++;
432 continue;
433 }
434
435 // Instrument this instruction.
436 All.emplace_back(I);
437 if (IsWrite) {
438 // For read-before-write and compound instrumentation we only need one
439 // write target, and we can override any previous entry if it exists.
440 WriteTargets[Addr] = All.size() - 1;
441 }
442 }
443 Local.clear();
444}
445
446static bool isTsanAtomic(const Instruction *I) {
447 // TODO: Ask TTI whether synchronization scope is between threads.
448 auto SSID = getAtomicSyncScopeID(I);
449 if (!SSID)
450 return false;
452 return *SSID != SyncScope::SingleThread;
453 return true;
454}
455
456void ThreadSanitizer::InsertRuntimeIgnores(Function &F) {
457 InstrumentationIRBuilder IRB(F.getEntryBlock().getFirstNonPHIIt());
458 IRB.CreateCall(TsanIgnoreBegin);
459 EscapeEnumerator EE(F, "tsan_ignore_cleanup",
460 Opts.tsan_handle_cxx_exceptions);
461 while (IRBuilder<> *AtExit = EE.Next()) {
463 AtExit->CreateCall(TsanIgnoreEnd);
464 }
465}
466
467bool ThreadSanitizer::sanitizeFunction(Function &F,
468 const TargetLibraryInfo &TLI) {
469 // This is required to prevent instrumenting call to __tsan_init from within
470 // the module constructor.
471 if (F.getName() == kTsanModuleCtorName)
472 return false;
473 // Naked functions can not have prologue/epilogue
474 // (__tsan_func_entry/__tsan_func_exit) generated, so don't instrument them at
475 // all.
476 if (F.hasFnAttribute(Attribute::Naked))
477 return false;
478
479 // __attribute__(disable_sanitizer_instrumentation) prevents all kinds of
480 // instrumentation.
481 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
482 return false;
483
484 initialize(*F.getParent(), TLI);
485 SmallVector<InstructionInfo, 8> AllLoadsAndStores;
486 SmallVector<Instruction*, 8> LocalLoadsAndStores;
487 SmallVector<Instruction*, 8> AtomicAccesses;
488 SmallVector<Instruction*, 8> MemIntrinCalls;
489 bool Res = false;
490 bool HasCalls = false;
491 bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);
492 const DataLayout &DL = F.getDataLayout();
493
494 // Traverse all instructions, collect loads/stores/returns, check for calls.
495 for (auto &BB : F) {
496 for (auto &Inst : BB) {
497 // Skip instructions inserted by another instrumentation.
498 if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
499 continue;
500 if (isTsanAtomic(&Inst))
501 AtomicAccesses.push_back(&Inst);
502 else if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
503 LocalLoadsAndStores.push_back(&Inst);
504 else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
505 if (CallInst *CI = dyn_cast<CallInst>(&Inst))
507 if (isa<MemIntrinsic>(Inst))
508 MemIntrinCalls.push_back(&Inst);
509 HasCalls = true;
510 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
511 DL);
512 }
513 }
514 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL);
515 }
516
517 // We have collected all loads and stores.
518 // FIXME: many of these accesses do not need to be checked for races
519 // (e.g. variables that do not escape, etc).
520
521 // Instrument memory accesses only if we want to report bugs in the function.
522 if (Opts.tsan_instrument_memory_accesses && SanitizeFunction)
523 for (const auto &II : AllLoadsAndStores) {
524 Res |= instrumentLoadOrStore(II, DL);
525 }
526
527 // Instrument atomic memory accesses in any case (they can be used to
528 // implement synchronization).
529 if (Opts.tsan_instrument_atomics)
530 for (auto *Inst : AtomicAccesses) {
531 Res |= instrumentAtomic(Inst, DL);
532 }
533
534 if (Opts.tsan_instrument_memintrinsics && SanitizeFunction)
535 for (auto *Inst : MemIntrinCalls) {
536 Res |= instrumentMemIntrinsic(Inst);
537 }
538
539 if (F.hasFnAttribute("sanitize_thread_no_checking_at_run_time")) {
540 assert(!F.hasFnAttribute(Attribute::SanitizeThread));
541 if (HasCalls)
542 InsertRuntimeIgnores(F);
543 }
544
545 // Instrument function entry/exit points if there were instrumented accesses.
546 if ((Res || HasCalls) && Opts.tsan_instrument_func_entry_exit) {
547 InstrumentationIRBuilder IRB(F.getEntryBlock().getFirstNonPHIIt());
548 auto ProgramAsPtrTy = PointerType::get(F.getParent()->getContext(),
549 DL.getProgramAddressSpace());
550 Value *ReturnAddress = IRB.CreateIntrinsic(
551 Intrinsic::returnaddress, {ProgramAsPtrTy}, IRB.getInt32(0));
552 IRB.CreateCall(TsanFuncEntry, ReturnAddress);
553
554 EscapeEnumerator EE(F, "tsan_cleanup", Opts.tsan_handle_cxx_exceptions);
555 while (IRBuilder<> *AtExit = EE.Next()) {
557 AtExit->CreateCall(TsanFuncExit, {});
558 }
559 Res = true;
560 }
561 return Res;
562}
563
564bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
565 const DataLayout &DL) {
567 const bool IsWrite = isa<StoreInst>(*II.Inst);
568 Value *Addr = IsWrite ? cast<StoreInst>(II.Inst)->getPointerOperand()
569 : cast<LoadInst>(II.Inst)->getPointerOperand();
570 Type *OrigTy = getLoadStoreType(II.Inst);
571
572 // swifterror memory addresses are mem2reg promoted by instruction selection.
573 // As such they cannot have regular uses like an instrumentation function and
574 // it makes no sense to track them as memory.
575 if (Addr->isSwiftError())
576 return false;
577
578 int Idx = getMemoryAccessFuncIndex(OrigTy, Addr, DL);
579 if (Idx < 0)
580 return false;
581 if (IsWrite && isVtableAccess(II.Inst)) {
582 LLVM_DEBUG(dbgs() << " VPTR : " << *II.Inst << "\n");
583 Value *StoredValue = cast<StoreInst>(II.Inst)->getValueOperand();
584 // StoredValue may be a vector type if we are storing several vptrs at once.
585 // In this case, just take the first element of the vector since this is
586 // enough to find vptr races.
587 if (isa<VectorType>(StoredValue->getType()))
588 StoredValue = IRB.CreateExtractElement(
589 StoredValue, ConstantInt::get(IRB.getInt32Ty(), 0));
590 if (StoredValue->getType()->isIntegerTy())
591 StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getPtrTy());
592 // Call TsanVptrUpdate.
593 IRB.CreateCall(TsanVptrUpdate, {Addr, StoredValue});
594 NumInstrumentedVtableWrites++;
595 return true;
596 }
597 if (!IsWrite && isVtableAccess(II.Inst)) {
598 IRB.CreateCall(TsanVptrLoad, Addr);
599 NumInstrumentedVtableReads++;
600 return true;
601 }
602
603 const Align Alignment = IsWrite ? cast<StoreInst>(II.Inst)->getAlign()
604 : cast<LoadInst>(II.Inst)->getAlign();
605 const bool IsCompoundRW = Opts.tsan_compound_read_before_write &&
606 (II.Flags & InstructionInfo::kCompoundRW);
607 const bool IsVolatile = Opts.tsan_distinguish_volatile &&
608 (IsWrite ? cast<StoreInst>(II.Inst)->isVolatile()
609 : cast<LoadInst>(II.Inst)->isVolatile());
610 assert((!IsVolatile || !IsCompoundRW) && "Compound volatile invalid!");
611
612 const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
613 FunctionCallee OnAccessFunc = nullptr;
614 if (Alignment >= Align(8) || (Alignment.value() % (TypeSize / 8)) == 0) {
615 if (IsCompoundRW)
616 OnAccessFunc = TsanCompoundRW[Idx];
617 else if (IsVolatile)
618 OnAccessFunc = IsWrite ? TsanVolatileWrite[Idx] : TsanVolatileRead[Idx];
619 else
620 OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
621 } else {
622 if (IsCompoundRW)
623 OnAccessFunc = TsanUnalignedCompoundRW[Idx];
624 else if (IsVolatile)
625 OnAccessFunc = IsWrite ? TsanUnalignedVolatileWrite[Idx]
626 : TsanUnalignedVolatileRead[Idx];
627 else
628 OnAccessFunc = IsWrite ? TsanUnalignedWrite[Idx] : TsanUnalignedRead[Idx];
629 }
630 IRB.CreateCall(OnAccessFunc, Addr);
631 if (IsCompoundRW || IsWrite)
632 NumInstrumentedWrites++;
633 if (IsCompoundRW || !IsWrite)
634 NumInstrumentedReads++;
635 return true;
636}
637
639 uint32_t v = 0;
640 switch (ord) {
642 llvm_unreachable("unexpected atomic ordering!");
643 case AtomicOrdering::Unordered: [[fallthrough]];
644 case AtomicOrdering::Monotonic: v = 0; break;
645 // Not specified yet:
646 // case AtomicOrdering::Consume: v = 1; break;
647 case AtomicOrdering::Acquire: v = 2; break;
648 case AtomicOrdering::Release: v = 3; break;
649 case AtomicOrdering::AcquireRelease: v = 4; break;
651 }
652 return IRB->getInt32(v);
653}
654
655// If a memset intrinsic gets inlined by the code gen, we will miss races on it.
656// So, we either need to ensure the intrinsic is not inlined, or instrument it.
657// We do not instrument memset/memmove/memcpy intrinsics (too complicated),
658// instead we simply replace them with regular function calls, which are then
659// intercepted by the run-time.
660// Since tsan is running after everyone else, the calls should not be
661// replaced back with intrinsics. If that becomes wrong at some point,
662// we will need to call e.g. __tsan_memset to avoid the intrinsics.
663bool ThreadSanitizer::instrumentMemIntrinsic(Instruction *I) {
666 Value *Cast1 = IRB.CreateIntCast(M->getArgOperand(1), IRB.getInt32Ty(), false);
667 Value *Cast2 = IRB.CreateIntCast(M->getArgOperand(2), IntptrTy, false);
668 IRB.CreateCall(
669 MemsetFn,
670 {M->getArgOperand(0),
671 Cast1,
672 Cast2});
673 I->eraseFromParent();
675 IRB.CreateCall(
676 isa<MemCpyInst>(M) ? MemcpyFn : MemmoveFn,
677 {M->getArgOperand(0),
678 M->getArgOperand(1),
679 IRB.CreateIntCast(M->getArgOperand(2), IntptrTy, false)});
680 I->eraseFromParent();
681 }
682 return false;
683}
684
685// Both llvm and ThreadSanitizer atomic operations are based on C++11/C1x
686// standards. For background see C++11 standard. A slightly older, publicly
687// available draft of the standard (not entirely up-to-date, but close enough
688// for casual browsing) is available here:
689// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
690// The following page contains more background information:
691// http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/
692
693bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) {
695 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
696 Value *Addr = LI->getPointerOperand();
697 Type *OrigTy = LI->getType();
698 int Idx = getMemoryAccessFuncIndex(OrigTy, Addr, DL);
699 if (Idx < 0)
700 return false;
701 Value *Args[] = {Addr,
702 createOrdering(&IRB, LI->getOrdering())};
703 Value *C = IRB.CreateCall(TsanAtomicLoad[Idx], Args);
704 Value *Cast = IRB.CreateBitOrPointerCast(C, OrigTy);
705 I->replaceAllUsesWith(Cast);
706 I->eraseFromParent();
707 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
708 Value *Addr = SI->getPointerOperand();
709 int Idx =
710 getMemoryAccessFuncIndex(SI->getValueOperand()->getType(), Addr, DL);
711 if (Idx < 0)
712 return false;
713 const unsigned ByteSize = 1U << Idx;
714 const unsigned BitSize = ByteSize * 8;
715 Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
716 Value *Args[] = {Addr,
717 IRB.CreateBitOrPointerCast(SI->getValueOperand(), Ty),
718 createOrdering(&IRB, SI->getOrdering())};
719 IRB.CreateCall(TsanAtomicStore[Idx], Args);
720 SI->eraseFromParent();
721 } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
722 Value *Addr = RMWI->getPointerOperand();
723 int Idx =
724 getMemoryAccessFuncIndex(RMWI->getValOperand()->getType(), Addr, DL);
725 if (Idx < 0)
726 return false;
727 FunctionCallee F = TsanAtomicRMW[RMWI->getOperation()][Idx];
728 if (!F)
729 return false;
730 const unsigned ByteSize = 1U << Idx;
731 const unsigned BitSize = ByteSize * 8;
732 Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
733 Value *Val = RMWI->getValOperand();
734 Value *Args[] = {Addr, IRB.CreateBitOrPointerCast(Val, Ty),
735 createOrdering(&IRB, RMWI->getOrdering())};
736 Value *C = IRB.CreateCall(F, Args);
737 I->replaceAllUsesWith(IRB.CreateBitOrPointerCast(C, Val->getType()));
738 I->eraseFromParent();
739 } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
740 Value *Addr = CASI->getPointerOperand();
741 Type *OrigOldValTy = CASI->getNewValOperand()->getType();
742 int Idx = getMemoryAccessFuncIndex(OrigOldValTy, Addr, DL);
743 if (Idx < 0)
744 return false;
745 const unsigned ByteSize = 1U << Idx;
746 const unsigned BitSize = ByteSize * 8;
747 Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
748 Value *CmpOperand =
749 IRB.CreateBitOrPointerCast(CASI->getCompareOperand(), Ty);
750 Value *NewOperand =
751 IRB.CreateBitOrPointerCast(CASI->getNewValOperand(), Ty);
752 Value *Args[] = {Addr,
753 CmpOperand,
754 NewOperand,
755 createOrdering(&IRB, CASI->getSuccessOrdering()),
756 createOrdering(&IRB, CASI->getFailureOrdering())};
757 CallInst *C = IRB.CreateCall(TsanAtomicCAS[Idx], Args);
758 Value *Success = IRB.CreateICmpEQ(C, CmpOperand);
759 Value *OldVal = C;
760 if (Ty != OrigOldValTy) {
761 // The value is a pointer, so we need to cast the return value.
762 OldVal = IRB.CreateIntToPtr(C, OrigOldValTy);
763 }
764
765 Value *Res =
766 IRB.CreateInsertValue(PoisonValue::get(CASI->getType()), OldVal, 0);
767 Res = IRB.CreateInsertValue(Res, Success, 1);
768
769 I->replaceAllUsesWith(Res);
770 I->eraseFromParent();
771 } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
772 Value *Args[] = {createOrdering(&IRB, FI->getOrdering())};
773 FunctionCallee F = FI->getSyncScopeID() == SyncScope::SingleThread
774 ? TsanAtomicSignalFence
775 : TsanAtomicThreadFence;
776 IRB.CreateCall(F, Args);
777 FI->eraseFromParent();
778 }
779 return true;
780}
781
782int ThreadSanitizer::getMemoryAccessFuncIndex(Type *OrigTy, Value *Addr,
783 const DataLayout &DL) {
784 assert(OrigTy->isSized());
785 if (OrigTy->isScalableTy()) {
786 // FIXME: support vscale.
787 return -1;
788 }
789 uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
790 if (TypeSize != 8 && TypeSize != 16 &&
791 TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
792 NumAccessesWithBadSize++;
793 // Ignore all unusual sizes.
794 return -1;
795 }
796 size_t Idx = llvm::countr_zero(TypeSize / 8);
798 return Idx;
799}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const size_t kNumberOfAccessSizes
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static bool insertModuleCtor(Module &M)
Definition CopyProf.cpp:77
This file defines the DenseMap class.
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for metadata subclasses.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file defines the SmallString class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr)
static bool isVtableAccess(Instruction *I)
static bool isTsanAtomic(const Instruction *I)
const char kTsanModuleCtorName[]
static ConstantInt * createOrdering(IRBuilder<> *IRB, AtomicOrdering ord)
const char kTsanInitName[]
an instruction to allocate memory on the stack
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
@ Add
*p = old + v
@ Sub
*p = old - v
@ And
*p = old & v
@ Xor
*p = old ^ v
@ Nand
*p = ~(old & v)
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:767
iterator end()
Definition DenseMap.h:687
EscapeEnumerator - This is a little algorithm to find all escape points from a function so that "fina...
An instruction for ordering other memory operations.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:474
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2918
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:71
An instruction for reading from memory.
Metadata node.
Definition Metadata.h:1081
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVM_ABI const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
Definition Value.cpp:828
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
Definition Value.cpp:1164
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char IsVolatile[]
Key for Kernel::Arg::Metadata::mIsVolatile.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:58
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
std::optional< SyncScope::ID > getAtomicSyncScopeID(const Instruction *I)
A helper function that returns an atomic operation's sync scope; returns std::nullopt if it is not an...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition Local.cpp:3893
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static void ensureDebugInfo(IRBuilder<> &IRB, const Function &F)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)