Skip to content

[hwasan] Update (Post-)DominatorTreeAnalysis and LoopAnalysis incrementally #66935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 28, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 47 additions & 25 deletions llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
Expand Down Expand Up @@ -303,17 +304,20 @@ class HWAddressSanitizer {
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);

int64_t getAccessInfo(bool IsWrite, unsigned AccessSizeIndex);
ShadowTagCheckInfo insertShadowTagCheck(Value *Ptr,
Instruction *InsertBefore);
ShadowTagCheckInfo insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
DomTreeUpdater &DTU, LoopInfo &LI);
void instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
unsigned AccessSizeIndex,
Instruction *InsertBefore);
Instruction *InsertBefore,
DomTreeUpdater &DTU, LoopInfo &LI);
void instrumentMemAccessInline(Value *Ptr, bool IsWrite,
unsigned AccessSizeIndex,
Instruction *InsertBefore);
Instruction *InsertBefore, DomTreeUpdater &DTU,
LoopInfo &LI);
bool ignoreMemIntrinsic(MemIntrinsic *MI);
void instrumentMemIntrinsic(MemIntrinsic *MI);
bool instrumentMemAccess(InterestingMemoryOperand &O);
bool instrumentMemAccess(InterestingMemoryOperand &O, DomTreeUpdater &DTU,
LoopInfo &LI);
bool ignoreAccess(Instruction *Inst, Value *Ptr);
void getInterestingMemoryOperands(
Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting);
Expand Down Expand Up @@ -434,6 +438,12 @@ PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
HWASan.sanitizeFunction(F, FAM);

PreservedAnalyses PA = PreservedAnalyses::none();
// DominatorTreeAnalysis, PostDominatorTreeAnalysis, and LoopAnalysis
// are incrementally updated throughout this pass whenever
// SplitBlockAndInsertIfThen is called.
PA.preserve<DominatorTreeAnalysis>();
PA.preserve<PostDominatorTreeAnalysis>();
PA.preserve<LoopAnalysis>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add PostDominatorTreeAnalysis here too? Seems like DomTreeUpdater also takes care of that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(And if not, please add a comment in the code on why not, because I think that's a natural question)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, added.

// GlobalsAA is considered stateless and does not get invalidated unless
// explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
// make changes that require GlobalsAA to be invalidated.
Expand Down Expand Up @@ -861,8 +871,8 @@ int64_t HWAddressSanitizer::getAccessInfo(bool IsWrite,
}

HWAddressSanitizer::ShadowTagCheckInfo
HWAddressSanitizer::insertShadowTagCheck(Value *Ptr,
Instruction *InsertBefore) {
HWAddressSanitizer::insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
DomTreeUpdater &DTU, LoopInfo &LI) {
ShadowTagCheckInfo R;

IRBuilder<> IRB(InsertBefore);
Expand All @@ -881,21 +891,24 @@ HWAddressSanitizer::insertShadowTagCheck(Value *Ptr,
TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
}

R.TagMismatchTerm =
SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, false,
MDBuilder(*C).createBranchWeights(1, 100000));
R.TagMismatchTerm = SplitBlockAndInsertIfThen(
TagMismatch, InsertBefore, false,
MDBuilder(*C).createBranchWeights(1, 100000), &DTU, &LI);

return R;
}

void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
unsigned AccessSizeIndex,
Instruction *InsertBefore) {
Instruction *InsertBefore,
DomTreeUpdater &DTU,
LoopInfo &LI) {
assert(!UsePageAliases);
const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);

if (InlineFastPath)
InsertBefore = insertShadowTagCheck(Ptr, InsertBefore).TagMismatchTerm;
InsertBefore =
insertShadowTagCheck(Ptr, InsertBefore, DTU, LI).TagMismatchTerm;

IRBuilder<> IRB(InsertBefore);
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
Expand All @@ -909,38 +922,38 @@ void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,

void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
unsigned AccessSizeIndex,
Instruction *InsertBefore) {
Instruction *InsertBefore,
DomTreeUpdater &DTU,
LoopInfo &LI) {
assert(!UsePageAliases);
const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);

ShadowTagCheckInfo TCI = insertShadowTagCheck(Ptr, InsertBefore);
ShadowTagCheckInfo TCI = insertShadowTagCheck(Ptr, InsertBefore, DTU, LI);

IRBuilder<> IRB(TCI.TagMismatchTerm);
Value *OutOfShortGranuleTagRange =
IRB.CreateICmpUGT(TCI.MemTag, ConstantInt::get(Int8Ty, 15));
Instruction *CheckFailTerm = SplitBlockAndInsertIfThen(
OutOfShortGranuleTagRange, TCI.TagMismatchTerm, !Recover,
MDBuilder(*C).createBranchWeights(1, 100000));
MDBuilder(*C).createBranchWeights(1, 100000), &DTU, &LI);

IRB.SetInsertPoint(TCI.TagMismatchTerm);
Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(TCI.PtrLong, 15), Int8Ty);
PtrLowBits = IRB.CreateAdd(
PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, TCI.MemTag);
SplitBlockAndInsertIfThen(PtrLowBitsOOB, TCI.TagMismatchTerm, false,
MDBuilder(*C).createBranchWeights(1, 100000),
(DomTreeUpdater *)nullptr, nullptr,
CheckFailTerm->getParent());
MDBuilder(*C).createBranchWeights(1, 100000), &DTU,
&LI, CheckFailTerm->getParent());

IRB.SetInsertPoint(TCI.TagMismatchTerm);
Value *InlineTagAddr = IRB.CreateOr(TCI.AddrLong, 15);
InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, Int8PtrTy);
Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
Value *InlineTagMismatch = IRB.CreateICmpNE(TCI.PtrTag, InlineTag);
SplitBlockAndInsertIfThen(InlineTagMismatch, TCI.TagMismatchTerm, false,
MDBuilder(*C).createBranchWeights(1, 100000),
(DomTreeUpdater *)nullptr, nullptr,
CheckFailTerm->getParent());
MDBuilder(*C).createBranchWeights(1, 100000), &DTU,
&LI, CheckFailTerm->getParent());

IRB.SetInsertPoint(CheckFailTerm);
InlineAsm *Asm;
Expand Down Expand Up @@ -1015,7 +1028,9 @@ void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
MI->eraseFromParent();
}

bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O,
DomTreeUpdater &DTU,
LoopInfo &LI) {
Value *Addr = O.getPtr();

LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n");
Expand All @@ -1036,9 +1051,11 @@ bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
Args);
} else if (OutlinedChecks) {
instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
DTU, LI);
} else {
instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
DTU, LI);
}
} else {
SmallVector<Value *, 3> Args{
Expand Down Expand Up @@ -1542,8 +1559,13 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
}
}

DominatorTree *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
PostDominatorTree *PDT = FAM.getCachedResult<PostDominatorTreeAnalysis>(F);
LoopInfo *LI = FAM.getCachedResult<LoopAnalysis>(F);
DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
for (auto &Operand : OperandsToInstrument)
instrumentMemAccess(Operand);
instrumentMemAccess(Operand, DTU, *LI);
DTU.flush();

if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) {
for (auto *Inst : IntrinToInstrument)
Expand Down