diff options
author | Yi Kong <yikong@google.com> | 2019-02-27 14:16:19 -0800 |
---|---|---|
committer | Yi Kong <yikong@google.com> | 2019-02-27 14:16:19 -0800 |
commit | 06a18b67a0c135bfaf4e9dd604e83a63090bbe50 (patch) | |
tree | b664493264259e1ca955b139d80574fbeaa094b7 | |
parent | 4ccd15c2037ec8506aff757452131a084bc3583e (diff) | |
download | llvm-06a18b67a0c135bfaf4e9dd604e83a63090bbe50.tar.gz |
revert to previous base llvm-svn.349610
Change-Id: Ibbe1931d087763e3fd973a6266aec9b6efa083c2
-rw-r--r-- | include/llvm/IR/Intrinsics.td | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenPrepare.cpp | 7 | ||||
-rw-r--r-- | lib/Linker/IRMover.cpp | 19 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64AsmPrinter.cpp | 112 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrInfo.td | 7 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64RegisterBankInfo.cpp | 3 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64RegisterInfo.td | 5 | ||||
-rw-r--r-- | lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 99 | ||||
-rw-r--r-- | test/CodeGen/AArch64/hwasan-check-memaccess.ll | 63 | ||||
-rw-r--r-- | test/Instrumentation/HWAddressSanitizer/alloca.ll | 6 | ||||
-rw-r--r-- | test/Instrumentation/HWAddressSanitizer/atomic.ll | 8 | ||||
-rw-r--r-- | test/Instrumentation/HWAddressSanitizer/basic.ll | 296 | ||||
-rw-r--r-- | test/Instrumentation/HWAddressSanitizer/kernel.ll | 19 | ||||
-rw-r--r-- | test/Instrumentation/HWAddressSanitizer/prologue.ll | 39 | ||||
-rw-r--r-- | test/LTO/X86/Inputs/type-mapping-bug2.ll | 16 | ||||
-rw-r--r-- | test/LTO/X86/type-mapping-bug2.ll | 42 | ||||
-rw-r--r-- | test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll | 13 |
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(...) |