LLVM  16.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 
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/Statistic.h"
27 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/IR/DataLayout.h"
32 #include "llvm/IR/Function.h"
33 #include "llvm/IR/IRBuilder.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/IntrinsicInst.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"
43 #include "llvm/Support/Debug.h"
51 
52 using namespace llvm;
53 
54 #define DEBUG_TYPE "tsan"
55 
57  "tsan-instrument-memory-accesses", cl::init(true),
58  cl::desc("Instrument memory accesses"), cl::Hidden);
59 static cl::opt<bool>
60  ClInstrumentFuncEntryExit("tsan-instrument-func-entry-exit", cl::init(true),
61  cl::desc("Instrument function entry and exit"),
62  cl::Hidden);
64  "tsan-handle-cxx-exceptions", cl::init(true),
65  cl::desc("Handle C++ exceptions (insert cleanup blocks for unwinding)"),
66  cl::Hidden);
67 static cl::opt<bool> ClInstrumentAtomics("tsan-instrument-atomics",
68  cl::init(true),
69  cl::desc("Instrument atomics"),
70  cl::Hidden);
72  "tsan-instrument-memintrinsics", cl::init(true),
73  cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden);
75  "tsan-distinguish-volatile", cl::init(false),
76  cl::desc("Emit special instrumentation for accesses to volatiles"),
77  cl::Hidden);
79  "tsan-instrument-read-before-write", cl::init(false),
80  cl::desc("Do not eliminate read instrumentation for read-before-writes"),
81  cl::Hidden);
83  "tsan-compound-read-before-write", cl::init(false),
84  cl::desc("Emit special compound instrumentation for reads-before-writes"),
85  cl::Hidden);
86 
87 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
88 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
89 STATISTIC(NumOmittedReadsBeforeWrite,
90  "Number of reads ignored due to following writes");
91 STATISTIC(NumAccessesWithBadSize, "Number of accesses with bad size");
92 STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
93 STATISTIC(NumInstrumentedVtableReads, "Number of vtable ptr reads");
94 STATISTIC(NumOmittedReadsFromConstantGlobals,
95  "Number of reads from constant globals");
96 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
97 STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
98 
99 const char kTsanModuleCtorName[] = "tsan.module_ctor";
100 const char kTsanInitName[] = "__tsan_init";
101 
102 namespace {
103 
104 /// ThreadSanitizer: instrument the code in module to find races.
105 ///
106 /// Instantiating ThreadSanitizer inserts the tsan runtime library API function
107 /// declarations into the module if they don't exist already. Instantiating
108 /// ensures the __tsan_init function is in the list of global constructors for
109 /// the module.
110 struct ThreadSanitizer {
111  ThreadSanitizer() {
112  // Check options and warn user.
114  errs()
115  << "warning: Option -tsan-compound-read-before-write has no effect "
116  "when -tsan-instrument-read-before-write is set.\n";
117  }
118  }
119 
120  bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
121 
122 private:
123  // Internal Instruction wrapper that contains more information about the
124  // Instruction from prior analysis.
125  struct InstructionInfo {
126  // Instrumentation emitted for this instruction is for a compounded set of
127  // read and write operations in the same basic block.
128  static constexpr unsigned kCompoundRW = (1U << 0);
129 
130  explicit InstructionInfo(Instruction *Inst) : Inst(Inst) {}
131 
132  Instruction *Inst;
133  unsigned Flags = 0;
134  };
135 
136  void initialize(Module &M);
137  bool instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL);
138  bool instrumentAtomic(Instruction *I, const DataLayout &DL);
139  bool instrumentMemIntrinsic(Instruction *I);
140  void chooseInstructionsToInstrument(SmallVectorImpl<Instruction *> &Local,
142  const DataLayout &DL);
143  bool addrPointsToConstantData(Value *Addr);
144  int getMemoryAccessFuncIndex(Type *OrigTy, Value *Addr, const DataLayout &DL);
145  void InsertRuntimeIgnores(Function &F);
146 
147  Type *IntptrTy;
148  FunctionCallee TsanFuncEntry;
149  FunctionCallee TsanFuncExit;
150  FunctionCallee TsanIgnoreBegin;
151  FunctionCallee TsanIgnoreEnd;
152  // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
153  static const size_t kNumberOfAccessSizes = 5;
156  FunctionCallee TsanUnalignedRead[kNumberOfAccessSizes];
157  FunctionCallee TsanUnalignedWrite[kNumberOfAccessSizes];
158  FunctionCallee TsanVolatileRead[kNumberOfAccessSizes];
159  FunctionCallee TsanVolatileWrite[kNumberOfAccessSizes];
160  FunctionCallee TsanUnalignedVolatileRead[kNumberOfAccessSizes];
161  FunctionCallee TsanUnalignedVolatileWrite[kNumberOfAccessSizes];
162  FunctionCallee TsanCompoundRW[kNumberOfAccessSizes];
163  FunctionCallee TsanUnalignedCompoundRW[kNumberOfAccessSizes];
164  FunctionCallee TsanAtomicLoad[kNumberOfAccessSizes];
165  FunctionCallee TsanAtomicStore[kNumberOfAccessSizes];
166  FunctionCallee TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1]
168  FunctionCallee TsanAtomicCAS[kNumberOfAccessSizes];
169  FunctionCallee TsanAtomicThreadFence;
170  FunctionCallee TsanAtomicSignalFence;
171  FunctionCallee TsanVptrUpdate;
172  FunctionCallee TsanVptrLoad;
173  FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
174 };
175 
176 void insertModuleCtor(Module &M) {
178  M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
179  /*InitArgs=*/{},
180  // This callback is invoked when the functions are created the first
181  // time. Hook them into the global ctors list in that case:
182  [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); });
183 }
184 } // namespace
185 
188  ThreadSanitizer TSan;
189  if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
190  return PreservedAnalyses::none();
191  return PreservedAnalyses::all();
192 }
193 
196  insertModuleCtor(M);
197  return PreservedAnalyses::none();
198 }
200  const DataLayout &DL = M.getDataLayout();
201  IntptrTy = DL.getIntPtrType(M.getContext());
202 
203  IRBuilder<> IRB(M.getContext());
204  AttributeList Attr;
205  Attr = Attr.addFnAttribute(M.getContext(), Attribute::NoUnwind);
206  // Initialize the callbacks.
207  TsanFuncEntry = M.getOrInsertFunction("__tsan_func_entry", Attr,
208  IRB.getVoidTy(), IRB.getInt8PtrTy());
209  TsanFuncExit =
210  M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy());
211  TsanIgnoreBegin = M.getOrInsertFunction("__tsan_ignore_thread_begin", Attr,
212  IRB.getVoidTy());
213  TsanIgnoreEnd =
214  M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
215  IntegerType *OrdTy = IRB.getInt32Ty();
216  for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
217  const unsigned ByteSize = 1U << i;
218  const unsigned BitSize = ByteSize * 8;
219  std::string ByteSizeStr = utostr(ByteSize);
220  std::string BitSizeStr = utostr(BitSize);
221  SmallString<32> ReadName("__tsan_read" + ByteSizeStr);
222  TsanRead[i] = M.getOrInsertFunction(ReadName, Attr, IRB.getVoidTy(),
223  IRB.getInt8PtrTy());
224 
225  SmallString<32> WriteName("__tsan_write" + ByteSizeStr);
226  TsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(),
227  IRB.getInt8PtrTy());
228 
229  SmallString<64> UnalignedReadName("__tsan_unaligned_read" + ByteSizeStr);
230  TsanUnalignedRead[i] = M.getOrInsertFunction(
231  UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
232 
233  SmallString<64> UnalignedWriteName("__tsan_unaligned_write" + ByteSizeStr);
234  TsanUnalignedWrite[i] = M.getOrInsertFunction(
235  UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
236 
237  SmallString<64> VolatileReadName("__tsan_volatile_read" + ByteSizeStr);
238  TsanVolatileRead[i] = M.getOrInsertFunction(
239  VolatileReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
240 
241  SmallString<64> VolatileWriteName("__tsan_volatile_write" + ByteSizeStr);
242  TsanVolatileWrite[i] = M.getOrInsertFunction(
243  VolatileWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
244 
245  SmallString<64> UnalignedVolatileReadName("__tsan_unaligned_volatile_read" +
246  ByteSizeStr);
247  TsanUnalignedVolatileRead[i] = M.getOrInsertFunction(
248  UnalignedVolatileReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
249 
250  SmallString<64> UnalignedVolatileWriteName(
251  "__tsan_unaligned_volatile_write" + ByteSizeStr);
252  TsanUnalignedVolatileWrite[i] = M.getOrInsertFunction(
253  UnalignedVolatileWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
254 
255  SmallString<64> CompoundRWName("__tsan_read_write" + ByteSizeStr);
256  TsanCompoundRW[i] = M.getOrInsertFunction(
257  CompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
258 
259  SmallString<64> UnalignedCompoundRWName("__tsan_unaligned_read_write" +
260  ByteSizeStr);
261  TsanUnalignedCompoundRW[i] = M.getOrInsertFunction(
262  UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
263 
264  Type *Ty = Type::getIntNTy(M.getContext(), BitSize);
265  Type *PtrTy = Ty->getPointerTo();
266  SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load");
267  {
268  AttributeList AL = Attr;
269  AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
270  TsanAtomicLoad[i] =
271  M.getOrInsertFunction(AtomicLoadName, AL, Ty, PtrTy, OrdTy);
272  }
273 
274  SmallString<32> AtomicStoreName("__tsan_atomic" + BitSizeStr + "_store");
275  {
276  AttributeList AL = Attr;
277  AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
278  AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt);
279  TsanAtomicStore[i] = M.getOrInsertFunction(
280  AtomicStoreName, AL, IRB.getVoidTy(), PtrTy, Ty, OrdTy);
281  }
282 
283  for (unsigned Op = AtomicRMWInst::FIRST_BINOP;
285  TsanAtomicRMW[Op][i] = nullptr;
286  const char *NamePart = nullptr;
287  if (Op == AtomicRMWInst::Xchg)
288  NamePart = "_exchange";
289  else if (Op == AtomicRMWInst::Add)
290  NamePart = "_fetch_add";
291  else if (Op == AtomicRMWInst::Sub)
292  NamePart = "_fetch_sub";
293  else if (Op == AtomicRMWInst::And)
294  NamePart = "_fetch_and";
295  else if (Op == AtomicRMWInst::Or)
296  NamePart = "_fetch_or";
297  else if (Op == AtomicRMWInst::Xor)
298  NamePart = "_fetch_xor";
299  else if (Op == AtomicRMWInst::Nand)
300  NamePart = "_fetch_nand";
301  else
302  continue;
303  SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart);
304  {
305  AttributeList AL = Attr;
306  AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
307  AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt);
308  TsanAtomicRMW[Op][i] =
309  M.getOrInsertFunction(RMWName, AL, Ty, PtrTy, Ty, OrdTy);
310  }
311  }
312 
313  SmallString<32> AtomicCASName("__tsan_atomic" + BitSizeStr +
314  "_compare_exchange_val");
315  {
316  AttributeList AL = Attr;
317  AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
318  AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt);
319  AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt);
320  AL = AL.addParamAttribute(M.getContext(), 4, Attribute::ZExt);
321  TsanAtomicCAS[i] = M.getOrInsertFunction(AtomicCASName, AL, Ty, PtrTy, Ty,
322  Ty, OrdTy, OrdTy);
323  }
324  }
325  TsanVptrUpdate =
326  M.getOrInsertFunction("__tsan_vptr_update", Attr, IRB.getVoidTy(),
327  IRB.getInt8PtrTy(), IRB.getInt8PtrTy());
328  TsanVptrLoad = M.getOrInsertFunction("__tsan_vptr_read", Attr,
329  IRB.getVoidTy(), IRB.getInt8PtrTy());
330  {
331  AttributeList AL = Attr;
332  AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
333  TsanAtomicThreadFence = M.getOrInsertFunction("__tsan_atomic_thread_fence",
334  AL, IRB.getVoidTy(), OrdTy);
335  }
336  {
337  AttributeList AL = Attr;
338  AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
339  TsanAtomicSignalFence = M.getOrInsertFunction("__tsan_atomic_signal_fence",
340  AL, IRB.getVoidTy(), OrdTy);
341  }
342 
343  MemmoveFn =
344  M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(),
345  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
346  MemcpyFn =
347  M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(),
348  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
349  MemsetFn =
350  M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(),
351  IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy);
352 }
353 
354 static bool isVtableAccess(Instruction *I) {
355  if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
356  return Tag->isTBAAVtableAccess();
357  return false;
358 }
359 
360 // Do not instrument known races/"benign races" that come from compiler
361 // instrumentatin. The user has no way of suppressing them.
363  // Peel off GEPs and BitCasts.
364  Addr = Addr->stripInBoundsOffsets();
365 
366  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
367  if (GV->hasSection()) {
368  StringRef SectionName = GV->getSection();
369  // Check if the global is in the PGO counters section.
370  auto OF = Triple(M->getTargetTriple()).getObjectFormat();
371  if (SectionName.endswith(
372  getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false)))
373  return false;
374  }
375 
376  // Check if the global is private gcov data.
377  if (GV->getName().startswith("__llvm_gcov") ||
378  GV->getName().startswith("__llvm_gcda"))
379  return false;
380  }
381 
382  // Do not instrument accesses from different address spaces; we cannot deal
383  // with them.
384  if (Addr) {
385  Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
386  if (PtrTy->getPointerAddressSpace() != 0)
387  return false;
388  }
389 
390  return true;
391 }
392 
393 bool ThreadSanitizer::addrPointsToConstantData(Value *Addr) {
394  // If this is a GEP, just analyze its pointer operand.
395  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Addr))
396  Addr = GEP->getPointerOperand();
397 
398  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
399  if (GV->isConstant()) {
400  // Reads from constant globals can not race with any writes.
401  NumOmittedReadsFromConstantGlobals++;
402  return true;
403  }
404  } else if (LoadInst *L = dyn_cast<LoadInst>(Addr)) {
405  if (isVtableAccess(L)) {
406  // Reads from a vtable pointer can not race with any writes.
407  NumOmittedReadsFromVtable++;
408  return true;
409  }
410  }
411  return false;
412 }
413 
414 // Instrumenting some of the accesses may be proven redundant.
415 // Currently handled:
416 // - read-before-write (within same BB, no calls between)
417 // - not captured variables
418 //
419 // We do not handle some of the patterns that should not survive
420 // after the classic compiler optimizations.
421 // E.g. two reads from the same temp should be eliminated by CSE,
422 // two writes should be eliminated by DSE, etc.
423 //
424 // 'Local' is a vector of insns within the same BB (no calls between).
425 // 'All' is a vector of insns that will be instrumented.
426 void ThreadSanitizer::chooseInstructionsToInstrument(
429  DenseMap<Value *, size_t> WriteTargets; // Map of addresses to index in All
430  // Iterate from the end.
431  for (Instruction *I : reverse(Local)) {
432  const bool IsWrite = isa<StoreInst>(*I);
433  Value *Addr = IsWrite ? cast<StoreInst>(I)->getPointerOperand()
434  : cast<LoadInst>(I)->getPointerOperand();
435 
436  if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr))
437  continue;
438 
439  if (!IsWrite) {
440  const auto WriteEntry = WriteTargets.find(Addr);
441  if (!ClInstrumentReadBeforeWrite && WriteEntry != WriteTargets.end()) {
442  auto &WI = All[WriteEntry->second];
443  // If we distinguish volatile accesses and if either the read or write
444  // is volatile, do not omit any instrumentation.
445  const bool AnyVolatile =
446  ClDistinguishVolatile && (cast<LoadInst>(I)->isVolatile() ||
447  cast<StoreInst>(WI.Inst)->isVolatile());
448  if (!AnyVolatile) {
449  // We will write to this temp, so no reason to analyze the read.
450  // Mark the write instruction as compound.
451  WI.Flags |= InstructionInfo::kCompoundRW;
452  NumOmittedReadsBeforeWrite++;
453  continue;
454  }
455  }
456 
457  if (addrPointsToConstantData(Addr)) {
458  // Addr points to some constant data -- it can not race with any writes.
459  continue;
460  }
461  }
462 
463  if (isa<AllocaInst>(getUnderlyingObject(Addr)) &&
464  !PointerMayBeCaptured(Addr, true, true)) {
465  // The variable is addressable but not captured, so it cannot be
466  // referenced from a different thread and participate in a data race
467  // (see llvm/Analysis/CaptureTracking.h for details).
468  NumOmittedNonCaptured++;
469  continue;
470  }
471 
472  // Instrument this instruction.
473  All.emplace_back(I);
474  if (IsWrite) {
475  // For read-before-write and compound instrumentation we only need one
476  // write target, and we can override any previous entry if it exists.
477  WriteTargets[Addr] = All.size() - 1;
478  }
479  }
480  Local.clear();
481 }
482 
483 static bool isTsanAtomic(const Instruction *I) {
484  // TODO: Ask TTI whether synchronization scope is between threads.
485  auto SSID = getAtomicSyncScopeID(I);
486  if (!SSID)
487  return false;
488  if (isa<LoadInst>(I) || isa<StoreInst>(I))
489  return SSID.value() != SyncScope::SingleThread;
490  return true;
491 }
492 
493 void ThreadSanitizer::InsertRuntimeIgnores(Function &F) {
494  InstrumentationIRBuilder IRB(F.getEntryBlock().getFirstNonPHI());
495  IRB.CreateCall(TsanIgnoreBegin);
496  EscapeEnumerator EE(F, "tsan_ignore_cleanup", ClHandleCxxExceptions);
497  while (IRBuilder<> *AtExit = EE.Next()) {
499  AtExit->CreateCall(TsanIgnoreEnd);
500  }
501 }
502 
503 bool ThreadSanitizer::sanitizeFunction(Function &F,
504  const TargetLibraryInfo &TLI) {
505  // This is required to prevent instrumenting call to __tsan_init from within
506  // the module constructor.
507  if (F.getName() == kTsanModuleCtorName)
508  return false;
509  // Naked functions can not have prologue/epilogue
510  // (__tsan_func_entry/__tsan_func_exit) generated, so don't instrument them at
511  // all.
512  if (F.hasFnAttribute(Attribute::Naked))
513  return false;
514 
515  // __attribute__(disable_sanitizer_instrumentation) prevents all kinds of
516  // instrumentation.
517  if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
518  return false;
519 
520  initialize(*F.getParent());
521  SmallVector<InstructionInfo, 8> AllLoadsAndStores;
522  SmallVector<Instruction*, 8> LocalLoadsAndStores;
523  SmallVector<Instruction*, 8> AtomicAccesses;
524  SmallVector<Instruction*, 8> MemIntrinCalls;
525  bool Res = false;
526  bool HasCalls = false;
527  bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);
528  const DataLayout &DL = F.getParent()->getDataLayout();
529 
530  // Traverse all instructions, collect loads/stores/returns, check for calls.
531  for (auto &BB : F) {
532  for (auto &Inst : BB) {
533  if (isTsanAtomic(&Inst))
534  AtomicAccesses.push_back(&Inst);
535  else if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
536  LocalLoadsAndStores.push_back(&Inst);
537  else if ((isa<CallInst>(Inst) && !isa<DbgInfoIntrinsic>(Inst)) ||
538  isa<InvokeInst>(Inst)) {
539  if (CallInst *CI = dyn_cast<CallInst>(&Inst))
541  if (isa<MemIntrinsic>(Inst))
542  MemIntrinCalls.push_back(&Inst);
543  HasCalls = true;
544  chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
545  DL);
546  }
547  }
548  chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL);
549  }
550 
551  // We have collected all loads and stores.
552  // FIXME: many of these accesses do not need to be checked for races
553  // (e.g. variables that do not escape, etc).
554 
555  // Instrument memory accesses only if we want to report bugs in the function.
556  if (ClInstrumentMemoryAccesses && SanitizeFunction)
557  for (const auto &II : AllLoadsAndStores) {
558  Res |= instrumentLoadOrStore(II, DL);
559  }
560 
561  // Instrument atomic memory accesses in any case (they can be used to
562  // implement synchronization).
564  for (auto *Inst : AtomicAccesses) {
565  Res |= instrumentAtomic(Inst, DL);
566  }
567 
568  if (ClInstrumentMemIntrinsics && SanitizeFunction)
569  for (auto *Inst : MemIntrinCalls) {
570  Res |= instrumentMemIntrinsic(Inst);
571  }
572 
573  if (F.hasFnAttribute("sanitize_thread_no_checking_at_run_time")) {
574  assert(!F.hasFnAttribute(Attribute::SanitizeThread));
575  if (HasCalls)
576  InsertRuntimeIgnores(F);
577  }
578 
579  // Instrument function entry/exit points if there were instrumented accesses.
580  if ((Res || HasCalls) && ClInstrumentFuncEntryExit) {
581  InstrumentationIRBuilder IRB(F.getEntryBlock().getFirstNonPHI());
582  Value *ReturnAddress = IRB.CreateCall(
583  Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress),
584  IRB.getInt32(0));
585  IRB.CreateCall(TsanFuncEntry, ReturnAddress);
586 
587  EscapeEnumerator EE(F, "tsan_cleanup", ClHandleCxxExceptions);
588  while (IRBuilder<> *AtExit = EE.Next()) {
590  AtExit->CreateCall(TsanFuncExit, {});
591  }
592  Res = true;
593  }
594  return Res;
595 }
596 
597 bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
598  const DataLayout &DL) {
599  InstrumentationIRBuilder IRB(II.Inst);
600  const bool IsWrite = isa<StoreInst>(*II.Inst);
601  Value *Addr = IsWrite ? cast<StoreInst>(II.Inst)->getPointerOperand()
602  : cast<LoadInst>(II.Inst)->getPointerOperand();
603  Type *OrigTy = getLoadStoreType(II.Inst);
604 
605  // swifterror memory addresses are mem2reg promoted by instruction selection.
606  // As such they cannot have regular uses like an instrumentation function and
607  // it makes no sense to track them as memory.
608  if (Addr->isSwiftError())
609  return false;
610 
611  int Idx = getMemoryAccessFuncIndex(OrigTy, Addr, DL);
612  if (Idx < 0)
613  return false;
614  if (IsWrite && isVtableAccess(II.Inst)) {
615  LLVM_DEBUG(dbgs() << " VPTR : " << *II.Inst << "\n");
616  Value *StoredValue = cast<StoreInst>(II.Inst)->getValueOperand();
617  // StoredValue may be a vector type if we are storing several vptrs at once.
618  // In this case, just take the first element of the vector since this is
619  // enough to find vptr races.
620  if (isa<VectorType>(StoredValue->getType()))
621  StoredValue = IRB.CreateExtractElement(
622  StoredValue, ConstantInt::get(IRB.getInt32Ty(), 0));
623  if (StoredValue->getType()->isIntegerTy())
624  StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getInt8PtrTy());
625  // Call TsanVptrUpdate.
626  IRB.CreateCall(TsanVptrUpdate,
627  {IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
628  IRB.CreatePointerCast(StoredValue, IRB.getInt8PtrTy())});
629  NumInstrumentedVtableWrites++;
630  return true;
631  }
632  if (!IsWrite && isVtableAccess(II.Inst)) {
633  IRB.CreateCall(TsanVptrLoad,
634  IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
635  NumInstrumentedVtableReads++;
636  return true;
637  }
638 
639  const Align Alignment = IsWrite ? cast<StoreInst>(II.Inst)->getAlign()
640  : cast<LoadInst>(II.Inst)->getAlign();
641  const bool IsCompoundRW =
642  ClCompoundReadBeforeWrite && (II.Flags & InstructionInfo::kCompoundRW);
643  const bool IsVolatile = ClDistinguishVolatile &&
644  (IsWrite ? cast<StoreInst>(II.Inst)->isVolatile()
645  : cast<LoadInst>(II.Inst)->isVolatile());
646  assert((!IsVolatile || !IsCompoundRW) && "Compound volatile invalid!");
647 
648  const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
649  FunctionCallee OnAccessFunc = nullptr;
650  if (Alignment >= Align(8) || (Alignment.value() % (TypeSize / 8)) == 0) {
651  if (IsCompoundRW)
652  OnAccessFunc = TsanCompoundRW[Idx];
653  else if (IsVolatile)
654  OnAccessFunc = IsWrite ? TsanVolatileWrite[Idx] : TsanVolatileRead[Idx];
655  else
656  OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
657  } else {
658  if (IsCompoundRW)
659  OnAccessFunc = TsanUnalignedCompoundRW[Idx];
660  else if (IsVolatile)
661  OnAccessFunc = IsWrite ? TsanUnalignedVolatileWrite[Idx]
662  : TsanUnalignedVolatileRead[Idx];
663  else
664  OnAccessFunc = IsWrite ? TsanUnalignedWrite[Idx] : TsanUnalignedRead[Idx];
665  }
666  IRB.CreateCall(OnAccessFunc, IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
667  if (IsCompoundRW || IsWrite)
668  NumInstrumentedWrites++;
669  if (IsCompoundRW || !IsWrite)
670  NumInstrumentedReads++;
671  return true;
672 }
673 
675  uint32_t v = 0;
676  switch (ord) {
678  llvm_unreachable("unexpected atomic ordering!");
679  case AtomicOrdering::Unordered: [[fallthrough]];
680  case AtomicOrdering::Monotonic: v = 0; break;
681  // Not specified yet:
682  // case AtomicOrdering::Consume: v = 1; break;
683  case AtomicOrdering::Acquire: v = 2; break;
684  case AtomicOrdering::Release: v = 3; break;
685  case AtomicOrdering::AcquireRelease: v = 4; break;
686  case AtomicOrdering::SequentiallyConsistent: v = 5; break;
687  }
688  return IRB->getInt32(v);
689 }
690 
691 // If a memset intrinsic gets inlined by the code gen, we will miss races on it.
692 // So, we either need to ensure the intrinsic is not inlined, or instrument it.
693 // We do not instrument memset/memmove/memcpy intrinsics (too complicated),
694 // instead we simply replace them with regular function calls, which are then
695 // intercepted by the run-time.
696 // Since tsan is running after everyone else, the calls should not be
697 // replaced back with intrinsics. If that becomes wrong at some point,
698 // we will need to call e.g. __tsan_memset to avoid the intrinsics.
699 bool ThreadSanitizer::instrumentMemIntrinsic(Instruction *I) {
700  IRBuilder<> IRB(I);
701  if (MemSetInst *M = dyn_cast<MemSetInst>(I)) {
702  IRB.CreateCall(
703  MemsetFn,
704  {IRB.CreatePointerCast(M->getArgOperand(0), IRB.getInt8PtrTy()),
705  IRB.CreateIntCast(M->getArgOperand(1), IRB.getInt32Ty(), false),
706  IRB.CreateIntCast(M->getArgOperand(2), IntptrTy, false)});
707  I->eraseFromParent();
708  } else if (MemTransferInst *M = dyn_cast<MemTransferInst>(I)) {
709  IRB.CreateCall(
710  isa<MemCpyInst>(M) ? MemcpyFn : MemmoveFn,
711  {IRB.CreatePointerCast(M->getArgOperand(0), IRB.getInt8PtrTy()),
712  IRB.CreatePointerCast(M->getArgOperand(1), IRB.getInt8PtrTy()),
713  IRB.CreateIntCast(M->getArgOperand(2), IntptrTy, false)});
714  I->eraseFromParent();
715  }
716  return false;
717 }
718 
719 // Both llvm and ThreadSanitizer atomic operations are based on C++11/C1x
720 // standards. For background see C++11 standard. A slightly older, publicly
721 // available draft of the standard (not entirely up-to-date, but close enough
722 // for casual browsing) is available here:
723 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
724 // The following page contains more background information:
725 // http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/
726 
727 bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) {
729  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
730  Value *Addr = LI->getPointerOperand();
731  Type *OrigTy = LI->getType();
732  int Idx = getMemoryAccessFuncIndex(OrigTy, Addr, DL);
733  if (Idx < 0)
734  return false;
735  const unsigned ByteSize = 1U << Idx;
736  const unsigned BitSize = ByteSize * 8;
737  Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
738  Type *PtrTy = Ty->getPointerTo();
739  Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
740  createOrdering(&IRB, LI->getOrdering())};
741  Value *C = IRB.CreateCall(TsanAtomicLoad[Idx], Args);
742  Value *Cast = IRB.CreateBitOrPointerCast(C, OrigTy);
743  I->replaceAllUsesWith(Cast);
744  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
745  Value *Addr = SI->getPointerOperand();
746  int Idx =
747  getMemoryAccessFuncIndex(SI->getValueOperand()->getType(), Addr, DL);
748  if (Idx < 0)
749  return false;
750  const unsigned ByteSize = 1U << Idx;
751  const unsigned BitSize = ByteSize * 8;
752  Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
753  Type *PtrTy = Ty->getPointerTo();
754  Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
755  IRB.CreateBitOrPointerCast(SI->getValueOperand(), Ty),
756  createOrdering(&IRB, SI->getOrdering())};
757  CallInst *C = CallInst::Create(TsanAtomicStore[Idx], Args);
759  } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
760  Value *Addr = RMWI->getPointerOperand();
761  int Idx =
762  getMemoryAccessFuncIndex(RMWI->getValOperand()->getType(), Addr, DL);
763  if (Idx < 0)
764  return false;
765  FunctionCallee F = TsanAtomicRMW[RMWI->getOperation()][Idx];
766  if (!F)
767  return false;
768  const unsigned ByteSize = 1U << Idx;
769  const unsigned BitSize = ByteSize * 8;
770  Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
771  Type *PtrTy = Ty->getPointerTo();
772  Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
773  IRB.CreateIntCast(RMWI->getValOperand(), Ty, false),
774  createOrdering(&IRB, RMWI->getOrdering())};
777  } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
778  Value *Addr = CASI->getPointerOperand();
779  Type *OrigOldValTy = CASI->getNewValOperand()->getType();
780  int Idx = getMemoryAccessFuncIndex(OrigOldValTy, Addr, DL);
781  if (Idx < 0)
782  return false;
783  const unsigned ByteSize = 1U << Idx;
784  const unsigned BitSize = ByteSize * 8;
785  Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
786  Type *PtrTy = Ty->getPointerTo();
787  Value *CmpOperand =
788  IRB.CreateBitOrPointerCast(CASI->getCompareOperand(), Ty);
789  Value *NewOperand =
790  IRB.CreateBitOrPointerCast(CASI->getNewValOperand(), Ty);
791  Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
792  CmpOperand,
793  NewOperand,
794  createOrdering(&IRB, CASI->getSuccessOrdering()),
795  createOrdering(&IRB, CASI->getFailureOrdering())};
796  CallInst *C = IRB.CreateCall(TsanAtomicCAS[Idx], Args);
797  Value *Success = IRB.CreateICmpEQ(C, CmpOperand);
798  Value *OldVal = C;
799  if (Ty != OrigOldValTy) {
800  // The value is a pointer, so we need to cast the return value.
801  OldVal = IRB.CreateIntToPtr(C, OrigOldValTy);
802  }
803 
804  Value *Res =
805  IRB.CreateInsertValue(UndefValue::get(CASI->getType()), OldVal, 0);
806  Res = IRB.CreateInsertValue(Res, Success, 1);
807 
808  I->replaceAllUsesWith(Res);
809  I->eraseFromParent();
810  } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
811  Value *Args[] = {createOrdering(&IRB, FI->getOrdering())};
812  FunctionCallee F = FI->getSyncScopeID() == SyncScope::SingleThread
813  ? TsanAtomicSignalFence
814  : TsanAtomicThreadFence;
817  }
818  return true;
819 }
820 
821 int ThreadSanitizer::getMemoryAccessFuncIndex(Type *OrigTy, Value *Addr,
822  const DataLayout &DL) {
823  assert(OrigTy->isSized());
824  assert(
825  cast<PointerType>(Addr->getType())->isOpaqueOrPointeeTypeMatches(OrigTy));
826  uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
827  if (TypeSize != 8 && TypeSize != 16 &&
828  TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
829  NumAccessesWithBadSize++;
830  // Ignore all unusual sizes.
831  return -1;
832  }
833  size_t Idx = countTrailingZeros(TypeSize / 8);
835  return Idx;
836 }
i
i
Definition: README.txt:29
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
Instrumentation.h
llvm::AtomicOrdering::AcquireRelease
@ AcquireRelease
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:269
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::AArch64CC::AL
@ AL
Definition: AArch64BaseInfo.h:269
Optional.h
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1421
Metadata.h
IntrinsicInst.h
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:778
llvm::EscapeEnumerator
EscapeEnumerator - This is a little algorithm to find all escape points from a function so that "fina...
Definition: EscapeEnumerator.h:29
ThreadSanitizer.h
llvm::MemTransferInst
This class wraps the llvm.memcpy/memmove intrinsics.
Definition: IntrinsicInst.h:1026
llvm::Function
Definition: Function.h:60
kNumberOfAccessSizes
static const size_t kNumberOfAccessSizes
Definition: AddressSanitizer.cpp:177
llvm::AtomicRMWInst::Xor
@ Xor
*p = old ^ v
Definition: Instructions.h:741
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1183
Statistic.h
CaptureTracking.h
llvm::Type::getPointerAddressSpace
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:729
llvm::IRBuilder<>
llvm::GlobalVariable
Definition: GlobalVariable.h:39
ValueTracking.h
Local.h
llvm::AtomicOrdering::SequentiallyConsistent
@ SequentiallyConsistent
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
llvm::getLoadStoreType
Type * getLoadStoreType(Value *I)
A helper function that returns the type of a load or store instruction.
Definition: Instructions.h:5373
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
Module.h
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:381
llvm::AttributeList
Definition: Attributes.h:425
llvm::FenceInst
An instruction for ordering other memory operations.
Definition: Instructions.h:433
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
initialize
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Definition: TargetLibraryInfo.cpp:150
llvm::AtomicRMWInst::FIRST_BINOP
@ FIRST_BINOP
Definition: Instructions.h:765
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
HasCalls
@ HasCalls
Definition: AArch64InstrInfo.cpp:6932
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::AtomicOrdering::Monotonic
@ Monotonic
kTsanModuleCtorName
const char kTsanModuleCtorName[]
Definition: ThreadSanitizer.cpp:99
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
CommandLine.h
llvm::getOrCreateSanitizerCtorAndInitFunctions
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())
Creates sanitizer constructor function lazily.
Definition: ModuleUtils.cpp:157
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
createOrdering
static ConstantInt * createOrdering(IRBuilder<> *IRB, AtomicOrdering ord)
Definition: ThreadSanitizer.cpp:674
SmallString.h
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::CallInst::Create
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:1517
llvm::ReplaceInstWithInst
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
Definition: BasicBlockUtils.cpp:478
TargetLibraryInfo.h
shouldInstrumentReadWriteFromAddress
static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr)
Definition: ThreadSanitizer.cpp:362
llvm::ModuleThreadSanitizerPass::run
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition: ThreadSanitizer.cpp:194
llvm::IntegerType
Class to represent integer types.
Definition: DerivedTypes.h:40
llvm::InstrumentationIRBuilder
Definition: Instrumentation.h:184
llvm::Instruction
Definition: Instruction.h:42
InstrProf.h
llvm::AtomicOrdering::Acquire
@ Acquire
llvm::Triple::getObjectFormat
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition: Triple.h:371
llvm::AtomicRMWInst::Nand
@ Nand
*p = ~(old & v)
Definition: Instructions.h:737
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1710
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:879
llvm::getUnderlyingObject
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
Definition: ValueTracking.cpp:4487
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
ClInstrumentAtomics
static cl::opt< bool > ClInstrumentAtomics("tsan-instrument-atomics", cl::init(true), cl::desc("Instrument atomics"), cl::Hidden)
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::AtomicRMWInst::Xchg
@ Xchg
*p = v
Definition: Instructions.h:729
llvm::AtomicRMWInst::Add
@ Add
*p = old + v
Definition: Instructions.h:731
Type.h
llvm::MemSetInst
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
Definition: IntrinsicInst.h:993
ClInstrumentReadBeforeWrite
static cl::opt< bool > ClInstrumentReadBeforeWrite("tsan-instrument-read-before-write", cl::init(false), cl::desc("Do not eliminate read instrumentation for read-before-writes"), cl::Hidden)
llvm::SmallString< 32 >
ClInstrumentMemIntrinsics
static cl::opt< bool > ClInstrumentMemIntrinsics("tsan-instrument-memintrinsics", cl::init(true), cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden)
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:196
llvm::AtomicOrdering
AtomicOrdering
Atomic ordering for LLVM's memory model.
Definition: AtomicOrdering.h:56
llvm::cl::opt< bool >
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:298
isTsanAtomic
static bool isTsanAtomic(const Instruction *I)
Definition: ThreadSanitizer.cpp:483
llvm::AtomicRMWInst::Sub
@ Sub
*p = old - v
Definition: Instructions.h:733
llvm::ThreadSanitizerPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Definition: ThreadSanitizer.cpp:186
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
llvm::IRBuilderBase::getInt32
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:461
llvm::DenseMap
Definition: DenseMap.h:714
llvm::AtomicOrdering::Unordered
@ Unordered
I
#define I(x, y, z)
Definition: MD5.cpp:58
StringExtras.h
llvm::GetElementPtrInst
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:929
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:439
llvm::AtomicRMWInst::Or
@ Or
*p = old | v
Definition: Instructions.h:739
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI
StandardInstrumentations SI(Debug, VerifyEach)
ClCompoundReadBeforeWrite
static cl::opt< bool > ClCompoundReadBeforeWrite("tsan-compound-read-before-write", cl::init(false), cl::desc("Emit special compound instrumentation for reads-before-writes"), cl::Hidden)
ClInstrumentMemoryAccesses
static cl::opt< bool > ClInstrumentMemoryAccesses("tsan-instrument-memory-accesses", cl::init(true), cl::desc("Instrument memory accesses"), cl::Hidden)
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MDNode
Metadata node.
Definition: Metadata.h:944
llvm::PointerMayBeCaptured
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
Definition: CaptureTracking.cpp:229
DataLayout.h
llvm::countTrailingZeros
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:152
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
ClInstrumentFuncEntryExit
static cl::opt< bool > ClInstrumentFuncEntryExit("tsan-instrument-func-entry-exit", cl::init(true), cl::desc("Instrument function entry and exit"), cl::Hidden)
uint32_t
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::SyncScope::SingleThread
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:54
llvm::maybeMarkSanitizerLibraryCallNoBuiltin
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:3258
llvm::AMDGPU::HSAMD::Kernel::Arg::Key::IsVolatile
constexpr char IsVolatile[]
Key for Kernel::Arg::Metadata::mIsVolatile.
Definition: AMDGPUMetadata.h:199
ClHandleCxxExceptions
static cl::opt< bool > ClHandleCxxExceptions("tsan-handle-cxx-exceptions", cl::init(true), cl::desc("Handle C++ exceptions (insert cleanup blocks for unwinding)"), cl::Hidden)
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:715
llvm::pdb::PDB_DataKind::Local
@ Local
llvm::AtomicOrdering::Release
@ Release
llvm::MachO::All
@ All
Definition: InterfaceFile.h:69
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition: Type.cpp:243
llvm::AttributeList::addFnAttribute
AttributeList addFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add a function attribute to the list.
Definition: Attributes.h:512
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:84
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::Align::value
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
llvm::SectionName
Definition: DWARFSection.h:21
Success
#define Success
Definition: AArch64Disassembler.cpp:280
llvm::AtomicRMWInst::And
@ And
*p = old & v
Definition: Instructions.h:735
llvm::TypeSize
Definition: TypeSize.h:435
Function.h
llvm::Type::getPointerTo
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:774
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:222
llvm::getAtomicSyncScopeID
Optional< SyncScope::ID > getAtomicSyncScopeID(const Instruction *I)
A helper function that returns an atomic operation's sync scope; returns None if it is not an atomic ...
Definition: Instructions.h:5383
ClDistinguishVolatile
static cl::opt< bool > ClDistinguishVolatile("tsan-distinguish-volatile", cl::init(false), cl::desc("Emit special instrumentation for accesses to volatiles"), cl::Hidden)
llvm::getInstrProfSectionName
std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
Definition: InstrProf.cpp:212
llvm::InstrumentationIRBuilder::ensureDebugInfo
static void ensureDebugInfo(IRBuilder<> &IRB, const Function &F)
Definition: Instrumentation.h:185
Instructions.h
SmallVector.h
ModuleUtils.h
EscapeEnumerator.h
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::SmallVectorImpl< Instruction * >
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1474
llvm::AtomicRMWInst::LAST_BINOP
@ LAST_BINOP
Definition: Instructions.h:766
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:171
LLVMContext.h
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::appendToGlobalCtors
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.
Definition: ModuleUtils.cpp:65
llvm::cl::desc
Definition: CommandLine.h:412
isVtableAccess
static bool isVtableAccess(Instruction *I)
Definition: ThreadSanitizer.cpp:354
raw_ostream.h
BasicBlockUtils.h
kTsanInitName
const char kTsanInitName[]
Definition: ThreadSanitizer.cpp:100
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:510
Debug.h
llvm::TargetLibraryAnalysis
Analysis pass providing the TargetLibraryInfo.
Definition: TargetLibraryInfo.h:443
llvm::AtomicOrdering::NotAtomic
@ NotAtomic