Skip to content

Commit b3b6ede

Browse files
authored
[hwasan] Update (Post-)DominatorTreeAnalysis and LoopAnalysis incrementally (#66935)
HWAddressSanitizerPass::run sanitizes functions one by one. The sanitization of each function - which may split blocks via insertShadowTagCheck - may result in some cached analyses are invalid. This matters because sanitizeFunction(F', FAM) may indirectly call the global stack safety analysis, hence we need to make sure the analyses of F are up to date. Bug report: #66934
1 parent d5ccbaf commit b3b6ede

File tree

1 file changed

+47
-25
lines changed

1 file changed

+47
-25
lines changed

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/ADT/SmallVector.h"
1818
#include "llvm/ADT/StringExtras.h"
1919
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/Analysis/DomTreeUpdater.h"
2021
#include "llvm/Analysis/GlobalsModRef.h"
2122
#include "llvm/Analysis/PostDominators.h"
2223
#include "llvm/Analysis/StackSafetyAnalysis.h"
@@ -303,17 +304,20 @@ class HWAddressSanitizer {
303304
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
304305

305306
int64_t getAccessInfo(bool IsWrite, unsigned AccessSizeIndex);
306-
ShadowTagCheckInfo insertShadowTagCheck(Value *Ptr,
307-
Instruction *InsertBefore);
307+
ShadowTagCheckInfo insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
308+
DomTreeUpdater &DTU, LoopInfo &LI);
308309
void instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
309310
unsigned AccessSizeIndex,
310-
Instruction *InsertBefore);
311+
Instruction *InsertBefore,
312+
DomTreeUpdater &DTU, LoopInfo &LI);
311313
void instrumentMemAccessInline(Value *Ptr, bool IsWrite,
312314
unsigned AccessSizeIndex,
313-
Instruction *InsertBefore);
315+
Instruction *InsertBefore, DomTreeUpdater &DTU,
316+
LoopInfo &LI);
314317
bool ignoreMemIntrinsic(MemIntrinsic *MI);
315318
void instrumentMemIntrinsic(MemIntrinsic *MI);
316-
bool instrumentMemAccess(InterestingMemoryOperand &O);
319+
bool instrumentMemAccess(InterestingMemoryOperand &O, DomTreeUpdater &DTU,
320+
LoopInfo &LI);
317321
bool ignoreAccess(Instruction *Inst, Value *Ptr);
318322
void getInterestingMemoryOperands(
319323
Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting);
@@ -434,6 +438,12 @@ PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
434438
HWASan.sanitizeFunction(F, FAM);
435439

436440
PreservedAnalyses PA = PreservedAnalyses::none();
441+
// DominatorTreeAnalysis, PostDominatorTreeAnalysis, and LoopAnalysis
442+
// are incrementally updated throughout this pass whenever
443+
// SplitBlockAndInsertIfThen is called.
444+
PA.preserve<DominatorTreeAnalysis>();
445+
PA.preserve<PostDominatorTreeAnalysis>();
446+
PA.preserve<LoopAnalysis>();
437447
// GlobalsAA is considered stateless and does not get invalidated unless
438448
// explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
439449
// make changes that require GlobalsAA to be invalidated.
@@ -861,8 +871,8 @@ int64_t HWAddressSanitizer::getAccessInfo(bool IsWrite,
861871
}
862872

863873
HWAddressSanitizer::ShadowTagCheckInfo
864-
HWAddressSanitizer::insertShadowTagCheck(Value *Ptr,
865-
Instruction *InsertBefore) {
874+
HWAddressSanitizer::insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
875+
DomTreeUpdater &DTU, LoopInfo &LI) {
866876
ShadowTagCheckInfo R;
867877

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

884-
R.TagMismatchTerm =
885-
SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, false,
886-
MDBuilder(*C).createBranchWeights(1, 100000));
894+
R.TagMismatchTerm = SplitBlockAndInsertIfThen(
895+
TagMismatch, InsertBefore, false,
896+
MDBuilder(*C).createBranchWeights(1, 100000), &DTU, &LI);
887897

888898
return R;
889899
}
890900

891901
void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
892902
unsigned AccessSizeIndex,
893-
Instruction *InsertBefore) {
903+
Instruction *InsertBefore,
904+
DomTreeUpdater &DTU,
905+
LoopInfo &LI) {
894906
assert(!UsePageAliases);
895907
const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
896908

897909
if (InlineFastPath)
898-
InsertBefore = insertShadowTagCheck(Ptr, InsertBefore).TagMismatchTerm;
910+
InsertBefore =
911+
insertShadowTagCheck(Ptr, InsertBefore, DTU, LI).TagMismatchTerm;
899912

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

910923
void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
911924
unsigned AccessSizeIndex,
912-
Instruction *InsertBefore) {
925+
Instruction *InsertBefore,
926+
DomTreeUpdater &DTU,
927+
LoopInfo &LI) {
913928
assert(!UsePageAliases);
914929
const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
915930

916-
ShadowTagCheckInfo TCI = insertShadowTagCheck(Ptr, InsertBefore);
931+
ShadowTagCheckInfo TCI = insertShadowTagCheck(Ptr, InsertBefore, DTU, LI);
917932

918933
IRBuilder<> IRB(TCI.TagMismatchTerm);
919934
Value *OutOfShortGranuleTagRange =
920935
IRB.CreateICmpUGT(TCI.MemTag, ConstantInt::get(Int8Ty, 15));
921936
Instruction *CheckFailTerm = SplitBlockAndInsertIfThen(
922937
OutOfShortGranuleTagRange, TCI.TagMismatchTerm, !Recover,
923-
MDBuilder(*C).createBranchWeights(1, 100000));
938+
MDBuilder(*C).createBranchWeights(1, 100000), &DTU, &LI);
924939

925940
IRB.SetInsertPoint(TCI.TagMismatchTerm);
926941
Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(TCI.PtrLong, 15), Int8Ty);
927942
PtrLowBits = IRB.CreateAdd(
928943
PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
929944
Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, TCI.MemTag);
930945
SplitBlockAndInsertIfThen(PtrLowBitsOOB, TCI.TagMismatchTerm, false,
931-
MDBuilder(*C).createBranchWeights(1, 100000),
932-
(DomTreeUpdater *)nullptr, nullptr,
933-
CheckFailTerm->getParent());
946+
MDBuilder(*C).createBranchWeights(1, 100000), &DTU,
947+
&LI, CheckFailTerm->getParent());
934948

935949
IRB.SetInsertPoint(TCI.TagMismatchTerm);
936950
Value *InlineTagAddr = IRB.CreateOr(TCI.AddrLong, 15);
937951
InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, Int8PtrTy);
938952
Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
939953
Value *InlineTagMismatch = IRB.CreateICmpNE(TCI.PtrTag, InlineTag);
940954
SplitBlockAndInsertIfThen(InlineTagMismatch, TCI.TagMismatchTerm, false,
941-
MDBuilder(*C).createBranchWeights(1, 100000),
942-
(DomTreeUpdater *)nullptr, nullptr,
943-
CheckFailTerm->getParent());
955+
MDBuilder(*C).createBranchWeights(1, 100000), &DTU,
956+
&LI, CheckFailTerm->getParent());
944957

945958
IRB.SetInsertPoint(CheckFailTerm);
946959
InlineAsm *Asm;
@@ -1015,7 +1028,9 @@ void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
10151028
MI->eraseFromParent();
10161029
}
10171030

1018-
bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
1031+
bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O,
1032+
DomTreeUpdater &DTU,
1033+
LoopInfo &LI) {
10191034
Value *Addr = O.getPtr();
10201035

10211036
LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n");
@@ -1036,9 +1051,11 @@ bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
10361051
IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
10371052
Args);
10381053
} else if (OutlinedChecks) {
1039-
instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
1054+
instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
1055+
DTU, LI);
10401056
} else {
1041-
instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
1057+
instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
1058+
DTU, LI);
10421059
}
10431060
} else {
10441061
SmallVector<Value *, 3> Args{
@@ -1542,8 +1559,13 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
15421559
}
15431560
}
15441561

1562+
DominatorTree *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
1563+
PostDominatorTree *PDT = FAM.getCachedResult<PostDominatorTreeAnalysis>(F);
1564+
LoopInfo *LI = FAM.getCachedResult<LoopAnalysis>(F);
1565+
DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
15451566
for (auto &Operand : OperandsToInstrument)
1546-
instrumentMemAccess(Operand);
1567+
instrumentMemAccess(Operand, DTU, *LI);
1568+
DTU.flush();
15471569

15481570
if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) {
15491571
for (auto *Inst : IntrinToInstrument)

0 commit comments

Comments
 (0)