Skip to content

Commit 917f646

Browse files
author
git apple-llvm automerger
committed
Merge commit '8bd39c5d667a' from apple/main into swift/next
2 parents e7a0642 + 8bd39c5 commit 917f646

File tree

2 files changed

+127
-35
lines changed

2 files changed

+127
-35
lines changed

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,11 +2329,44 @@ bool IndVarSimplify::sinkUnusedInvariants(Loop *L) {
23292329
return MadeAnyChanges;
23302330
}
23312331

2332+
// Returns true if the condition of \p BI being checked is invariant and can be
2333+
// proved to be trivially true.
2334+
static bool isTrivialCond(const Loop *L, BranchInst *BI, ScalarEvolution *SE,
2335+
bool ProvingLoopExit) {
2336+
ICmpInst::Predicate Pred;
2337+
Value *LHS, *RHS;
2338+
using namespace PatternMatch;
2339+
BasicBlock *TrueSucc, *FalseSucc;
2340+
if (!match(BI, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
2341+
m_BasicBlock(TrueSucc), m_BasicBlock(FalseSucc))))
2342+
return false;
2343+
2344+
assert((L->contains(TrueSucc) != L->contains(FalseSucc)) &&
2345+
"Not a loop exit!");
2346+
2347+
// 'LHS pred RHS' should now mean that we stay in loop.
2348+
if (L->contains(FalseSucc))
2349+
Pred = CmpInst::getInversePredicate(Pred);
2350+
2351+
// If we are proving loop exit, invert the predicate.
2352+
if (ProvingLoopExit)
2353+
Pred = CmpInst::getInversePredicate(Pred);
2354+
2355+
const SCEV *LHSS = SE->getSCEVAtScope(LHS, L);
2356+
const SCEV *RHSS = SE->getSCEVAtScope(RHS, L);
2357+
// Can we prove it to be trivially true?
2358+
if (SE->isKnownPredicate(Pred, LHSS, RHSS))
2359+
return true;
2360+
2361+
return false;
2362+
}
2363+
23322364
bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
23332365
SmallVector<BasicBlock*, 16> ExitingBlocks;
23342366
L->getExitingBlocks(ExitingBlocks);
23352367

2336-
// Remove all exits which aren't both rewriteable and analyzeable.
2368+
// Remove all exits which aren't both rewriteable and execute on every
2369+
// iteration.
23372370
auto NewEnd = llvm::remove_if(ExitingBlocks, [&](BasicBlock *ExitingBB) {
23382371
// If our exitting block exits multiple loops, we can only rewrite the
23392372
// innermost one. Otherwise, we're changing how many times the innermost
@@ -2350,9 +2383,10 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
23502383
if (isa<Constant>(BI->getCondition()))
23512384
return true;
23522385

2353-
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
2354-
if (isa<SCEVCouldNotCompute>(ExitCount))
2386+
// Likewise, the loop latch must be dominated by the exiting BB.
2387+
if (!DT->dominates(ExitingBB, L->getLoopLatch()))
23552388
return true;
2389+
23562390
return false;
23572391
});
23582392
ExitingBlocks.erase(NewEnd, ExitingBlocks.end());
@@ -2365,10 +2399,9 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
23652399
if (isa<SCEVCouldNotCompute>(MaxExitCount))
23662400
return false;
23672401

2368-
// Visit our exit blocks in order of dominance. We know from the fact that
2369-
// all exits (left) are analyzeable that the must be a total dominance order
2370-
// between them as each must dominate the latch. The visit order only
2371-
// matters for the provably equal case.
2402+
// Visit our exit blocks in order of dominance. We know from the fact that
2403+
// all exits must dominate the latch, so there is a total dominance order
2404+
// between them.
23722405
llvm::sort(ExitingBlocks,
23732406
[&](BasicBlock *A, BasicBlock *B) {
23742407
// std::sort sorts in ascending order, so we want the inverse of
@@ -2399,7 +2432,20 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
23992432
SmallSet<const SCEV*, 8> DominatingExitCounts;
24002433
for (BasicBlock *ExitingBB : ExitingBlocks) {
24012434
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
2402-
assert(!isa<SCEVCouldNotCompute>(ExitCount) && "checked above");
2435+
if (isa<SCEVCouldNotCompute>(ExitCount)) {
2436+
// Okay, we do not know the exit count here. Can we at least prove that it
2437+
// will remain the same within iteration space?
2438+
auto *BI = cast<BranchInst>(ExitingBB->getTerminator());
2439+
if (isTrivialCond(L, BI, SE, false)) {
2440+
FoldExit(ExitingBB, false);
2441+
Changed = true;
2442+
}
2443+
if (isTrivialCond(L, BI, SE, true)) {
2444+
FoldExit(ExitingBB, true);
2445+
Changed = true;
2446+
}
2447+
continue;
2448+
}
24032449

24042450
// If we know we'd exit on the first iteration, rewrite the exit to
24052451
// reflect this. This does not imply the loop must exit through this

llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -176,32 +176,18 @@ define i32 @func_11() nounwind uwtable {
176176
; CHECK-NEXT: entry:
177177
; CHECK-NEXT: br label [[FORCOND:%.*]]
178178
; CHECK: forcond:
179-
; CHECK-NEXT: [[__KEY6_0:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[TMP37:%.*]], [[NOASSERT:%.*]] ]
180-
; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[__KEY6_0]], 10
181-
; CHECK-NEXT: br i1 [[EXITCOND1]], label [[NOASSERT]], label [[FORCOND38_PREHEADER:%.*]]
179+
; CHECK-NEXT: br i1 false, label [[NOASSERT:%.*]], label [[FORCOND38_PREHEADER:%.*]]
182180
; CHECK: forcond38.preheader:
183181
; CHECK-NEXT: br label [[FORCOND38:%.*]]
184182
; CHECK: noassert:
185-
; CHECK-NEXT: [[TMP13:%.*]] = sdiv i32 -32768, [[__KEY6_0]]
186-
; CHECK-NEXT: [[TMP2936:%.*]] = shl i32 [[TMP13]], 24
187-
; CHECK-NEXT: [[SEXT23:%.*]] = shl i32 [[TMP13]], 24
188-
; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i32 [[TMP2936]], [[SEXT23]]
189-
; CHECK-NEXT: [[TMP37]] = add nuw nsw i32 [[__KEY6_0]], 1
190-
; CHECK-NEXT: br i1 [[TMP32]], label [[FORCOND]], label [[ASSERT33:%.*]]
183+
; CHECK-NEXT: br i1 true, label [[FORCOND]], label [[ASSERT33:%.*]]
191184
; CHECK: assert33:
192185
; CHECK-NEXT: tail call void @llvm.trap()
193186
; CHECK-NEXT: unreachable
194187
; CHECK: forcond38:
195-
; CHECK-NEXT: [[__KEY8_0:%.*]] = phi i32 [ [[TMP81:%.*]], [[NOASSERT68:%.*]] ], [ 2, [[FORCOND38_PREHEADER]] ]
196-
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[__KEY8_0]], 10
197-
; CHECK-NEXT: br i1 [[EXITCOND]], label [[NOASSERT68]], label [[UNROLLEDEND:%.*]]
188+
; CHECK-NEXT: br i1 false, label [[NOASSERT68:%.*]], label [[UNROLLEDEND:%.*]]
198189
; CHECK: noassert68:
199-
; CHECK-NEXT: [[TMP57:%.*]] = sdiv i32 -32768, [[__KEY8_0]]
200-
; CHECK-NEXT: [[SEXT34:%.*]] = shl i32 [[TMP57]], 16
201-
; CHECK-NEXT: [[SEXT21:%.*]] = shl i32 [[TMP57]], 16
202-
; CHECK-NEXT: [[TMP76:%.*]] = icmp eq i32 [[SEXT34]], [[SEXT21]]
203-
; CHECK-NEXT: [[TMP81]] = add nuw nsw i32 [[__KEY8_0]], 1
204-
; CHECK-NEXT: br i1 [[TMP76]], label [[FORCOND38]], label [[ASSERT77:%.*]]
190+
; CHECK-NEXT: br i1 true, label [[FORCOND38]], label [[ASSERT77:%.*]]
205191
; CHECK: assert77:
206192
; CHECK-NEXT: tail call void @llvm.trap()
207193
; CHECK-NEXT: unreachable
@@ -252,6 +238,73 @@ unrolledend: ; preds = %forcond38
252238
ret i32 0
253239
}
254240

241+
define i32 @func_11_flipped() nounwind uwtable {
242+
; CHECK-LABEL: @func_11_flipped(
243+
; CHECK-NEXT: entry:
244+
; CHECK-NEXT: br label [[FORCOND:%.*]]
245+
; CHECK: forcond:
246+
; CHECK-NEXT: br i1 true, label [[FORCOND38_PREHEADER:%.*]], label [[NOASSERT:%.*]]
247+
; CHECK: forcond38.preheader:
248+
; CHECK-NEXT: br label [[FORCOND38:%.*]]
249+
; CHECK: noassert:
250+
; CHECK-NEXT: br i1 true, label [[FORCOND]], label [[ASSERT33:%.*]]
251+
; CHECK: assert33:
252+
; CHECK-NEXT: tail call void @llvm.trap()
253+
; CHECK-NEXT: unreachable
254+
; CHECK: forcond38:
255+
; CHECK-NEXT: br i1 false, label [[NOASSERT68:%.*]], label [[UNROLLEDEND:%.*]]
256+
; CHECK: noassert68:
257+
; CHECK-NEXT: br i1 true, label [[FORCOND38]], label [[ASSERT77:%.*]]
258+
; CHECK: assert77:
259+
; CHECK-NEXT: tail call void @llvm.trap()
260+
; CHECK-NEXT: unreachable
261+
; CHECK: unrolledend:
262+
; CHECK-NEXT: ret i32 0
263+
;
264+
entry:
265+
br label %forcond
266+
267+
forcond: ; preds = %noassert, %entry
268+
%__key6.0 = phi i32 [ 2, %entry ], [ %tmp37, %noassert ]
269+
%tmp5 = icmp sge i32 %__key6.0, 10
270+
br i1 %tmp5, label %forcond38.preheader, label %noassert
271+
272+
forcond38.preheader: ; preds = %forcond
273+
br label %forcond38
274+
275+
noassert: ; preds = %forbody
276+
%tmp13 = sdiv i32 -32768, %__key6.0
277+
%tmp2936 = shl i32 %tmp13, 24
278+
%sext23 = shl i32 %tmp13, 24
279+
%tmp32 = icmp eq i32 %tmp2936, %sext23
280+
%tmp37 = add i32 %__key6.0, 1
281+
br i1 %tmp32, label %forcond, label %assert33
282+
283+
assert33: ; preds = %noassert
284+
tail call void @llvm.trap()
285+
unreachable
286+
287+
forcond38: ; preds = %noassert68, %forcond38.preheader
288+
%__key8.0 = phi i32 [ %tmp81, %noassert68 ], [ 2, %forcond38.preheader ]
289+
%tmp46 = icmp slt i32 %__key8.0, 10
290+
br i1 %tmp46, label %noassert68, label %unrolledend
291+
292+
noassert68: ; preds = %forbody39
293+
%tmp57 = sdiv i32 -32768, %__key8.0
294+
%sext34 = shl i32 %tmp57, 16
295+
%sext21 = shl i32 %tmp57, 16
296+
%tmp76 = icmp eq i32 %sext34, %sext21
297+
%tmp81 = add i32 %__key8.0, 1
298+
br i1 %tmp76, label %forcond38, label %assert77
299+
300+
assert77: ; preds = %noassert68
301+
tail call void @llvm.trap()
302+
unreachable
303+
304+
unrolledend: ; preds = %forcond38
305+
ret i32 0
306+
}
307+
255308
declare void @llvm.trap() noreturn nounwind
256309

257310
; In this case the second loop only has a single iteration, fold the header away
@@ -260,18 +313,11 @@ define i32 @func_12() nounwind uwtable {
260313
; CHECK-NEXT: entry:
261314
; CHECK-NEXT: br label [[FORCOND:%.*]]
262315
; CHECK: forcond:
263-
; CHECK-NEXT: [[__KEY6_0:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[TMP37:%.*]], [[NOASSERT:%.*]] ]
264-
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[__KEY6_0]], 10
265-
; CHECK-NEXT: br i1 [[EXITCOND]], label [[NOASSERT]], label [[FORCOND38_PREHEADER:%.*]]
316+
; CHECK-NEXT: br i1 false, label [[NOASSERT:%.*]], label [[FORCOND38_PREHEADER:%.*]]
266317
; CHECK: forcond38.preheader:
267318
; CHECK-NEXT: br label [[FORCOND38:%.*]]
268319
; CHECK: noassert:
269-
; CHECK-NEXT: [[TMP13:%.*]] = sdiv i32 -32768, [[__KEY6_0]]
270-
; CHECK-NEXT: [[TMP2936:%.*]] = shl i32 [[TMP13]], 24
271-
; CHECK-NEXT: [[SEXT23:%.*]] = shl i32 [[TMP13]], 24
272-
; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i32 [[TMP2936]], [[SEXT23]]
273-
; CHECK-NEXT: [[TMP37]] = add nuw nsw i32 [[__KEY6_0]], 1
274-
; CHECK-NEXT: br i1 [[TMP32]], label [[FORCOND]], label [[ASSERT33:%.*]]
320+
; CHECK-NEXT: br i1 true, label [[FORCOND]], label [[ASSERT33:%.*]]
275321
; CHECK: assert33:
276322
; CHECK-NEXT: tail call void @llvm.trap()
277323
; CHECK-NEXT: unreachable

0 commit comments

Comments
 (0)