Skip to content

Commit

Permalink
[AA][JumpThreading] Don't use DomTree for AA in JumpThreading (#79294)
Browse files Browse the repository at this point in the history
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.

(cherry picked from commit 4f32f5d)
  • Loading branch information
nikic authored and tstellar committed Feb 5, 2024
1 parent a581690 commit 28879ab
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 9 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ class AAQueryInfo {
/// store %l, ...
bool MayBeCrossIteration = false;

/// Whether alias analysis is allowed to use the dominator tree, for use by
/// passes that lazily update the DT while performing AA queries.
bool UseDominatorTree = true;

AAQueryInfo(AAResults &AAR, CaptureInfo *CI) : AAR(AAR), CI(CI) {}
};

Expand Down Expand Up @@ -668,6 +672,9 @@ class BatchAAResults {
void enableCrossIterationMode() {
AAQI.MayBeCrossIteration = true;
}

/// Disable the use of the dominator tree during alias analysis queries.
void disableDominatorTree() { AAQI.UseDominatorTree = false; }
};

/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis
Expand Down
14 changes: 10 additions & 4 deletions llvm/include/llvm/Analysis/BasicAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,26 @@ class BasicAAResult : public AAResultBase {
const Function &F;
const TargetLibraryInfo &TLI;
AssumptionCache ∾
DominatorTree *DT;
/// Use getDT() instead of accessing this member directly, in order to
/// respect the AAQI.UseDominatorTree option.
DominatorTree *DT_;

DominatorTree *getDT(const AAQueryInfo &AAQI) const {
return AAQI.UseDominatorTree ? DT_ : nullptr;
}

public:
BasicAAResult(const DataLayout &DL, const Function &F,
const TargetLibraryInfo &TLI, AssumptionCache &AC,
DominatorTree *DT = nullptr)
: DL(DL), F(F), TLI(TLI), AC(AC), DT(DT) {}
: DL(DL), F(F), TLI(TLI), AC(AC), DT_(DT) {}

BasicAAResult(const BasicAAResult &Arg)
: AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC),
DT(Arg.DT) {}
DT_(Arg.DT_) {}
BasicAAResult(BasicAAResult &&Arg)
: AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI),
AC(Arg.AC), DT(Arg.DT) {}
AC(Arg.AC), DT_(Arg.DT_) {}

/// Handle invalidation events in the new pass manager.
bool invalidate(Function &Fn, const PreservedAnalyses &PA,
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Analysis/BasicAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA,
// may be created without handles to some analyses and in that case don't
// depend on them.
if (Inv.invalidate<AssumptionAnalysis>(Fn, PA) ||
(DT && Inv.invalidate<DominatorTreeAnalysis>(Fn, PA)))
(DT_ && Inv.invalidate<DominatorTreeAnalysis>(Fn, PA)))
return true;

// Otherwise this analysis result remains valid.
Expand Down Expand Up @@ -1063,6 +1063,7 @@ AliasResult BasicAAResult::aliasGEP(
: AliasResult::MayAlias;
}

DominatorTree *DT = getDT(AAQI);
DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT);
DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT);

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

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

return isNotInCycle(Inst, DT, /*LI*/ nullptr);
return isNotInCycle(Inst, getDT(AAQI), /*LI*/ nullptr);
}

/// Computes the symbolic difference between two de-composed GEPs.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Transforms/Scalar/JumpThreading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,8 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
BasicBlock::iterator BBIt(LoadI);
bool IsLoadCSE;
BatchAAResults BatchAA(*AA);
// The dominator tree is updated lazily and may not be valid at this point.
BatchAA.disableDominatorTree();
if (Value *AvailableVal = FindAvailableLoadedValue(
LoadI, LoadBB, BBIt, DefMaxInstsToScan, &BatchAA, &IsLoadCSE)) {
// If the value of the load is locally available within the block, just use
Expand Down
4 changes: 1 addition & 3 deletions llvm/test/Transforms/JumpThreading/pr79175.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
@f = external global i32

; Make sure the value of @f is reloaded prior to the final comparison.
; FIXME: This is a miscompile.
define i32 @test(i64 %idx, i32 %val) {
; CHECK-LABEL: define i32 @test(
; CHECK-SAME: i64 [[IDX:%.*]], i32 [[VAL:%.*]]) {
Expand All @@ -20,13 +19,12 @@ define i32 @test(i64 %idx, i32 %val) {
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[CMP_I]]
; CHECK-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP0:%.*]]
; CHECK: cond.end.thread:
; CHECK-NEXT: [[F_RELOAD_PR:%.*]] = load i32, ptr @f, align 4
; CHECK-NEXT: br label [[TMP0]]
; CHECK: 0:
; CHECK-NEXT: [[F_RELOAD:%.*]] = phi i32 [ [[F]], [[COND_END]] ], [ [[F_RELOAD_PR]], [[COND_END_THREAD]] ]
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ 0, [[COND_END_THREAD]] ], [ [[VAL]], [[COND_END]] ]
; CHECK-NEXT: [[F_IDX:%.*]] = getelementptr inbounds i32, ptr @f, i64 [[IDX]]
; CHECK-NEXT: store i32 [[TMP1]], ptr [[F_IDX]], align 4
; CHECK-NEXT: [[F_RELOAD:%.*]] = load i32, ptr @f, align 4
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[F_RELOAD]], 1
; CHECK-NEXT: br i1 [[CMP3]], label [[RETURN2:%.*]], label [[RETURN]]
; CHECK: return:
Expand Down

0 comments on commit 28879ab

Please sign in to comment.