revert to previous base llvm-svn.349610

Change-Id: Ibbe1931d087763e3fd973a6266aec9b6efa083c2
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index d20858f..f503d3e 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -1042,9 +1042,6 @@
 def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
                                  [IntrReadMem, IntrArgMemOnly]>;
 
-def int_hwasan_check_memaccess :
-  Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly]>;
-
 // Xray intrinsics
 //===----------------------------------------------------------------------===//
 // Custom event logging for x-ray.
diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp
index c35f866..392e8bc 100644
--- a/lib/CodeGen/CodeGenPrepare.cpp
+++ b/lib/CodeGen/CodeGenPrepare.cpp
@@ -5160,11 +5160,11 @@
       }
 
       // Generate a new GEP to replace the current one.
-      LLVMContext &Ctx = GEP->getContext();
+      IRBuilder<> Builder(GEP);
       Type *IntPtrTy = DL->getIntPtrType(GEP->getType());
       Type *I8PtrTy =
-          Type::getInt8PtrTy(Ctx, GEP->getType()->getPointerAddressSpace());
-      Type *I8Ty = Type::getInt8Ty(Ctx);
+          Builder.getInt8PtrTy(GEP->getType()->getPointerAddressSpace());
+      Type *I8Ty = Builder.getInt8Ty();
 
       if (!NewBaseGEP) {
         // Create a new base if we don't have one yet.  Find the insertion
@@ -5200,7 +5200,6 @@
         NewGEPBases.insert(NewBaseGEP);
       }
 
-      IRBuilder<> Builder(GEP);
       Value *NewGEP = NewBaseGEP;
       if (Offset == BaseOffset) {
         if (GEP->getType() != I8PtrTy)
diff --git a/lib/Linker/IRMover.cpp b/lib/Linker/IRMover.cpp
index c0e618c..afbc57a 100644
--- a/lib/Linker/IRMover.cpp
+++ b/lib/Linker/IRMover.cpp
@@ -240,18 +240,27 @@
   // These are types that LLVM itself will unique.
   bool IsUniqued = !isa<StructType>(Ty) || cast<StructType>(Ty)->isLiteral();
 
-#ifndef NDEBUG
   if (!IsUniqued) {
+    StructType *STy = cast<StructType>(Ty);
+    // This is actually a type from the destination module, this can be reached
+    // when this type is loaded in another module, added to DstStructTypesSet,
+    // and then we reach the same type in another module where it has not been
+    // added to MappedTypes. (PR37684)
+    if (STy->getContext().isODRUniquingDebugTypes() && !STy->isOpaque() &&
+        DstStructTypesSet.hasType(STy))
+      return *Entry = STy;
+
+#ifndef NDEBUG
     for (auto &Pair : MappedTypes) {
       assert(!(Pair.first != Ty && Pair.second == Ty) &&
              "mapping to a source type");
     }
-  }
 #endif
 
-  if (!IsUniqued && !Visited.insert(cast<StructType>(Ty)).second) {
-    StructType *DTy = StructType::create(Ty->getContext());
-    return *Entry = DTy;
+    if (!Visited.insert(STy).second) {
+      StructType *DTy = StructType::create(Ty->getContext());
+      return *Entry = DTy;
+    }
   }
 
   // If this is not a recursive type, then just map all of the elements and
diff --git a/lib/Target/AArch64/AArch64AsmPrinter.cpp b/lib/Target/AArch64/AArch64AsmPrinter.cpp
index c7c651f..828fbb2 100644
--- a/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -29,7 +29,6 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/COFF.h"
-#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -45,7 +44,6 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstBuilder.h"
-#include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/Casting.h"
@@ -98,10 +96,6 @@
   void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
   void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
 
-  std::map<std::pair<unsigned, uint32_t>, MCSymbol *> HwasanMemaccessSymbols;
-  void LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI);
-  void EmitHwasanMemaccessSymbols(Module &M);
-
   void EmitSled(const MachineInstr &MI, SledKind Kind);
 
   /// tblgen'erated driver function for lowering simple MI->MC
@@ -236,109 +230,7 @@
   recordSled(CurSled, MI, Kind);
 }
 
-void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
-  unsigned Reg = MI.getOperand(0).getReg();
-  uint32_t AccessInfo = MI.getOperand(1).getImm();
-  MCSymbol *&Sym = HwasanMemaccessSymbols[{Reg, AccessInfo}];
-  if (!Sym) {
-    // FIXME: Make this work on non-ELF.
-    if (!TM.getTargetTriple().isOSBinFormatELF())
-      report_fatal_error("llvm.hwasan.check.memaccess only supported on ELF");
-
-    std::string SymName = "__hwasan_check_x" + utostr(Reg - AArch64::X0) + "_" +
-                          utostr(AccessInfo);
-    Sym = OutContext.getOrCreateSymbol(SymName);
-  }
-
-  EmitToStreamer(*OutStreamer,
-                 MCInstBuilder(AArch64::BL)
-                     .addExpr(MCSymbolRefExpr::create(Sym, OutContext)));
-}
-
-void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
-  if (HwasanMemaccessSymbols.empty())
-    return;
-
-  const Triple &TT = TM.getTargetTriple();
-  assert(TT.isOSBinFormatELF());
-  std::unique_ptr<MCSubtargetInfo> STI(
-      TM.getTarget().createMCSubtargetInfo(TT.str(), "", ""));
-
-  MCSymbol *HwasanTagMismatchSym =
-      OutContext.getOrCreateSymbol("__hwasan_tag_mismatch");
-
-  for (auto &P : HwasanMemaccessSymbols) {
-    unsigned Reg = P.first.first;
-    uint32_t AccessInfo = P.first.second;
-    MCSymbol *Sym = P.second;
-
-    OutStreamer->SwitchSection(OutContext.getELFSection(
-        ".text.hot", ELF::SHT_PROGBITS,
-        ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0,
-        Sym->getName()));
-
-    OutStreamer->EmitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
-    OutStreamer->EmitSymbolAttribute(Sym, MCSA_Weak);
-    OutStreamer->EmitSymbolAttribute(Sym, MCSA_Hidden);
-    OutStreamer->EmitLabel(Sym);
-
-    OutStreamer->EmitInstruction(MCInstBuilder(AArch64::UBFMXri)
-                                     .addReg(AArch64::X16)
-                                     .addReg(Reg)
-                                     .addImm(4)
-                                     .addImm(55),
-                                 *STI);
-    OutStreamer->EmitInstruction(MCInstBuilder(AArch64::LDRBBroX)
-                                     .addReg(AArch64::W16)
-                                     .addReg(AArch64::X9)
-                                     .addReg(AArch64::X16)
-                                     .addImm(0)
-                                     .addImm(0),
-                                 *STI);
-    OutStreamer->EmitInstruction(MCInstBuilder(AArch64::UBFMXri)
-                                     .addReg(AArch64::X17)
-                                     .addReg(Reg)
-                                     .addImm(56)
-                                     .addImm(63),
-                                 *STI);
-    OutStreamer->EmitInstruction(MCInstBuilder(AArch64::SUBSWrs)
-                                     .addReg(AArch64::WZR)
-                                     .addReg(AArch64::W16)
-                                     .addReg(AArch64::W17)
-                                     .addImm(0),
-                                 *STI);
-    MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
-    OutStreamer->EmitInstruction(
-        MCInstBuilder(AArch64::Bcc)
-            .addImm(AArch64CC::NE)
-            .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
-        *STI);
-    OutStreamer->EmitInstruction(
-        MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI);
-
-    OutStreamer->EmitLabel(HandleMismatchSym);
-    if (Reg != AArch64::X0)
-      OutStreamer->EmitInstruction(MCInstBuilder(AArch64::ORRXrs)
-                                       .addReg(AArch64::X0)
-                                       .addReg(AArch64::XZR)
-                                       .addReg(Reg)
-                                       .addImm(0),
-                                   *STI);
-    OutStreamer->EmitInstruction(MCInstBuilder(AArch64::MOVZXi)
-                                     .addReg(AArch64::X1)
-                                     .addImm(AccessInfo)
-                                     .addImm(0),
-                                 *STI);
-    OutStreamer->EmitInstruction(
-        MCInstBuilder(AArch64::B)
-            .addExpr(MCSymbolRefExpr::create(HwasanTagMismatchSym, OutContext)),
-        *STI);
-  }
-}
-
 void AArch64AsmPrinter::EmitEndOfAsmFile(Module &M) {
-  EmitHwasanMemaccessSymbols(M);
-
   const Triple &TT = TM.getTargetTriple();
   if (TT.isOSBinFormatMachO()) {
     // Funny Darwin hack: This flag tells the linker that no global symbols
@@ -951,10 +843,6 @@
     LowerPATCHABLE_TAIL_CALL(*MI);
     return;
 
-  case AArch64::HWASAN_CHECK_MEMACCESS:
-    LowerHWASAN_CHECK_MEMACCESS(*MI);
-    return;
-
   case AArch64::SEH_StackAlloc:
     TS->EmitARM64WinCFIAllocStack(MI->getOperand(0).getImm());
     return;
diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td
index 9e9722e..ee43b55 100644
--- a/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/lib/Target/AArch64/AArch64InstrInfo.td
@@ -752,13 +752,6 @@
 def MOVbaseTLS : Pseudo<(outs GPR64:$dst), (ins),
                        [(set GPR64:$dst, AArch64threadpointer)]>, Sched<[WriteSys]>;
 
-let Uses = [ X9 ], Defs = [ X16, X17, LR, NZCV ] in {
-def HWASAN_CHECK_MEMACCESS : Pseudo<
-  (outs), (ins GPR64noip:$ptr, i32imm:$accessinfo),
-  [(int_hwasan_check_memaccess X9, GPR64noip:$ptr, (i32 imm:$accessinfo))]>,
-  Sched<[]>;
-}
-
 // The cycle counter PMC register is PMCCNTR_EL0.
 let Predicates = [HasPerfMon] in
 def : Pat<(readcyclecounter), (MRS 0xdce8)>;
diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
index 0e230e1..c497669 100644
--- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
+++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
@@ -249,9 +249,6 @@
   case AArch64::GPR64spRegClassID:
   case AArch64::GPR64sponlyRegClassID:
   case AArch64::GPR64allRegClassID:
-  case AArch64::GPR64noipRegClassID:
-  case AArch64::GPR64common_and_GPR64noipRegClassID:
-  case AArch64::GPR64noip_and_tcGPR64RegClassID:
   case AArch64::tcGPR64RegClassID:
   case AArch64::WSeqPairsClassRegClassID:
   case AArch64::XSeqPairsClassRegClassID:
diff --git a/lib/Target/AArch64/AArch64RegisterInfo.td b/lib/Target/AArch64/AArch64RegisterInfo.td
index 9729b14..d3710ce 100644
--- a/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -206,11 +206,6 @@
 // BTI-protected function.
 def rtcGPR64 : RegisterClass<"AArch64", [i64], 64, (add X16, X17)>;
 
-// Register set that excludes registers that are reserved for procedure calls.
-// This is used for pseudo-instructions that are actually implemented using a
-// procedure call.
-def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)>;
-
 // GPR register classes for post increment amount of vector load/store that
 // has alternate printing when Rm=31 and prints a constant immediate value
 // equal to the total number of bytes transferred.
diff --git a/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 837220c..042e8ea 100644
--- a/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -152,14 +152,6 @@
                               cl::desc("create static frame descriptions"),
                               cl::Hidden, cl::init(true));
 
-static cl::opt<bool> ClInlineAllChecks("hwasan-inline-all-checks",
-                                       cl::desc("inline all checks"),
-                                       cl::Hidden, cl::init(false));
-
-static cl::opt<bool> ClAllowIfunc("hwasan-allow-ifunc",
-                                  cl::desc("allow the use of ifunc"),
-                                  cl::Hidden, cl::init(false));
-
 namespace {
 
 /// An instrumentation pass implementing detection of addressability bugs
@@ -183,13 +175,11 @@
 
   void initializeCallbacks(Module &M);
 
-  Value *getDynamicShadowIfunc(IRBuilder<> &IRB);
   Value *getDynamicShadowNonTls(IRBuilder<> &IRB);
 
   void untagPointerOperand(Instruction *I, Value *Addr);
-  Value *shadowBase();
-  Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
-  void instrumentMemAccessInline(Value *Ptr, bool IsWrite,
+  Value *memToShadow(Value *Shadow, Type *Ty, IRBuilder<> &IRB);
+  void instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
                                  unsigned AccessSizeIndex,
                                  Instruction *InsertBefore);
   bool instrumentMemAccess(Instruction *I);
@@ -257,7 +247,6 @@
   Type *IntptrTy;
   Type *Int8PtrTy;
   Type *Int8Ty;
-  Type *Int32Ty;
 
   bool CompileKernel;
   bool Recover;
@@ -312,7 +301,6 @@
   IntptrTy = IRB.getIntPtrTy(DL);
   Int8PtrTy = IRB.getInt8PtrTy();
   Int8Ty = IRB.getInt8Ty();
-  Int32Ty = IRB.getInt32Ty();
 
   HwasanCtorFunction = nullptr;
   if (!CompileKernel) {
@@ -382,18 +370,9 @@
   HwasanGenerateTagFunc = checkSanitizerInterfaceFunction(
       M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty));
 
-  ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow",
-                                     ArrayType::get(IRB.getInt8Ty(), 0));
-}
-
-Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
-  // An empty inline asm with input reg == output reg.
-  // An opaque no-op cast, basically.
-  InlineAsm *Asm = InlineAsm::get(
-      FunctionType::get(Int8PtrTy, {ShadowGlobal->getType()}, false),
-      StringRef(""), StringRef("=r,0"),
-      /*hasSideEffects=*/false);
-  return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow");
+  if (Mapping.InGlobal)
+    ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow",
+                                       ArrayType::get(IRB.getInt8Ty(), 0));
 }
 
 Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) {
@@ -402,11 +381,17 @@
     return nullptr;
 
   if (Mapping.InGlobal) {
-    return getDynamicShadowIfunc(IRB);
+    // An empty inline asm with input reg == output reg.
+    // An opaque pointer-to-int cast, basically.
+    InlineAsm *Asm = InlineAsm::get(
+        FunctionType::get(IntptrTy, {ShadowGlobal->getType()}, false),
+        StringRef(""), StringRef("=r,0"),
+        /*hasSideEffects=*/false);
+    return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow");
   } else {
     Value *GlobalDynamicAddress =
         IRB.GetInsertBlock()->getParent()->getParent()->getOrInsertGlobal(
-            kHwasanShadowMemoryDynamicAddress, Int8PtrTy);
+            kHwasanShadowMemoryDynamicAddress, IntptrTy);
     return IRB.CreateLoad(GlobalDynamicAddress);
   }
 }
@@ -499,44 +484,29 @@
   I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
 }
 
-Value *HWAddressSanitizer::shadowBase() {
-  if (LocalDynamicShadow)
-    return LocalDynamicShadow;
-  return ConstantExpr::getIntToPtr(ConstantInt::get(IntptrTy, Mapping.Offset),
-                                   Int8PtrTy);
-}
-
-Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
+Value *HWAddressSanitizer::memToShadow(Value *Mem, Type *Ty, IRBuilder<> &IRB) {
   // Mem >> Scale
   Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale);
   if (Mapping.Offset == 0)
-    return IRB.CreateIntToPtr(Shadow, Int8PtrTy);
+    return Shadow;
   // (Mem >> Scale) + Offset
-  return IRB.CreateGEP(Int8Ty, shadowBase(), Shadow);
+  Value *ShadowBase;
+  if (LocalDynamicShadow)
+    ShadowBase = LocalDynamicShadow;
+  else
+    ShadowBase = ConstantInt::get(Ty, Mapping.Offset);
+  return IRB.CreateAdd(Shadow, ShadowBase);
 }
 
-void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
+void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
                                                    unsigned AccessSizeIndex,
                                                    Instruction *InsertBefore) {
-  const int64_t AccessInfo = Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex;
   IRBuilder<> IRB(InsertBefore);
-
-  if (!ClInlineAllChecks && TargetTriple.isAArch64() &&
-      TargetTriple.isOSBinFormatELF() && !Recover) {
-    Module *M = IRB.GetInsertBlock()->getParent()->getParent();
-    Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy);
-    IRB.CreateCall(
-        Intrinsic::getDeclaration(M, Intrinsic::hwasan_check_memaccess),
-        {shadowBase(), Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
-    return;
-  }
-
-  Value *PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
   Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, kPointerTagShift),
                                   IRB.getInt8Ty());
   Value *AddrLong = untagPointer(IRB, PtrLong);
-  Value *Shadow = memToShadow(AddrLong, IRB);
-  Value *MemTag = IRB.CreateLoad(Shadow);
+  Value *ShadowLong = memToShadow(AddrLong, PtrLong->getType(), IRB);
+  Value *MemTag = IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, Int8PtrTy));
   Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
 
   int matchAllTag = ClMatchAllTag.getNumOccurrences() > 0 ?
@@ -552,6 +522,7 @@
                                 MDBuilder(*C).createBranchWeights(1, 100000));
 
   IRB.SetInsertPoint(CheckTerm);
+  const int64_t AccessInfo = Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex;
   InlineAsm *Asm;
   switch (TargetTriple.getArch()) {
     case Triple::x86_64:
@@ -593,6 +564,7 @@
     return false; //FIXME
 
   IRBuilder<> IRB(I);
+  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
   if (isPowerOf2_64(TypeSize) &&
       (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) &&
       (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 ||
@@ -600,14 +572,13 @@
     size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize);
     if (ClInstrumentWithCalls) {
       IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex],
-                     IRB.CreatePointerCast(Addr, IntptrTy));
+                     AddrLong);
     } else {
-      instrumentMemAccessInline(Addr, IsWrite, AccessSizeIndex, I);
+      instrumentMemAccessInline(AddrLong, IsWrite, AccessSizeIndex, I);
     }
   } else {
     IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite],
-                   {IRB.CreatePointerCast(Addr, IntptrTy),
-                    ConstantInt::get(IntptrTy, TypeSize / 8)});
+                   {AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8)});
   }
   untagPointerOperand(I, Addr);
 
@@ -638,7 +609,9 @@
                     ConstantInt::get(IntptrTy, Size)});
   } else {
     size_t ShadowSize = Size >> Mapping.Scale;
-    Value *ShadowPtr = memToShadow(IRB.CreatePointerCast(AI, IntptrTy), IRB);
+    Value *ShadowPtr = IRB.CreateIntToPtr(
+        memToShadow(IRB.CreatePointerCast(AI, IntptrTy), AI->getType(), IRB),
+        Int8PtrTy);
     // If this memset is not inlined, it will be intercepted in the hwasan
     // runtime library. That's OK, because the interceptor skips the checks if
     // the address is in the shadow region.
@@ -739,12 +712,10 @@
 Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
   Module *M = IRB.GetInsertBlock()->getParent()->getParent();
   if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) {
-    // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
-    // in Bionic's libc/private/bionic_tls.h.
     Function *ThreadPointerFunc =
         Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
     Value *SlotPtr = IRB.CreatePointerCast(
-        IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), 0x30),
+        IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), 0x40),
         Ty->getPointerTo(0));
     return SlotPtr;
   }
@@ -790,9 +761,6 @@
   if (!Mapping.InTls)
     return getDynamicShadowNonTls(IRB);
 
-  if (ClAllowIfunc && !WithFrameRecord && TargetTriple.isAndroid())
-    return getDynamicShadowIfunc(IRB);
-
   Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
   assert(SlotPtr);
 
@@ -847,7 +815,6 @@
           ThreadLongMaybeUntagged,
           ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
       ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
-  ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
   return ShadowBase;
 }
 
diff --git a/test/CodeGen/AArch64/hwasan-check-memaccess.ll b/test/CodeGen/AArch64/hwasan-check-memaccess.ll
deleted file mode 100644
index 3d5340b..0000000
--- a/test/CodeGen/AArch64/hwasan-check-memaccess.ll
+++ /dev/null
@@ -1,63 +0,0 @@
-; RUN: llc < %s | FileCheck %s
-
-target triple = "aarch64--linux-android"
-
-define i8* @f1(i8* %x0, i8* %x1) {
-  ; CHECK: f1:
-  ; CHECK: str x30, [sp, #-16]!
-  ; CHECK-NEXT: .cfi_def_cfa_offset 16
-  ; CHECK-NEXT: .cfi_offset w30, -16
-  ; CHECK-NEXT: mov x9, x0
-  ; CHECK-NEXT: bl __hwasan_check_x1_123
-  ; CHECK-NEXT: mov x0, x1
-  ; CHECK-NEXT: ldr x30, [sp], #16
-  ; CHECK-NEXT: ret
-  call void @llvm.hwasan.check.memaccess(i8* %x0, i8* %x1, i32 123)
-  ret i8* %x1
-}
-
-define i8* @f2(i8* %x0, i8* %x1) {
-  ; CHECK: f2:
-  ; CHECK: str x30, [sp, #-16]!
-  ; CHECK-NEXT: .cfi_def_cfa_offset 16
-  ; CHECK-NEXT: .cfi_offset w30, -16
-  ; CHECK-NEXT: mov x9, x1
-  ; CHECK-NEXT: bl __hwasan_check_x0_456
-  ; CHECK-NEXT: ldr x30, [sp], #16
-  ; CHECK-NEXT: ret
-  call void @llvm.hwasan.check.memaccess(i8* %x1, i8* %x0, i32 456)
-  ret i8* %x0
-}
-
-declare void @llvm.hwasan.check.memaccess(i8*, i8*, i32)
-
-; CHECK:      .section .text.hot,"axG",@progbits,__hwasan_check_x0_456,comdat
-; CHECK-NEXT: .type __hwasan_check_x0_456,@function
-; CHECK-NEXT: .weak __hwasan_check_x0_456
-; CHECK-NEXT: .hidden __hwasan_check_x0_456
-; CHECK-NEXT: __hwasan_check_x0_456:
-; CHECK-NEXT: ubfx x16, x0, #4, #52
-; CHECK-NEXT: ldrb w16, [x9, x16]
-; CHECK-NEXT: lsr x17, x0, #56
-; CHECK-NEXT: cmp w16, w17
-; CHECK-NEXT: b.ne .Ltmp0
-; CHECK-NEXT: ret
-; CHECK-NEXT: .Ltmp0:
-; CHECK-NEXT: mov x1, #456
-; CHECK-NEXT: b __hwasan_tag_mismatch
-
-; CHECK:      .section .text.hot,"axG",@progbits,__hwasan_check_x1_123,comdat
-; CHECK-NEXT: .type __hwasan_check_x1_123,@function
-; CHECK-NEXT: .weak __hwasan_check_x1_123
-; CHECK-NEXT: .hidden __hwasan_check_x1_123
-; CHECK-NEXT: __hwasan_check_x1_123:
-; CHECK-NEXT: ubfx x16, x1, #4, #52
-; CHECK-NEXT: ldrb w16, [x9, x16]
-; CHECK-NEXT: lsr x17, x1, #56
-; CHECK-NEXT: cmp w16, w17
-; CHECK-NEXT: b.ne .Ltmp1
-; CHECK-NEXT: ret
-; CHECK-NEXT: .Ltmp1:
-; CHECK-NEXT: mov x0, x1
-; CHECK-NEXT: mov x1, #123
-; CHECK-NEXT: b __hwasan_tag_mismatch
diff --git a/test/Instrumentation/HWAddressSanitizer/alloca.ll b/test/Instrumentation/HWAddressSanitizer/alloca.ll
index 12175fa..f132741 100644
--- a/test/Instrumentation/HWAddressSanitizer/alloca.ll
+++ b/test/Instrumentation/HWAddressSanitizer/alloca.ll
@@ -26,7 +26,8 @@
 ; CHECK: %[[X_TAG2:[^ ]*]] = trunc i64 %[[X_TAG]] to i8
 ; CHECK: %[[E:[^ ]*]] = ptrtoint i32* %[[X]] to i64
 ; CHECK: %[[F:[^ ]*]] = lshr i64 %[[E]], 4
-; DYNAMIC-SHADOW: %[[X_SHADOW:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %[[F]]
+; DYNAMIC-SHADOW: %[[F_DYN:[^ ]*]] = add i64 %[[F]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[X_SHADOW:[^ ]*]] = inttoptr i64 %[[F_DYN]] to i8*
 ; ZERO-BASED-SHADOW: %[[X_SHADOW:[^ ]*]] = inttoptr i64 %[[F]] to i8*
 ; CHECK: call void @llvm.memset.p0i8.i64(i8* align 1 %[[X_SHADOW]], i8 %[[X_TAG2]], i64 1, i1 false)
 ; CHECK: call void @use32(i32* nonnull %[[X_HWASAN]])
@@ -35,7 +36,8 @@
 ; UAR-TAGS: %[[X_TAG_UAR:[^ ]*]] = trunc i64 %[[BASE_TAG_COMPL]] to i8
 ; CHECK: %[[E2:[^ ]*]] = ptrtoint i32* %[[X]] to i64
 ; CHECK: %[[F2:[^ ]*]] = lshr i64 %[[E2]], 4
-; DYNAMIC-SHADOW: %[[X_SHADOW2:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %[[F2]]
+; DYNAMIC-SHADOW: %[[F2_DYN:[^ ]*]] = add i64 %[[F2]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[X_SHADOW2:[^ ]*]] = inttoptr i64 %[[F2_DYN]] to i8*
 ; ZERO-BASED-SHADOW: %[[X_SHADOW2:[^ ]*]] = inttoptr i64 %[[F2]] to i8*
 ; NO-UAR-TAGS: call void @llvm.memset.p0i8.i64(i8* align 1 %[[X_SHADOW2]], i8 0, i64 1, i1 false)
 ; UAR-TAGS: call void @llvm.memset.p0i8.i64(i8* align 1 %[[X_SHADOW2]], i8 %[[X_TAG_UAR]], i64 1, i1 false)
diff --git a/test/Instrumentation/HWAddressSanitizer/atomic.ll b/test/Instrumentation/HWAddressSanitizer/atomic.ll
index 8e8f346..e6f7c2d 100644
--- a/test/Instrumentation/HWAddressSanitizer/atomic.ll
+++ b/test/Instrumentation/HWAddressSanitizer/atomic.ll
@@ -7,8 +7,8 @@
 
 define void @atomicrmw(i64* %ptr) sanitize_hwaddress {
 ; CHECK-LABEL: @atomicrmw(
-; CHECK: [[PTRI8:%[^ ]*]] = bitcast i64* %ptr to i8*
-; CHECK: call void @llvm.hwasan.check.memaccess({{.*}}, i8* [[PTRI8]], i32 19)
+; CHECK: lshr i64 %[[A:[^ ]*]], 56
+; CHECK: call void asm sideeffect "brk #2323", "{x0}"(i64 %[[A]])
 ; CHECK: atomicrmw add i64* %ptr, i64 1 seq_cst
 ; CHECK: ret void
 
@@ -19,8 +19,8 @@
 
 define void @cmpxchg(i64* %ptr, i64 %compare_to, i64 %new_value) sanitize_hwaddress {
 ; CHECK-LABEL: @cmpxchg(
-; CHECK: [[PTRI8:%[^ ]*]] = bitcast i64* %ptr to i8*
-; CHECK: call void @llvm.hwasan.check.memaccess({{.*}}, i8* [[PTRI8]], i32 19)
+; CHECK: lshr i64 %[[A:[^ ]*]], 56
+; CHECK: call void asm sideeffect "brk #2323", "{x0}"(i64 %[[A]])
 ; CHECK: cmpxchg i64* %ptr, i64 %compare_to, i64 %new_value seq_cst seq_cst
 ; CHECK: ret void
 
diff --git a/test/Instrumentation/HWAddressSanitizer/basic.ll b/test/Instrumentation/HWAddressSanitizer/basic.ll
index ec50ea7..e02e5fc 100644
--- a/test/Instrumentation/HWAddressSanitizer/basic.ll
+++ b/test/Instrumentation/HWAddressSanitizer/basic.ll
@@ -1,9 +1,9 @@
 ; Test basic address sanitizer instrumentation.
 ;
-; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-DYNAMIC-SHADOW
-; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-DYNAMIC-SHADOW
-; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-ZERO-BASED-SHADOW
-; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW
+; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,DYNAMIC-SHADOW
+; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,DYNAMIC-SHADOW
+; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ZERO-BASED-SHADOW
+; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,ZERO-BASED-SHADOW
 
 ; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @hwasan.module_ctor, i8* bitcast (void ()* @hwasan.module_ctor to i8*) }]
 ; CHECK: @__hwasan = private constant [0 x i8] zeroinitializer, section "__hwasan_frames", comdat($hwasan.module_ctor)
@@ -13,23 +13,23 @@
 
 define i8 @test_load8(i8* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load8(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2304", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %a, i32 0)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %a, i32 0)
-
 ; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4
 ; CHECK: ret i8 %[[G]]
 
@@ -40,24 +40,23 @@
 
 define i16 @test_load16(i16* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load16(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2305", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2337", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i16* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 1)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 1)
-
 ; CHECK: %[[G:[^ ]*]] = load i16, i16* %a, align 4
 ; CHECK: ret i16 %[[G]]
 
@@ -68,24 +67,23 @@
 
 define i32 @test_load32(i32* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load32(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2306", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2338", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i32* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 2)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 2)
-
 ; CHECK: %[[G:[^ ]*]] = load i32, i32* %a, align 4
 ; CHECK: ret i32 %[[G]]
 
@@ -96,24 +94,23 @@
 
 define i64 @test_load64(i64* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load64(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2307", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2339", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i64* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 3)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 3)
-
 ; CHECK: %[[G:[^ ]*]] = load i64, i64* %a, align 8
 ; CHECK: ret i64 %[[G]]
 
@@ -124,24 +121,23 @@
 
 define i128 @test_load128(i128* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load128(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2308", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2340", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i128* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 4)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 4)
-
 ; CHECK: %[[G:[^ ]*]] = load i128, i128* %a, align 16
 ; CHECK: ret i128 %[[G]]
 
@@ -165,23 +161,23 @@
 
 define void @test_store8(i8* %a, i8 %b) sanitize_hwaddress {
 ; CHECK-LABEL: @test_store8(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2320", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2352", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %a, i32 16)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %a, i32 16)
-
 ; CHECK: store i8 %b, i8* %a, align 4
 ; CHECK: ret void
 
@@ -192,24 +188,23 @@
 
 define void @test_store16(i16* %a, i16 %b) sanitize_hwaddress {
 ; CHECK-LABEL: @test_store16(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2321", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2353", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i16* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 17)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 17)
-
 ; CHECK: store i16 %b, i16* %a, align 4
 ; CHECK: ret void
 
@@ -220,24 +215,23 @@
 
 define void @test_store32(i32* %a, i32 %b) sanitize_hwaddress {
 ; CHECK-LABEL: @test_store32(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2322", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2354", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i32* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 18)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 18)
-
 ; CHECK: store i32 %b, i32* %a, align 4
 ; CHECK: ret void
 
@@ -248,24 +242,23 @@
 
 define void @test_store64(i64* %a, i64 %b) sanitize_hwaddress {
 ; CHECK-LABEL: @test_store64(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2323", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2355", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i64* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 19)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 19)
-
 ; CHECK: store i64 %b, i64* %a, align 8
 ; CHECK: ret void
 
@@ -276,24 +269,23 @@
 
 define void @test_store128(i128* %a, i128 %b) sanitize_hwaddress {
 ; CHECK-LABEL: @test_store128(
-; RECOVER: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
-; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
-; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
-; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
-; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
-; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
-; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
-; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
-; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
-; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
+; CHECK: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
+; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
+; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
+; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
+; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
+; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
+; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
+; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
+; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
+; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
+; ABORT: call void asm sideeffect "brk #2324", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
 ; RECOVER: call void asm sideeffect "brk #2356", "{x0}"(i64 %[[A]])
 ; RECOVER: br label
 
-; ABORT: %[[A:[^ ]*]] = bitcast i128* %a to i8*
-; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess(i8* %.hwasan.shadow, i8* %[[A]], i32 20)
-; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess(i8* null, i8* %[[A]], i32 20)
-
 ; CHECK: store i128 %b, i128* %a, align 16
 ; CHECK: ret void
 
diff --git a/test/Instrumentation/HWAddressSanitizer/kernel.ll b/test/Instrumentation/HWAddressSanitizer/kernel.ll
index 3f5891c..ad3dba7 100644
--- a/test/Instrumentation/HWAddressSanitizer/kernel.ll
+++ b/test/Instrumentation/HWAddressSanitizer/kernel.ll
@@ -1,9 +1,11 @@
 ; Test KHWASan instrumentation.
 ;
-; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -S | FileCheck %s --allow-empty --check-prefixes=INIT
-; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -S | FileCheck %s  --check-prefixes=CHECK,NOOFFSET,MATCH-ALL
-; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -hwasan-mapping-offset=12345678 -S | FileCheck %s  --check-prefixes=CHECK,OFFSET,MATCH-ALL
-; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -hwasan-match-all-tag=-1 -S | FileCheck %s  --check-prefixes=CHECK,NOOFFSET,NO-MATCH-ALL
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s --allow-empty --check-prefixes=INIT
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s  --check-prefixes=CHECK,NOOFFSET,MATCH-ALL
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-mapping-offset=12345678 -S | FileCheck %s  --check-prefixes=CHECK,OFFSET,MATCH-ALL
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=0 -S | FileCheck %s  --check-prefixes=CHECK,NOOFFSET,ABORT,MATCH-ALL
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -S | FileCheck %s  --check-prefixes=CHECK,NOOFFSET,RECOVER,MATCH-ALL
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -hwasan-match-all-tag=-1 -S | FileCheck %s  --check-prefixes=CHECK,NOOFFSET,RECOVER,NO-MATCH-ALL
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "aarch64--linux-android"
@@ -18,7 +20,8 @@
 
 ; NOOFFSET: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
 
-; OFFSET: %[[E:[^ ]*]] = getelementptr i8, i8* inttoptr (i64 12345678 to i8*), i64 %[[D]]
+; OFFSET: %[[D1:[^ ]*]] = add i64 %[[D]], 12345678
+; OFFSET: %[[E:[^ ]*]] = inttoptr i64 %[[D1]] to i8*
 
 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
@@ -29,8 +32,10 @@
 
 ; NO-MATCH-ALL: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
 
-; CHECK: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]])
-; CHECK: br label
+; ABORT: call void asm sideeffect "brk #2304", "{x0}"(i64 %[[A]])
+; ABORT: unreachable
+; RECOVER: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]])
+; RECOVER: br label
 
 ; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4
 ; CHECK: ret i8 %[[G]]
diff --git a/test/Instrumentation/HWAddressSanitizer/prologue.ll b/test/Instrumentation/HWAddressSanitizer/prologue.ll
index 1163dbe..6b02b986 100644
--- a/test/Instrumentation/HWAddressSanitizer/prologue.ll
+++ b/test/Instrumentation/HWAddressSanitizer/prologue.ll
@@ -1,15 +1,15 @@
 ; Test -hwasan-with-ifunc flag.
 ;
-; RUN: opt -hwasan -hwasan-allow-ifunc -S < %s | \
-; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY
-; RUN: opt -hwasan -hwasan-allow-ifunc -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=1 < %s | \
-; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY
-; RUN: opt -hwasan -hwasan-allow-ifunc -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=0 < %s | \
-; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-IFUNC,CHECK-NOHISTORY
-; RUN: opt -hwasan -hwasan-allow-ifunc -S -hwasan-with-ifunc=0 -hwasan-with-tls=0 < %s | \
+; RUN: opt -hwasan -S < %s | \
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-TLS,CHECK-HISTORY
+; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=1 < %s | \
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-TLS,CHECK-HISTORY
+; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=0 < %s | \
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-TLS,CHECK-NOHISTORY
+; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=0 < %s | \
 ; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL,CHECK-NOHISTORY
-; RUN: opt -hwasan -hwasan-allow-ifunc -S -hwasan-with-ifunc=1  -hwasan-with-tls=0 < %s | \
-; RUN:     FileCheck %s --check-prefixes=CHECK,CHECk-NOGLOBAL,CHECK-IFUNC,CHECK-NOHISTORY
+; RUN: opt -hwasan -S -hwasan-with-ifunc=1  -hwasan-with-tls=0 < %s | \
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC,CHECK-NOHISTORY
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "aarch64--linux-android22"
@@ -23,10 +23,17 @@
 ; CHECK-LABEL: @test_load
 ; CHECK: entry:
 
-; CHECK-NOGLOBAL:   %[[A:[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
-; CHECK-NOGLOBAL:   @llvm.hwasan.check.memaccess(i8* %[[A]]
+; CHECK-IFUNC:   %[[A:[^ ]*]] = call i64 asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
+; CHECK-IFUNC:   add i64 %{{.*}}, %[[A]]
 
-; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address
+; CHECK-GLOBAL: load i64, i64* @__hwasan_shadow_memory_dynamic_address
+
+; CHECK-TLS:   %[[A:[^ ]*]] = call i8* @llvm.thread.pointer()
+; CHECK-TLS:   %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 64
+; CHECK-TLS:   %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64*
+; CHECK-TLS:   %[[D:[^ ]*]] = load i64, i64* %[[C]]
+; CHECK-TLS:   %[[E:[^ ]*]] = or i64 %[[D]], 4294967295
+; CHECK-TLS:   = add i64 %[[E]], 1
 
 ; "store i64" is only used to update stack history (this input IR intentionally does not use any i64)
 ; W/o any allocas, the history is not updated, even if it is enabled explicitly with -hwasan-record-stack-history=1
@@ -47,13 +54,13 @@
 ; CHECK-LABEL: @test_alloca
 ; CHECK: entry:
 
-; CHECK-IFUNC:   %[[A:[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
-; CHECK-IFUNC:   getelementptr i8, i8* %[[A]]
+; CHECK-IFUNC:   %[[A:[^ ]*]] = call i64 asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
+; CHECK-IFUNC:   add i64 %{{.*}}, %[[A]]
 
-; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address
+; CHECK-GLOBAL: load i64, i64* @__hwasan_shadow_memory_dynamic_address
 
 ; CHECK-TLS:   %[[A:[^ ]*]] = call i8* @llvm.thread.pointer()
-; CHECK-TLS:   %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 48
+; CHECK-TLS:   %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 64
 ; CHECK-TLS:   %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64*
 ; CHECK-TLS:   %[[D:[^ ]*]] = load i64, i64* %[[C]]
 
diff --git a/test/LTO/X86/Inputs/type-mapping-bug2.ll b/test/LTO/X86/Inputs/type-mapping-bug2.ll
new file mode 100644
index 0000000..b58a1e9
--- /dev/null
+++ b/test/LTO/X86/Inputs/type-mapping-bug2.ll
@@ -0,0 +1,16 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @c() !dbg !6 {
+  unreachable
+}
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{i32 1, !"ThinLTO", i32 0}
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4)
+!3 = !DIFile(filename: "f2", directory: "")
+!4 = !{!5}
+!5 = !DICompositeType(tag: DW_TAG_class_type, file: !3, flags: DIFlagFwdDecl, identifier: "SHARED")
+!6 = distinct !DISubprogram(unit: !2)
diff --git a/test/LTO/X86/type-mapping-bug2.ll b/test/LTO/X86/type-mapping-bug2.ll
new file mode 100644
index 0000000..f14183f
--- /dev/null
+++ b/test/LTO/X86/type-mapping-bug2.ll
@@ -0,0 +1,42 @@
+; RUN: opt -module-summary -o %t0.o %S/Inputs/type-mapping-bug2.ll
+; RUN: opt -module-summary -o %t1.o %s
+; RUN: llvm-lto2 run -o %t2 %t0.o %t1.o -r %t0.o,c,px -r %t1.o,a,px -r %t1.o,b,px
+;
+; Test for the issue described in https://bugs.llvm.org/show_bug.cgi?id=37684
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; T1 will be linked against T2 because T2 was already loaded in %t0.o due to
+; the declaration for @b being imported due to !13
+%"T1" = type {}
+%"T2" = type {}
+
+define %"T1" @a() {
+  unreachable
+}
+
+define i1 @b(%"T2"*) {
+  unreachable
+}
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{i32 1, !"ThinLTO", i32 0}
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4)
+!3 = !DIFile(filename: "f1", directory: "")
+!4 = !{!5, !9}
+!5 = !DICompositeType(tag: DW_TAG_class_type, file: !3, templateParams: !6, scope: !8)
+!6 = !{!7}
+
+; The reference to @b and T2 that will be loaded in %t0.o
+
+!7 = !DITemplateValueParameter(value: i1 (%"T2"*)* @b)
+!8 = distinct !DISubprogram(unit: !2)
+
+; This DICompositeType is uniqued against !5 in Inputs/type-mapping-bug2.ll,
+; causing !7 and hence %T2 to be loaded into it's module
+
+!9 = !DICompositeType(tag: DW_TAG_array_type, identifier: "SHARED", scope: !8)
+
diff --git a/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll b/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
index 005ea37..5cc00b7 100644
--- a/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
+++ b/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
@@ -88,23 +88,18 @@
 }
 
 declare %struct_type* @foo()
-declare void @foo2()
 
 define void @test4(i32 %n) personality i32 (...)* @__FrameHandler {
 ; CHECK-LABEL: test4
 entry:
-  br label %while_cond
+  %struct = invoke %struct_type* @foo() to label %while_cond unwind label %cleanup
 
 while_cond:
   %phi = phi i32 [ 0, %entry ], [ %i, %while_body ]
-  %struct = invoke %struct_type* @foo() to label %while_cond_x unwind label %cleanup
-
-while_cond_x:
 ; CHECK:     mov     w{{[0-9]+}}, #40000
 ; CHECK-NOT: mov     w{{[0-9]+}}, #40004
   %gep0 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 1
   %gep1 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 2
-  store i32 0, i32* %gep0
   %cmp = icmp slt i32 %phi, %n
   br i1 %cmp, label %while_body, label %while_end
 
@@ -119,10 +114,8 @@
   ret void
 
 cleanup:
-  %x10 = landingpad { i8*, i32 }
-          cleanup
-  call void @foo2()
-  resume { i8*, i32 } %x10
+  landingpad { i8*, i32 } cleanup
+  unreachable
 }
 
 declare i32 @__FrameHandler(...)