Home | History | Annotate | Download | only in Instrumentation
      1 //===-- ThreadSanitizer.cpp - race detector -------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of ThreadSanitizer, a race detector.
     11 //
     12 // The tool is under development, for the details about previous versions see
     13 // http://code.google.com/p/data-race-test
     14 //
     15 // The instrumentation phase is quite simple:
     16 //   - Insert calls to run-time library before every memory access.
     17 //      - Optimizations may apply to avoid instrumenting some of the accesses.
     18 //   - Insert calls at function entry/exit.
     19 // The rest is handled by the run-time library.
     20 //===----------------------------------------------------------------------===//
     21 
     22 #define DEBUG_TYPE "tsan"
     23 
     24 #include "llvm/Transforms/Instrumentation.h"
     25 #include "llvm/ADT/SmallSet.h"
     26 #include "llvm/ADT/SmallString.h"
     27 #include "llvm/ADT/SmallVector.h"
     28 #include "llvm/ADT/Statistic.h"
     29 #include "llvm/ADT/StringExtras.h"
     30 #include "llvm/IR/DataLayout.h"
     31 #include "llvm/IR/Function.h"
     32 #include "llvm/IR/IRBuilder.h"
     33 #include "llvm/IR/Intrinsics.h"
     34 #include "llvm/IR/LLVMContext.h"
     35 #include "llvm/IR/Metadata.h"
     36 #include "llvm/IR/Module.h"
     37 #include "llvm/IR/Type.h"
     38 #include "llvm/Support/CommandLine.h"
     39 #include "llvm/Support/Debug.h"
     40 #include "llvm/Support/MathExtras.h"
     41 #include "llvm/Support/raw_ostream.h"
     42 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
     43 #include "llvm/Transforms/Utils/BlackList.h"
     44 #include "llvm/Transforms/Utils/ModuleUtils.h"
     45 
     46 using namespace llvm;
     47 
     48 static cl::opt<std::string>  ClBlacklistFile("tsan-blacklist",
     49        cl::desc("Blacklist file"), cl::Hidden);
     50 static cl::opt<bool>  ClInstrumentMemoryAccesses(
     51     "tsan-instrument-memory-accesses", cl::init(true),
     52     cl::desc("Instrument memory accesses"), cl::Hidden);
     53 static cl::opt<bool>  ClInstrumentFuncEntryExit(
     54     "tsan-instrument-func-entry-exit", cl::init(true),
     55     cl::desc("Instrument function entry and exit"), cl::Hidden);
     56 static cl::opt<bool>  ClInstrumentAtomics(
     57     "tsan-instrument-atomics", cl::init(true),
     58     cl::desc("Instrument atomics"), cl::Hidden);
     59 
     60 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
     61 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
     62 STATISTIC(NumOmittedReadsBeforeWrite,
     63           "Number of reads ignored due to following writes");
     64 STATISTIC(NumAccessesWithBadSize, "Number of accesses with bad size");
     65 STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
     66 STATISTIC(NumOmittedReadsFromConstantGlobals,
     67           "Number of reads from constant globals");
     68 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
     69 
     70 namespace {
     71 
     72 /// ThreadSanitizer: instrument the code in module to find races.
     73 struct ThreadSanitizer : public FunctionPass {
     74   ThreadSanitizer(StringRef BlacklistFile = StringRef())
     75       : FunctionPass(ID),
     76         TD(0),
     77         BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile
     78                                             : BlacklistFile) { }
     79   const char *getPassName() const;
     80   bool runOnFunction(Function &F);
     81   bool doInitialization(Module &M);
     82   static char ID;  // Pass identification, replacement for typeid.
     83 
     84  private:
     85   void initializeCallbacks(Module &M);
     86   bool instrumentLoadOrStore(Instruction *I);
     87   bool instrumentAtomic(Instruction *I);
     88   void chooseInstructionsToInstrument(SmallVectorImpl<Instruction*> &Local,
     89                                       SmallVectorImpl<Instruction*> &All);
     90   bool addrPointsToConstantData(Value *Addr);
     91   int getMemoryAccessFuncIndex(Value *Addr);
     92 
     93   DataLayout *TD;
     94   SmallString<64> BlacklistFile;
     95   OwningPtr<BlackList> BL;
     96   IntegerType *OrdTy;
     97   // Callbacks to run-time library are computed in doInitialization.
     98   Function *TsanFuncEntry;
     99   Function *TsanFuncExit;
    100   // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
    101   static const size_t kNumberOfAccessSizes = 5;
    102   Function *TsanRead[kNumberOfAccessSizes];
    103   Function *TsanWrite[kNumberOfAccessSizes];
    104   Function *TsanAtomicLoad[kNumberOfAccessSizes];
    105   Function *TsanAtomicStore[kNumberOfAccessSizes];
    106   Function *TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][kNumberOfAccessSizes];
    107   Function *TsanAtomicCAS[kNumberOfAccessSizes];
    108   Function *TsanAtomicThreadFence;
    109   Function *TsanAtomicSignalFence;
    110   Function *TsanVptrUpdate;
    111 };
    112 }  // namespace
    113 
    114 char ThreadSanitizer::ID = 0;
    115 INITIALIZE_PASS(ThreadSanitizer, "tsan",
    116     "ThreadSanitizer: detects data races.",
    117     false, false)
    118 
    119 const char *ThreadSanitizer::getPassName() const {
    120   return "ThreadSanitizer";
    121 }
    122 
    123 FunctionPass *llvm::createThreadSanitizerPass(StringRef BlacklistFile) {
    124   return new ThreadSanitizer(BlacklistFile);
    125 }
    126 
    127 static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
    128   if (Function *F = dyn_cast<Function>(FuncOrBitcast))
    129      return F;
    130   FuncOrBitcast->dump();
    131   report_fatal_error("ThreadSanitizer interface function redefined");
    132 }
    133 
    134 void ThreadSanitizer::initializeCallbacks(Module &M) {
    135   IRBuilder<> IRB(M.getContext());
    136   // Initialize the callbacks.
    137   TsanFuncEntry = checkInterfaceFunction(M.getOrInsertFunction(
    138       "__tsan_func_entry", IRB.getVoidTy(), IRB.getInt8PtrTy(), NULL));
    139   TsanFuncExit = checkInterfaceFunction(M.getOrInsertFunction(
    140       "__tsan_func_exit", IRB.getVoidTy(), NULL));
    141   OrdTy = IRB.getInt32Ty();
    142   for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
    143     const size_t ByteSize = 1 << i;
    144     const size_t BitSize = ByteSize * 8;
    145     SmallString<32> ReadName("__tsan_read" + itostr(ByteSize));
    146     TsanRead[i] = checkInterfaceFunction(M.getOrInsertFunction(
    147         ReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), NULL));
    148 
    149     SmallString<32> WriteName("__tsan_write" + itostr(ByteSize));
    150     TsanWrite[i] = checkInterfaceFunction(M.getOrInsertFunction(
    151         WriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), NULL));
    152 
    153     Type *Ty = Type::getIntNTy(M.getContext(), BitSize);
    154     Type *PtrTy = Ty->getPointerTo();
    155     SmallString<32> AtomicLoadName("__tsan_atomic" + itostr(BitSize) +
    156                                    "_load");
    157     TsanAtomicLoad[i] = checkInterfaceFunction(M.getOrInsertFunction(
    158         AtomicLoadName, Ty, PtrTy, OrdTy, NULL));
    159 
    160     SmallString<32> AtomicStoreName("__tsan_atomic" + itostr(BitSize) +
    161                                     "_store");
    162     TsanAtomicStore[i] = checkInterfaceFunction(M.getOrInsertFunction(
    163         AtomicStoreName, IRB.getVoidTy(), PtrTy, Ty, OrdTy,
    164         NULL));
    165 
    166     for (int op = AtomicRMWInst::FIRST_BINOP;
    167         op <= AtomicRMWInst::LAST_BINOP; ++op) {
    168       TsanAtomicRMW[op][i] = NULL;
    169       const char *NamePart = NULL;
    170       if (op == AtomicRMWInst::Xchg)
    171         NamePart = "_exchange";
    172       else if (op == AtomicRMWInst::Add)
    173         NamePart = "_fetch_add";
    174       else if (op == AtomicRMWInst::Sub)
    175         NamePart = "_fetch_sub";
    176       else if (op == AtomicRMWInst::And)
    177         NamePart = "_fetch_and";
    178       else if (op == AtomicRMWInst::Or)
    179         NamePart = "_fetch_or";
    180       else if (op == AtomicRMWInst::Xor)
    181         NamePart = "_fetch_xor";
    182       else if (op == AtomicRMWInst::Nand)
    183         NamePart = "_fetch_nand";
    184       else
    185         continue;
    186       SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart);
    187       TsanAtomicRMW[op][i] = checkInterfaceFunction(M.getOrInsertFunction(
    188           RMWName, Ty, PtrTy, Ty, OrdTy, NULL));
    189     }
    190 
    191     SmallString<32> AtomicCASName("__tsan_atomic" + itostr(BitSize) +
    192                                   "_compare_exchange_val");
    193     TsanAtomicCAS[i] = checkInterfaceFunction(M.getOrInsertFunction(
    194         AtomicCASName, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy, NULL));
    195   }
    196   TsanVptrUpdate = checkInterfaceFunction(M.getOrInsertFunction(
    197       "__tsan_vptr_update", IRB.getVoidTy(), IRB.getInt8PtrTy(),
    198       IRB.getInt8PtrTy(), NULL));
    199   TsanAtomicThreadFence = checkInterfaceFunction(M.getOrInsertFunction(
    200       "__tsan_atomic_thread_fence", IRB.getVoidTy(), OrdTy, NULL));
    201   TsanAtomicSignalFence = checkInterfaceFunction(M.getOrInsertFunction(
    202       "__tsan_atomic_signal_fence", IRB.getVoidTy(), OrdTy, NULL));
    203 }
    204 
    205 bool ThreadSanitizer::doInitialization(Module &M) {
    206   TD = getAnalysisIfAvailable<DataLayout>();
    207   if (!TD)
    208     return false;
    209   BL.reset(new BlackList(BlacklistFile));
    210 
    211   // Always insert a call to __tsan_init into the module's CTORs.
    212   IRBuilder<> IRB(M.getContext());
    213   Value *TsanInit = M.getOrInsertFunction("__tsan_init",
    214                                           IRB.getVoidTy(), NULL);
    215   appendToGlobalCtors(M, cast<Function>(TsanInit), 0);
    216 
    217   return true;
    218 }
    219 
    220 static bool isVtableAccess(Instruction *I) {
    221   if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa)) {
    222     if (Tag->getNumOperands() < 1) return false;
    223     if (MDString *Tag1 = dyn_cast<MDString>(Tag->getOperand(0))) {
    224       if (Tag1->getString() == "vtable pointer") return true;
    225     }
    226   }
    227   return false;
    228 }
    229 
    230 bool ThreadSanitizer::addrPointsToConstantData(Value *Addr) {
    231   // If this is a GEP, just analyze its pointer operand.
    232   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Addr))
    233     Addr = GEP->getPointerOperand();
    234 
    235   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
    236     if (GV->isConstant()) {
    237       // Reads from constant globals can not race with any writes.
    238       NumOmittedReadsFromConstantGlobals++;
    239       return true;
    240     }
    241   } else if (LoadInst *L = dyn_cast<LoadInst>(Addr)) {
    242     if (isVtableAccess(L)) {
    243       // Reads from a vtable pointer can not race with any writes.
    244       NumOmittedReadsFromVtable++;
    245       return true;
    246     }
    247   }
    248   return false;
    249 }
    250 
    251 // Instrumenting some of the accesses may be proven redundant.
    252 // Currently handled:
    253 //  - read-before-write (within same BB, no calls between)
    254 //
    255 // We do not handle some of the patterns that should not survive
    256 // after the classic compiler optimizations.
    257 // E.g. two reads from the same temp should be eliminated by CSE,
    258 // two writes should be eliminated by DSE, etc.
    259 //
    260 // 'Local' is a vector of insns within the same BB (no calls between).
    261 // 'All' is a vector of insns that will be instrumented.
    262 void ThreadSanitizer::chooseInstructionsToInstrument(
    263     SmallVectorImpl<Instruction*> &Local,
    264     SmallVectorImpl<Instruction*> &All) {
    265   SmallSet<Value*, 8> WriteTargets;
    266   // Iterate from the end.
    267   for (SmallVectorImpl<Instruction*>::reverse_iterator It = Local.rbegin(),
    268        E = Local.rend(); It != E; ++It) {
    269     Instruction *I = *It;
    270     if (StoreInst *Store = dyn_cast<StoreInst>(I)) {
    271       WriteTargets.insert(Store->getPointerOperand());
    272     } else {
    273       LoadInst *Load = cast<LoadInst>(I);
    274       Value *Addr = Load->getPointerOperand();
    275       if (WriteTargets.count(Addr)) {
    276         // We will write to this temp, so no reason to analyze the read.
    277         NumOmittedReadsBeforeWrite++;
    278         continue;
    279       }
    280       if (addrPointsToConstantData(Addr)) {
    281         // Addr points to some constant data -- it can not race with any writes.
    282         continue;
    283       }
    284     }
    285     All.push_back(I);
    286   }
    287   Local.clear();
    288 }
    289 
    290 static bool isAtomic(Instruction *I) {
    291   if (LoadInst *LI = dyn_cast<LoadInst>(I))
    292     return LI->isAtomic() && LI->getSynchScope() == CrossThread;
    293   if (StoreInst *SI = dyn_cast<StoreInst>(I))
    294     return SI->isAtomic() && SI->getSynchScope() == CrossThread;
    295   if (isa<AtomicRMWInst>(I))
    296     return true;
    297   if (isa<AtomicCmpXchgInst>(I))
    298     return true;
    299   if (isa<FenceInst>(I))
    300     return true;
    301   return false;
    302 }
    303 
    304 bool ThreadSanitizer::runOnFunction(Function &F) {
    305   if (!TD) return false;
    306   if (BL->isIn(F)) return false;
    307   initializeCallbacks(*F.getParent());
    308   SmallVector<Instruction*, 8> RetVec;
    309   SmallVector<Instruction*, 8> AllLoadsAndStores;
    310   SmallVector<Instruction*, 8> LocalLoadsAndStores;
    311   SmallVector<Instruction*, 8> AtomicAccesses;
    312   bool Res = false;
    313   bool HasCalls = false;
    314 
    315   // Traverse all instructions, collect loads/stores/returns, check for calls.
    316   for (Function::iterator FI = F.begin(), FE = F.end();
    317        FI != FE; ++FI) {
    318     BasicBlock &BB = *FI;
    319     for (BasicBlock::iterator BI = BB.begin(), BE = BB.end();
    320          BI != BE; ++BI) {
    321       if (isAtomic(BI))
    322         AtomicAccesses.push_back(BI);
    323       else if (isa<LoadInst>(BI) || isa<StoreInst>(BI))
    324         LocalLoadsAndStores.push_back(BI);
    325       else if (isa<ReturnInst>(BI))
    326         RetVec.push_back(BI);
    327       else if (isa<CallInst>(BI) || isa<InvokeInst>(BI)) {
    328         HasCalls = true;
    329         chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores);
    330       }
    331     }
    332     chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores);
    333   }
    334 
    335   // We have collected all loads and stores.
    336   // FIXME: many of these accesses do not need to be checked for races
    337   // (e.g. variables that do not escape, etc).
    338 
    339   // Instrument memory accesses.
    340   if (ClInstrumentMemoryAccesses)
    341     for (size_t i = 0, n = AllLoadsAndStores.size(); i < n; ++i) {
    342       Res |= instrumentLoadOrStore(AllLoadsAndStores[i]);
    343     }
    344 
    345   // Instrument atomic memory accesses.
    346   if (ClInstrumentAtomics)
    347     for (size_t i = 0, n = AtomicAccesses.size(); i < n; ++i) {
    348       Res |= instrumentAtomic(AtomicAccesses[i]);
    349     }
    350 
    351   // Instrument function entry/exit points if there were instrumented accesses.
    352   if ((Res || HasCalls) && ClInstrumentFuncEntryExit) {
    353     IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
    354     Value *ReturnAddress = IRB.CreateCall(
    355         Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress),
    356         IRB.getInt32(0));
    357     IRB.CreateCall(TsanFuncEntry, ReturnAddress);
    358     for (size_t i = 0, n = RetVec.size(); i < n; ++i) {
    359       IRBuilder<> IRBRet(RetVec[i]);
    360       IRBRet.CreateCall(TsanFuncExit);
    361     }
    362     Res = true;
    363   }
    364   return Res;
    365 }
    366 
    367 bool ThreadSanitizer::instrumentLoadOrStore(Instruction *I) {
    368   IRBuilder<> IRB(I);
    369   bool IsWrite = isa<StoreInst>(*I);
    370   Value *Addr = IsWrite
    371       ? cast<StoreInst>(I)->getPointerOperand()
    372       : cast<LoadInst>(I)->getPointerOperand();
    373   int Idx = getMemoryAccessFuncIndex(Addr);
    374   if (Idx < 0)
    375     return false;
    376   if (IsWrite && isVtableAccess(I)) {
    377     DEBUG(dbgs() << "  VPTR : " << *I << "\n");
    378     Value *StoredValue = cast<StoreInst>(I)->getValueOperand();
    379     // StoredValue does not necessary have a pointer type.
    380     if (isa<IntegerType>(StoredValue->getType()))
    381       StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getInt8PtrTy());
    382     // Call TsanVptrUpdate.
    383     IRB.CreateCall2(TsanVptrUpdate,
    384                     IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
    385                     IRB.CreatePointerCast(StoredValue, IRB.getInt8PtrTy()));
    386     NumInstrumentedVtableWrites++;
    387     return true;
    388   }
    389   Value *OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
    390   IRB.CreateCall(OnAccessFunc, IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
    391   if (IsWrite) NumInstrumentedWrites++;
    392   else         NumInstrumentedReads++;
    393   return true;
    394 }
    395 
    396 static ConstantInt *createOrdering(IRBuilder<> *IRB, AtomicOrdering ord) {
    397   uint32_t v = 0;
    398   switch (ord) {
    399     case NotAtomic:              assert(false);
    400     case Unordered:              // Fall-through.
    401     case Monotonic:              v = 0; break;
    402     // case Consume:                v = 1; break;  // Not specified yet.
    403     case Acquire:                v = 2; break;
    404     case Release:                v = 3; break;
    405     case AcquireRelease:         v = 4; break;
    406     case SequentiallyConsistent: v = 5; break;
    407   }
    408   return IRB->getInt32(v);
    409 }
    410 
    411 static ConstantInt *createFailOrdering(IRBuilder<> *IRB, AtomicOrdering ord) {
    412   uint32_t v = 0;
    413   switch (ord) {
    414     case NotAtomic:              assert(false);
    415     case Unordered:              // Fall-through.
    416     case Monotonic:              v = 0; break;
    417     // case Consume:                v = 1; break;  // Not specified yet.
    418     case Acquire:                v = 2; break;
    419     case Release:                v = 0; break;
    420     case AcquireRelease:         v = 2; break;
    421     case SequentiallyConsistent: v = 5; break;
    422   }
    423   return IRB->getInt32(v);
    424 }
    425 
    426 // Both llvm and ThreadSanitizer atomic operations are based on C++11/C1x
    427 // standards.  For background see C++11 standard.  A slightly older, publically
    428 // available draft of the standard (not entirely up-to-date, but close enough
    429 // for casual browsing) is available here:
    430 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
    431 // The following page contains more background information:
    432 // http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/
    433 
    434 bool ThreadSanitizer::instrumentAtomic(Instruction *I) {
    435   IRBuilder<> IRB(I);
    436   if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
    437     Value *Addr = LI->getPointerOperand();
    438     int Idx = getMemoryAccessFuncIndex(Addr);
    439     if (Idx < 0)
    440       return false;
    441     const size_t ByteSize = 1 << Idx;
    442     const size_t BitSize = ByteSize * 8;
    443     Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
    444     Type *PtrTy = Ty->getPointerTo();
    445     Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
    446                      createOrdering(&IRB, LI->getOrdering())};
    447     CallInst *C = CallInst::Create(TsanAtomicLoad[Idx],
    448                                    ArrayRef<Value*>(Args));
    449     ReplaceInstWithInst(I, C);
    450 
    451   } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
    452     Value *Addr = SI->getPointerOperand();
    453     int Idx = getMemoryAccessFuncIndex(Addr);
    454     if (Idx < 0)
    455       return false;
    456     const size_t ByteSize = 1 << Idx;
    457     const size_t BitSize = ByteSize * 8;
    458     Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
    459     Type *PtrTy = Ty->getPointerTo();
    460     Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
    461                      IRB.CreateIntCast(SI->getValueOperand(), Ty, false),
    462                      createOrdering(&IRB, SI->getOrdering())};
    463     CallInst *C = CallInst::Create(TsanAtomicStore[Idx],
    464                                    ArrayRef<Value*>(Args));
    465     ReplaceInstWithInst(I, C);
    466   } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
    467     Value *Addr = RMWI->getPointerOperand();
    468     int Idx = getMemoryAccessFuncIndex(Addr);
    469     if (Idx < 0)
    470       return false;
    471     Function *F = TsanAtomicRMW[RMWI->getOperation()][Idx];
    472     if (F == NULL)
    473       return false;
    474     const size_t ByteSize = 1 << Idx;
    475     const size_t BitSize = ByteSize * 8;
    476     Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
    477     Type *PtrTy = Ty->getPointerTo();
    478     Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
    479                      IRB.CreateIntCast(RMWI->getValOperand(), Ty, false),
    480                      createOrdering(&IRB, RMWI->getOrdering())};
    481     CallInst *C = CallInst::Create(F, ArrayRef<Value*>(Args));
    482     ReplaceInstWithInst(I, C);
    483   } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
    484     Value *Addr = CASI->getPointerOperand();
    485     int Idx = getMemoryAccessFuncIndex(Addr);
    486     if (Idx < 0)
    487       return false;
    488     const size_t ByteSize = 1 << Idx;
    489     const size_t BitSize = ByteSize * 8;
    490     Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
    491     Type *PtrTy = Ty->getPointerTo();
    492     Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
    493                      IRB.CreateIntCast(CASI->getCompareOperand(), Ty, false),
    494                      IRB.CreateIntCast(CASI->getNewValOperand(), Ty, false),
    495                      createOrdering(&IRB, CASI->getOrdering()),
    496                      createFailOrdering(&IRB, CASI->getOrdering())};
    497     CallInst *C = CallInst::Create(TsanAtomicCAS[Idx], ArrayRef<Value*>(Args));
    498     ReplaceInstWithInst(I, C);
    499   } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
    500     Value *Args[] = {createOrdering(&IRB, FI->getOrdering())};
    501     Function *F = FI->getSynchScope() == SingleThread ?
    502         TsanAtomicSignalFence : TsanAtomicThreadFence;
    503     CallInst *C = CallInst::Create(F, ArrayRef<Value*>(Args));
    504     ReplaceInstWithInst(I, C);
    505   }
    506   return true;
    507 }
    508 
    509 int ThreadSanitizer::getMemoryAccessFuncIndex(Value *Addr) {
    510   Type *OrigPtrTy = Addr->getType();
    511   Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
    512   assert(OrigTy->isSized());
    513   uint32_t TypeSize = TD->getTypeStoreSizeInBits(OrigTy);
    514   if (TypeSize != 8  && TypeSize != 16 &&
    515       TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
    516     NumAccessesWithBadSize++;
    517     // Ignore all unusual sizes.
    518     return -1;
    519   }
    520   size_t Idx = CountTrailingZeros_32(TypeSize / 8);
    521   assert(Idx < kNumberOfAccessSizes);
    522   return Idx;
    523 }
    524