From: Peter Collingbourne Date: Thu, 27 Jun 2019 23:24:07 +0000 (+0000) Subject: hwasan: Use llvm.read_register intrinsic to read the PC on aarch64 instead of taking... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=405de2bdbd73ca58ed3c2ced6cca9a6ef2a49722;p=llvm hwasan: Use llvm.read_register intrinsic to read the PC on aarch64 instead of taking the function's address. This shaves an instruction (and a GOT entry in PIC code) off prologues of functions with stack variables. Differential Revision: https://reviews.llvm.org/D63472 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364608 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 4f6dae0cc40..9085da6e113 100644 --- a/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -210,6 +210,7 @@ public: SmallVectorImpl &Allocas, DenseMap> &AllocaDeclareMap, SmallVectorImpl &RetVec, Value *StackTag); + Value *readRegister(IRBuilder<> &IRB, StringRef Name); bool instrumentLandingPads(SmallVectorImpl &RetVec); Value *getNextTagWithCall(IRBuilder<> &IRB); Value *getStackBaseTag(IRBuilder<> &IRB); @@ -935,7 +936,11 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) { StackBaseTag = IRB.CreateAShr(ThreadLong, 3); // Prepare ring buffer data. - auto PC = IRB.CreatePtrToInt(F, IntptrTy); + Value *PC; + if (TargetTriple.getArch() == Triple::aarch64) + PC = readRegister(IRB, "pc"); + else + PC = IRB.CreatePtrToInt(F, IntptrTy); auto GetStackPointerFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::frameaddress); Value *SP = IRB.CreatePtrToInt( @@ -981,19 +986,23 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) { LocalDynamicShadow = IRB.CreateIntToPtr(LocalDynamicShadow, Int8PtrTy); } -bool HWAddressSanitizer::instrumentLandingPads( - SmallVectorImpl &LandingPadVec) { - Module *M = LandingPadVec[0]->getModule(); +Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) { + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); Function *ReadRegister = Intrinsic::getDeclaration(M, Intrinsic::read_register, IntptrTy); - const char *RegName = - (TargetTriple.getArch() == Triple::x86_64) ? "rsp" : "sp"; - MDNode *MD = MDNode::get(*C, {MDString::get(*C, RegName)}); + MDNode *MD = MDNode::get(*C, {MDString::get(*C, Name)}); Value *Args[] = {MetadataAsValue::get(*C, MD)}; + return IRB.CreateCall(ReadRegister, Args); +} +bool HWAddressSanitizer::instrumentLandingPads( + SmallVectorImpl &LandingPadVec) { for (auto *LP : LandingPadVec) { IRBuilder<> IRB(LP->getNextNode()); - IRB.CreateCall(HWAsanHandleVfork, {IRB.CreateCall(ReadRegister, Args)}); + IRB.CreateCall( + HWAsanHandleVfork, + {readRegister(IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp" + : "sp")}); } return true; } diff --git a/test/Instrumentation/HWAddressSanitizer/prologue.ll b/test/Instrumentation/HWAddressSanitizer/prologue.ll index f197930253a..babfd9d725d 100644 --- a/test/Instrumentation/HWAddressSanitizer/prologue.ll +++ b/test/Instrumentation/HWAddressSanitizer/prologue.ll @@ -60,6 +60,7 @@ define void @test_alloca() sanitize_hwaddress { ; CHECK-NOHISTORY-NOT: store i64 +; CHECK-HISTORY: call i64 @llvm.read_register.i64(metadata [[MD:![0-9]*]]) ; CHECK-HISTORY: %[[PTR:[^ ]*]] = inttoptr i64 %[[D]] to i64* ; CHECK-HISTORY: store i64 %{{.*}}, i64* %[[PTR]] ; CHECK-HISTORY: %[[D1:[^ ]*]] = ashr i64 %[[D]], 56 @@ -82,3 +83,5 @@ entry: call void @use(i32* %x) ret void } + +; CHECK-HISTORY: [[MD]] = !{!"pc"}