Skip to content

Commit 0cbb8ec

Browse files
committed
Revert "[AssumptionCache] caches @llvm.experimental.guard's"
This reverts commit f9599bb. For some reason it caused us a huge compile time regression in downstream workloads. Not sure whether the source of it is in upstream code ir not. Temporarily reverting until investigated. Differential Revision: https://reviews.llvm.org/D142330
1 parent 3e84fc8 commit 0cbb8ec

File tree

11 files changed

+85
-57
lines changed

11 files changed

+85
-57
lines changed

llvm/include/llvm/Analysis/AssumptionCache.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
namespace llvm {
2828

29-
class CondGuardInst;
29+
class AssumeInst;
3030
class Function;
3131
class raw_ostream;
3232
class TargetTransformInfo;
@@ -120,15 +120,15 @@ class AssumptionCache {
120120
///
121121
/// The call passed in must be an instruction within this function and must
122122
/// not already be in the cache.
123-
void registerAssumption(CondGuardInst *CI);
123+
void registerAssumption(AssumeInst *CI);
124124

125125
/// Remove an \@llvm.assume intrinsic from this function's cache if it has
126126
/// been added to the cache earlier.
127-
void unregisterAssumption(CondGuardInst *CI);
127+
void unregisterAssumption(AssumeInst *CI);
128128

129129
/// Update the cache of values being affected by this assumption (i.e.
130130
/// the values about which this assumption provides information).
131-
void updateAffectedValues(CondGuardInst *CI);
131+
void updateAffectedValues(AssumeInst *CI);
132132

133133
/// Clear the cache of \@llvm.assume intrinsics for a function.
134134
///

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,20 +1513,9 @@ class GCResultInst : public GCProjectionInst {
15131513
}
15141514
};
15151515

1516-
/// This represents intrinsics that guard a condition
1517-
class CondGuardInst : public IntrinsicInst {
1518-
public:
1519-
static bool classof(const IntrinsicInst *I) {
1520-
return I->getIntrinsicID() == Intrinsic::assume ||
1521-
I->getIntrinsicID() == Intrinsic::experimental_guard;
1522-
}
1523-
static bool classof(const Value *V) {
1524-
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1525-
}
1526-
};
15271516

15281517
/// This represents the llvm.assume intrinsic.
1529-
class AssumeInst : public CondGuardInst {
1518+
class AssumeInst : public IntrinsicInst {
15301519
public:
15311520
static bool classof(const IntrinsicInst *I) {
15321521
return I->getIntrinsicID() == Intrinsic::assume;

llvm/lib/Analysis/AssumeBundleQueries.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ llvm::getKnowledgeForValue(const Value *V,
162162
return RetainedKnowledge::none();
163163
if (AC) {
164164
for (AssumptionCache::ResultElem &Elem : AC->assumptionsFor(V)) {
165-
auto *II = dyn_cast_or_null<AssumeInst>(Elem.Assume);
165+
auto *II = cast_or_null<AssumeInst>(Elem.Assume);
166166
if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
167167
continue;
168168
if (RetainedKnowledge RK = getKnowledgeFromBundle(

llvm/lib/Analysis/AssumptionCache.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file contains a pass that keeps track of @llvm.assume and
10-
// @llvm.experimental.guard intrinsics in the functions of a module.
9+
// This file contains a pass that keeps track of @llvm.assume intrinsics in
10+
// the functions of a module.
1111
//
1212
//===----------------------------------------------------------------------===//
1313

@@ -140,7 +140,7 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
140140
}
141141
}
142142

143-
void AssumptionCache::updateAffectedValues(CondGuardInst *CI) {
143+
void AssumptionCache::updateAffectedValues(AssumeInst *CI) {
144144
SmallVector<AssumptionCache::ResultElem, 16> Affected;
145145
findAffectedValues(CI, TTI, Affected);
146146

@@ -153,7 +153,7 @@ void AssumptionCache::updateAffectedValues(CondGuardInst *CI) {
153153
}
154154
}
155155

156-
void AssumptionCache::unregisterAssumption(CondGuardInst *CI) {
156+
void AssumptionCache::unregisterAssumption(AssumeInst *CI) {
157157
SmallVector<AssumptionCache::ResultElem, 16> Affected;
158158
findAffectedValues(CI, TTI, Affected);
159159

@@ -217,18 +217,18 @@ void AssumptionCache::scanFunction() {
217217
// to this cache.
218218
for (BasicBlock &B : F)
219219
for (Instruction &I : B)
220-
if (isa<CondGuardInst>(&I))
220+
if (isa<AssumeInst>(&I))
221221
AssumeHandles.push_back({&I, ExprResultIdx});
222222

223223
// Mark the scan as complete.
224224
Scanned = true;
225225

226226
// Update affected values.
227227
for (auto &A : AssumeHandles)
228-
updateAffectedValues(cast<CondGuardInst>(A));
228+
updateAffectedValues(cast<AssumeInst>(A));
229229
}
230230

231-
void AssumptionCache::registerAssumption(CondGuardInst *CI) {
231+
void AssumptionCache::registerAssumption(AssumeInst *CI) {
232232
// If we haven't scanned the function yet, just drop this assumption. It will
233233
// be found when we scan later.
234234
if (!Scanned)
@@ -238,9 +238,9 @@ void AssumptionCache::registerAssumption(CondGuardInst *CI) {
238238

239239
#ifndef NDEBUG
240240
assert(CI->getParent() &&
241-
"Cannot a register CondGuardInst not in a basic block");
241+
"Cannot register @llvm.assume call not in a basic block");
242242
assert(&F == CI->getParent()->getParent() &&
243-
"Cannot a register CondGuardInst not in this function");
243+
"Cannot register @llvm.assume call not in this function");
244244

245245
// We expect the number of assumptions to be small, so in an asserts build
246246
// check that we don't accumulate duplicates and that all assumptions point
@@ -252,8 +252,8 @@ void AssumptionCache::registerAssumption(CondGuardInst *CI) {
252252

253253
assert(&F == cast<Instruction>(VH)->getParent()->getParent() &&
254254
"Cached assumption not inside this function!");
255-
assert(isa<CondGuardInst>(VH) &&
256-
"Cached something other than CondGuardInst!");
255+
assert(match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
256+
"Cached something other than a call to @llvm.assume!");
257257
assert(AssumptionSet.insert(VH).second &&
258258
"Cache contains multiple copies of a call!");
259259
}

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,7 +1771,8 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(const SCEV *Op, Type *Ty,
17711771
// these to compute max backedge taken counts, but can still use
17721772
// these to prove lack of overflow. Use this fact to avoid
17731773
// doing extra work that may not pay off.
1774-
if (!isa<SCEVCouldNotCompute>(MaxBECount) || !AC.assumptions().empty()) {
1774+
if (!isa<SCEVCouldNotCompute>(MaxBECount) || HasGuards ||
1775+
!AC.assumptions().empty()) {
17751776

17761777
auto NewFlags = proveNoUnsignedWrapViaInduction(AR);
17771778
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
@@ -5147,7 +5148,8 @@ ScalarEvolution::proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR) {
51475148
// these to prove lack of overflow. Use this fact to avoid
51485149
// doing extra work that may not pay off.
51495150

5150-
if (isa<SCEVCouldNotCompute>(MaxBECount) && AC.assumptions().empty())
5151+
if (isa<SCEVCouldNotCompute>(MaxBECount) && !HasGuards &&
5152+
AC.assumptions().empty())
51515153
return Result;
51525154

51535155
// If the backedge is guarded by a comparison with the pre-inc value the
@@ -5200,7 +5202,8 @@ ScalarEvolution::proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR) {
52005202
// these to prove lack of overflow. Use this fact to avoid
52015203
// doing extra work that may not pay off.
52025204

5203-
if (isa<SCEVCouldNotCompute>(MaxBECount) && AC.assumptions().empty())
5205+
if (isa<SCEVCouldNotCompute>(MaxBECount) && !HasGuards &&
5206+
AC.assumptions().empty())
52045207
return Result;
52055208

52065209
// If the backedge is guarded by a comparison with the pre-inc value the
@@ -11388,7 +11391,7 @@ bool ScalarEvolution::isImpliedViaGuard(const BasicBlock *BB,
1138811391
ICmpInst::Predicate Pred,
1138911392
const SCEV *LHS, const SCEV *RHS) {
1139011393
// No need to even try if we know the module has no guards.
11391-
if (AC.assumptions().empty())
11394+
if (!HasGuards)
1139211395
return false;
1139311396

1139411397
return any_of(*BB, [&](const Instruction &I) {
@@ -11598,6 +11601,15 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
1159811601
return true;
1159911602
}
1160011603

11604+
// Check conditions due to any @llvm.experimental.guard intrinsics.
11605+
auto *GuardDecl = F.getParent()->getFunction(
11606+
Intrinsic::getName(Intrinsic::experimental_guard));
11607+
if (GuardDecl)
11608+
for (const auto *GU : GuardDecl->users())
11609+
if (const auto *Guard = dyn_cast<IntrinsicInst>(GU))
11610+
if (Guard->getFunction() == BB->getParent() && DT.dominates(Guard, BB))
11611+
if (ProveViaCond(Guard->getArgOperand(0), false))
11612+
return true;
1160111613
return false;
1160211614
}
1160311615

@@ -13470,11 +13482,25 @@ ScalarEvolution::ScalarEvolution(Function &F, TargetLibraryInfo &TLI,
1347013482
LoopInfo &LI)
1347113483
: F(F), TLI(TLI), AC(AC), DT(DT), LI(LI),
1347213484
CouldNotCompute(new SCEVCouldNotCompute()), ValuesAtScopes(64),
13473-
LoopDispositions(64), BlockDispositions(64) {}
13485+
LoopDispositions(64), BlockDispositions(64) {
13486+
// To use guards for proving predicates, we need to scan every instruction in
13487+
// relevant basic blocks, and not just terminators. Doing this is a waste of
13488+
// time if the IR does not actually contain any calls to
13489+
// @llvm.experimental.guard, so do a quick check and remember this beforehand.
13490+
//
13491+
// This pessimizes the case where a pass that preserves ScalarEvolution wants
13492+
// to _add_ guards to the module when there weren't any before, and wants
13493+
// ScalarEvolution to optimize based on those guards. For now we prefer to be
13494+
// efficient in lieu of being smart in that rather obscure case.
13495+
13496+
auto *GuardDecl = F.getParent()->getFunction(
13497+
Intrinsic::getName(Intrinsic::experimental_guard));
13498+
HasGuards = GuardDecl && !GuardDecl->use_empty();
13499+
}
1347413500

1347513501
ScalarEvolution::ScalarEvolution(ScalarEvolution &&Arg)
13476-
: F(Arg.F), TLI(Arg.TLI), AC(Arg.AC), DT(Arg.DT), LI(Arg.LI),
13477-
CouldNotCompute(std::move(Arg.CouldNotCompute)),
13502+
: F(Arg.F), HasGuards(Arg.HasGuards), TLI(Arg.TLI), AC(Arg.AC), DT(Arg.DT),
13503+
LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)),
1347813504
ValueExprMap(std::move(Arg.ValueExprMap)),
1347913505
PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)),
1348013506
PendingPhiRanges(std::move(Arg.PendingPhiRanges)),
@@ -15166,7 +15192,16 @@ const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
1516615192
Terms.emplace_back(AssumeI->getOperand(0), true);
1516715193
}
1516815194

15169-
// Second, collect conditions from dominating branches. Starting at the loop
15195+
// Second, collect information from llvm.experimental.guards dominating the loop.
15196+
auto *GuardDecl = F.getParent()->getFunction(
15197+
Intrinsic::getName(Intrinsic::experimental_guard));
15198+
if (GuardDecl)
15199+
for (const auto *GU : GuardDecl->users())
15200+
if (const auto *Guard = dyn_cast<IntrinsicInst>(GU))
15201+
if (Guard->getFunction() == Header->getParent() && DT.dominates(Guard, Header))
15202+
Terms.emplace_back(Guard->getArgOperand(0), true);
15203+
15204+
// Third, collect conditions from dominating branches. Starting at the loop
1517015205
// predecessor, climb up the predecessor chain, as long as there are
1517115206
// predecessors that can be found that have unique successors leading to the
1517215207
// original header.

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -616,14 +616,17 @@ static bool isKnownNonZeroFromAssume(const Value *V, const Query &Q) {
616616
for (auto &AssumeVH : Q.AC->assumptionsFor(V)) {
617617
if (!AssumeVH)
618618
continue;
619-
CondGuardInst *I = cast<CondGuardInst>(AssumeVH);
619+
CallInst *I = cast<CallInst>(AssumeVH);
620620
assert(I->getFunction() == Q.CxtI->getFunction() &&
621621
"Got assumption for the wrong function!");
622622

623623
// Warning: This loop can end up being somewhat performance sensitive.
624624
// We're running this loop for once for each value queried resulting in a
625625
// runtime of ~O(#assumes * #values).
626626

627+
assert(I->getCalledFunction()->getIntrinsicID() == Intrinsic::assume &&
628+
"must be an assume intrinsic");
629+
627630
Value *RHS;
628631
CmpInst::Predicate Pred;
629632
auto m_V = m_CombineOr(m_Specific(V), m_PtrToInt(m_Specific(V)));
@@ -661,14 +664,17 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
661664
for (auto &AssumeVH : Q.AC->assumptionsFor(V)) {
662665
if (!AssumeVH)
663666
continue;
664-
CondGuardInst *I = cast<CondGuardInst>(AssumeVH);
667+
CallInst *I = cast<CallInst>(AssumeVH);
665668
assert(I->getParent()->getParent() == Q.CxtI->getParent()->getParent() &&
666669
"Got assumption for the wrong function!");
667670

668671
// Warning: This loop can end up being somewhat performance sensitive.
669672
// We're running this loop for once for each value queried resulting in a
670673
// runtime of ~O(#assumes * #values).
671674

675+
assert(I->getCalledFunction()->getIntrinsicID() == Intrinsic::assume &&
676+
"must be an assume intrinsic");
677+
672678
Value *Arg = I->getArgOperand(0);
673679

674680
if (Arg == V && isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
@@ -7492,9 +7498,11 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
74927498
for (auto &AssumeVH : AC->assumptionsFor(V)) {
74937499
if (!AssumeVH)
74947500
continue;
7495-
IntrinsicInst *I = cast<IntrinsicInst>(AssumeVH);
7501+
CallInst *I = cast<CallInst>(AssumeVH);
74967502
assert(I->getParent()->getParent() == CtxI->getParent()->getParent() &&
74977503
"Got assumption for the wrong function!");
7504+
assert(I->getCalledFunction()->getIntrinsicID() == Intrinsic::assume &&
7505+
"must be an assume intrinsic");
74987506

74997507
if (!isValidAssumeForContext(I, CtxI, DT))
75007508
continue;

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,14 +1649,14 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
16491649
}
16501650
}
16511651

1652-
// Remove CondGuardInsts that will be moved to the new function from the old
1653-
// function's assumption cache.
1652+
// Remove @llvm.assume calls that will be moved to the new function from the
1653+
// old function's assumption cache.
16541654
for (BasicBlock *Block : Blocks) {
16551655
for (Instruction &I : llvm::make_early_inc_range(*Block)) {
1656-
if (auto *CI = dyn_cast<CondGuardInst>(&I)) {
1656+
if (auto *AI = dyn_cast<AssumeInst>(&I)) {
16571657
if (AC)
1658-
AC->unregisterAssumption(CI);
1659-
CI->eraseFromParent();
1658+
AC->unregisterAssumption(AI);
1659+
AI->eraseFromParent();
16601660
}
16611661
}
16621662
}
@@ -1850,7 +1850,7 @@ bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
18501850
const Function &NewFunc,
18511851
AssumptionCache *AC) {
18521852
for (auto AssumeVH : AC->assumptions()) {
1853-
auto *I = dyn_cast_or_null<CondGuardInst>(AssumeVH);
1853+
auto *I = dyn_cast_or_null<CallInst>(AssumeVH);
18541854
if (!I)
18551855
continue;
18561856

@@ -1862,7 +1862,7 @@ bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
18621862
// that were previously in the old function, but that have now been moved
18631863
// to the new function.
18641864
for (auto AffectedValVH : AC->assumptionsFor(I->getOperand(0))) {
1865-
auto *AffectedCI = dyn_cast_or_null<CondGuardInst>(AffectedValVH);
1865+
auto *AffectedCI = dyn_cast_or_null<CallInst>(AffectedValVH);
18661866
if (!AffectedCI)
18671867
continue;
18681868
if (AffectedCI->getFunction() != &OldFunc)

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
23332333
for (BasicBlock &NewBlock :
23342334
make_range(FirstNewBlock->getIterator(), Caller->end()))
23352335
for (Instruction &I : NewBlock)
2336-
if (auto *II = dyn_cast<CondGuardInst>(&I))
2336+
if (auto *II = dyn_cast<AssumeInst>(&I))
23372337
IFI.GetAssumptionCache(*Caller).registerAssumption(II);
23382338
}
23392339

llvm/test/Analysis/AssumptionCache/basic.ll

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
44

55
declare void @llvm.assume(i1)
6-
declare void @llvm.experimental.guard(i1, ...)
76

87
define void @test1(i32 %a) {
98
; CHECK-LABEL: Cached assumptions for function: test1
109
; CHECK-NEXT: icmp ne i32 %{{.*}}, 0
1110
; CHECK-NEXT: icmp slt i32 %{{.*}}, 0
1211
; CHECK-NEXT: icmp sgt i32 %{{.*}}, 0
13-
; CHECK-NEXT: icmp ult i32 %{{.*}}, 0
14-
; CHECK-NEXT: icmp ugt i32 %{{.*}}, 0
1512

1613
entry:
1714
%cond1 = icmp ne i32 %a, 0
@@ -20,10 +17,6 @@ entry:
2017
call void @llvm.assume(i1 %cond2)
2118
%cond3 = icmp sgt i32 %a, 0
2219
call void @llvm.assume(i1 %cond3)
23-
%cond4 = icmp ult i32 %a, 0
24-
call void (i1, ...) @llvm.experimental.guard(i1 %cond4) [ "deopt"() ]
25-
%cond5 = icmp ugt i32 %a, 0
26-
call void (i1, ...) @llvm.experimental.guard(i1 %cond5) [ "deopt"() ]
2720

2821
ret void
2922
}

llvm/test/Analysis/ScalarEvolution/guards.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ entry:
8686
loop:
8787
; CHECK: loop:
8888
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
89-
; CHECK: %iv.inc.cmp = icmp ult i32 %iv.inc, %len
89+
; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len
9090
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
9191
; CHECK: leave:
9292
%iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
@@ -129,7 +129,7 @@ left:
129129

130130
be:
131131
; CHECK: be:
132-
; CHECK-NEXT: %iv.cmp = icmp ult i32 %iv, %len
132+
; CHECK-NEXT: %iv.cmp = icmp slt i32 %iv, %len
133133
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
134134
; CHECK: leave:
135135

0 commit comments

Comments
 (0)