aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Kong <yikong@google.com>2019-02-27 14:16:19 -0800
committerYi Kong <yikong@google.com>2019-02-27 14:16:19 -0800
commit06a18b67a0c135bfaf4e9dd604e83a63090bbe50 (patch)
treeb664493264259e1ca955b139d80574fbeaa094b7
parent4ccd15c2037ec8506aff757452131a084bc3583e (diff)
downloadllvm-06a18b67a0c135bfaf4e9dd604e83a63090bbe50.tar.gz
revert to previous base llvm-svn.349610
Change-Id: Ibbe1931d087763e3fd973a6266aec9b6efa083c2
-rw-r--r--include/llvm/IR/Intrinsics.td3
-rw-r--r--lib/CodeGen/CodeGenPrepare.cpp7
-rw-r--r--lib/Linker/IRMover.cpp19
-rw-r--r--lib/Target/AArch64/AArch64AsmPrinter.cpp112
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.td7
-rw-r--r--lib/Target/AArch64/AArch64RegisterBankInfo.cpp3
-rw-r--r--lib/Target/AArch64/AArch64RegisterInfo.td5
-rw-r--r--lib/Transforms/Instrumentation/HWAddressSanitizer.cpp99
-rw-r--r--test/CodeGen/AArch64/hwasan-check-memaccess.ll63
-rw-r--r--test/Instrumentation/HWAddressSanitizer/alloca.ll6
-rw-r--r--test/Instrumentation/HWAddressSanitizer/atomic.ll8
-rw-r--r--test/Instrumentation/HWAddressSanitizer/basic.ll296
-rw-r--r--test/Instrumentation/HWAddressSanitizer/kernel.ll19
-rw-r--r--test/Instrumentation/HWAddressSanitizer/prologue.ll39
-rw-r--r--test/LTO/X86/Inputs/type-mapping-bug2.ll16
-rw-r--r--test/LTO/X86/type-mapping-bug2.ll42
-rw-r--r--test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll13
17 files changed, 298 insertions, 459 deletions
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index d20858f59ab..f503d3ebbdf 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -1042,9 +1042,6 @@ def int_icall_branch_funnel : Intrinsic<[], [llvm_vararg_ty], []>;
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 c35f8666fa3..392e8bc0db4 100644
--- a/lib/CodeGen/CodeGenPrepare.cpp
+++ b/lib/CodeGen/CodeGenPrepare.cpp
@@ -5160,11 +5160,11 @@ bool CodeGenPrepare::splitLargeGEPOffsets() {
}
// 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 @@ bool CodeGenPrepare::splitLargeGEPOffsets() {
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 c0e618c2923..afbc57abfcc 100644
--- a/lib/Linker/IRMover.cpp
+++ b/lib/Linker/IRMover.cpp
@@ -240,18 +240,27 @@ Type *TypeMapTy::get(Type *Ty, SmallPtrSet<StructType *, 8> &Visited) {
// 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 c7c651f8e80..828fbb2de7e 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 @@ public:
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 @@ void AArch64AsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind)
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 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
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 9e9722ee68f..ee43b55aed9 100644
--- a/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/lib/Target/AArch64/AArch64InstrInfo.td
@@ -752,13 +752,6 @@ def MSRpstateImm4 : MSRpstateImm0_15;
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 0e230e15cf8..c497669f937 100644
--- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
+++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
@@ -249,9 +249,6 @@ const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
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 9729b143a9f..d3710cea068 100644
--- a/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -206,11 +206,6 @@ def tcGPR64 : RegisterClass<"AArch64", [i64], 64, (sub GPR64common, X19, X20, X2
// 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 837220ceb0a..042e8ea0d29 100644
--- a/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -152,14 +152,6 @@ static cl::opt<bool>
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 @@ public:
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 @@ private:
Type *IntptrTy;
Type *Int8PtrTy;
Type *Int8Ty;
- Type *Int32Ty;
bool CompileKernel;
bool Recover;
@@ -312,7 +301,6 @@ bool HWAddressSanitizer::doInitialization(Module &M) {
IntptrTy = IRB.getIntPtrTy(DL);
Int8PtrTy = IRB.getInt8PtrTy();
Int8Ty = IRB.getInt8Ty();
- Int32Ty = IRB.getInt32Ty();
HwasanCtorFunction = nullptr;
if (!CompileKernel) {
@@ -382,18 +370,9 @@ void HWAddressSanitizer::initializeCallbacks(Module &M) {
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 @@ Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) {
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 @@ void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
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 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
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 @@ bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) {
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 @@ bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) {
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 @@ bool HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI,
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::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
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 @@ Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
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 @@ Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
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 3d5340b4aa0..00000000000
--- 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 12175fa011f..f13274171f0 100644
--- a/test/Instrumentation/HWAddressSanitizer/alloca.ll
+++ b/test/Instrumentation/HWAddressSanitizer/alloca.ll
@@ -26,7 +26,8 @@ define void @test_alloca() sanitize_hwaddress {
; 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 @@ define void @test_alloca() sanitize_hwaddress {
; 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 8e8f34628f5..e6f7c2df23f 100644
--- a/test/Instrumentation/HWAddressSanitizer/atomic.ll
+++ b/test/Instrumentation/HWAddressSanitizer/atomic.ll
@@ -7,8 +7,8 @@ target triple = "aarch64--linux-android"
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 @@ entry:
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 ec50ea78839..e02e5fc283b 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 @@ target triple = "aarch64--linux-android"
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 @@ entry:
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 3f5891c1ddd..ad3dba7f896 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 @@ define i8 @test_load(i8* %a) sanitize_hwaddress {
; 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 @@ define i8 @test_load(i8* %a) sanitize_hwaddress {
; 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 1163dbe72de..6b02b9863cd 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 @@ define i32 @test_load(i32* %a) sanitize_hwaddress {
; 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 @@ define void @test_alloca() sanitize_hwaddress {
; 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 00000000000..b58a1e953fb
--- /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 00000000000..f14183f506f
--- /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 005ea37288c..5cc00b75962 100644
--- a/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
+++ b/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
@@ -88,23 +88,18 @@ while_end:
}
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 @@ while_end:
ret void
cleanup:
- %x10 = landingpad { i8*, i32 }
- cleanup
- call void @foo2()
- resume { i8*, i32 } %x10
+ landingpad { i8*, i32 } cleanup
+ unreachable
}
declare i32 @__FrameHandler(...)