Skip to content

Commit 4f32f5d

Browse files
authored
[AA][JumpThreading] Don't use DomTree for AA in JumpThreading (#79294)
JumpThreading may perform AA queries while the dominator tree is not up to date, which may result in miscompilations. Fix this by adding a new AAQI option to disable the use of the dominator tree in BasicAA. Fixes #79175.
1 parent e538486 commit 4f32f5d

File tree

5 files changed

+24
-9
lines changed

5 files changed

+24
-9
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ class AAQueryInfo {
287287
/// store %l, ...
288288
bool MayBeCrossIteration = false;
289289

290+
/// Whether alias analysis is allowed to use the dominator tree, for use by
291+
/// passes that lazily update the DT while performing AA queries.
292+
bool UseDominatorTree = true;
293+
290294
AAQueryInfo(AAResults &AAR, CaptureInfo *CI) : AAR(AAR), CI(CI) {}
291295
};
292296

@@ -668,6 +672,9 @@ class BatchAAResults {
668672
void enableCrossIterationMode() {
669673
AAQI.MayBeCrossIteration = true;
670674
}
675+
676+
/// Disable the use of the dominator tree during alias analysis queries.
677+
void disableDominatorTree() { AAQI.UseDominatorTree = false; }
671678
};
672679

673680
/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis

llvm/include/llvm/Analysis/BasicAliasAnalysis.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,26 @@ class BasicAAResult : public AAResultBase {
4343
const Function &F;
4444
const TargetLibraryInfo &TLI;
4545
AssumptionCache ∾
46-
DominatorTree *DT;
46+
/// Use getDT() instead of accessing this member directly, in order to
47+
/// respect the AAQI.UseDominatorTree option.
48+
DominatorTree *DT_;
49+
50+
DominatorTree *getDT(const AAQueryInfo &AAQI) const {
51+
return AAQI.UseDominatorTree ? DT_ : nullptr;
52+
}
4753

4854
public:
4955
BasicAAResult(const DataLayout &DL, const Function &F,
5056
const TargetLibraryInfo &TLI, AssumptionCache &AC,
5157
DominatorTree *DT = nullptr)
52-
: DL(DL), F(F), TLI(TLI), AC(AC), DT(DT) {}
58+
: DL(DL), F(F), TLI(TLI), AC(AC), DT_(DT) {}
5359

5460
BasicAAResult(const BasicAAResult &Arg)
5561
: AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC),
56-
DT(Arg.DT) {}
62+
DT_(Arg.DT_) {}
5763
BasicAAResult(BasicAAResult &&Arg)
5864
: AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI),
59-
AC(Arg.AC), DT(Arg.DT) {}
65+
AC(Arg.AC), DT_(Arg.DT_) {}
6066

6167
/// Handle invalidation events in the new pass manager.
6268
bool invalidate(Function &Fn, const PreservedAnalyses &PA,

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA,
8989
// may be created without handles to some analyses and in that case don't
9090
// depend on them.
9191
if (Inv.invalidate<AssumptionAnalysis>(Fn, PA) ||
92-
(DT && Inv.invalidate<DominatorTreeAnalysis>(Fn, PA)))
92+
(DT_ && Inv.invalidate<DominatorTreeAnalysis>(Fn, PA)))
9393
return true;
9494

9595
// Otherwise this analysis result remains valid.
@@ -1063,6 +1063,7 @@ AliasResult BasicAAResult::aliasGEP(
10631063
: AliasResult::MayAlias;
10641064
}
10651065

1066+
DominatorTree *DT = getDT(AAQI);
10661067
DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT);
10671068
DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT);
10681069

@@ -1556,6 +1557,7 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
15561557
const Value *HintO1 = getUnderlyingObject(Hint1);
15571558
const Value *HintO2 = getUnderlyingObject(Hint2);
15581559

1560+
DominatorTree *DT = getDT(AAQI);
15591561
auto ValidAssumeForPtrContext = [&](const Value *Ptr) {
15601562
if (const Instruction *PtrI = dyn_cast<Instruction>(Ptr)) {
15611563
return isValidAssumeForContext(Assume, PtrI, DT,
@@ -1735,7 +1737,7 @@ bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
17351737
if (!Inst || Inst->getParent()->isEntryBlock())
17361738
return true;
17371739

1738-
return isNotInCycle(Inst, DT, /*LI*/ nullptr);
1740+
return isNotInCycle(Inst, getDT(AAQI), /*LI*/ nullptr);
17391741
}
17401742

17411743
/// Computes the symbolic difference between two de-composed GEPs.

llvm/lib/Transforms/Scalar/JumpThreading.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,8 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
12611261
BasicBlock::iterator BBIt(LoadI);
12621262
bool IsLoadCSE;
12631263
BatchAAResults BatchAA(*AA);
1264+
// The dominator tree is updated lazily and may not be valid at this point.
1265+
BatchAA.disableDominatorTree();
12641266
if (Value *AvailableVal = FindAvailableLoadedValue(
12651267
LoadI, LoadBB, BBIt, DefMaxInstsToScan, &BatchAA, &IsLoadCSE)) {
12661268
// If the value of the load is locally available within the block, just use

llvm/test/Transforms/JumpThreading/pr79175.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
@f = external global i32
55

66
; Make sure the value of @f is reloaded prior to the final comparison.
7-
; FIXME: This is a miscompile.
87
define i32 @test(i64 %idx, i32 %val) {
98
; CHECK-LABEL: define i32 @test(
109
; CHECK-SAME: i64 [[IDX:%.*]], i32 [[VAL:%.*]]) {
@@ -20,13 +19,12 @@ define i32 @test(i64 %idx, i32 %val) {
2019
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[CMP_I]]
2120
; CHECK-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP0:%.*]]
2221
; CHECK: cond.end.thread:
23-
; CHECK-NEXT: [[F_RELOAD_PR:%.*]] = load i32, ptr @f, align 4
2422
; CHECK-NEXT: br label [[TMP0]]
2523
; CHECK: 0:
26-
; CHECK-NEXT: [[F_RELOAD:%.*]] = phi i32 [ [[F]], [[COND_END]] ], [ [[F_RELOAD_PR]], [[COND_END_THREAD]] ]
2724
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ 0, [[COND_END_THREAD]] ], [ [[VAL]], [[COND_END]] ]
2825
; CHECK-NEXT: [[F_IDX:%.*]] = getelementptr inbounds i32, ptr @f, i64 [[IDX]]
2926
; CHECK-NEXT: store i32 [[TMP1]], ptr [[F_IDX]], align 4
27+
; CHECK-NEXT: [[F_RELOAD:%.*]] = load i32, ptr @f, align 4
3028
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[F_RELOAD]], 1
3129
; CHECK-NEXT: br i1 [[CMP3]], label [[RETURN2:%.*]], label [[RETURN]]
3230
; CHECK: return:

0 commit comments

Comments
 (0)