| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This patch reverts rL311205 that was initially a wrong fix. The real problem
was in intersection of signed and unsigned ranges (see rL316552), and the
patch being reverted masked the problem instead of fixing it.
By now, the test against which rL311205 was made works OK even without this
code. This revert patch also contains a test case that demonstrates incorrect
behavior caused by rL311205: it is caused by incorrect choise of signed max
instead of unsigned.
llvm-svn: 317088
|
| |
|
|
|
|
|
|
|
|
| |
Rename `Offset`, `Scale`, `Length` into `Begin`, `Step`, `End` respectively
to make naming of similar entities for Ranges and Range Checks more
consistent.
Differential Revision: https://reviews.llvm.org/D39414
llvm-svn: 316979
|
| |
|
|
| |
llvm-svn: 316889
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
IRCE for unsigned latch conditions was temporarily disabled by rL314881. The motivating
example contained an unsigned latch condition and a signed range check. One of the safe
iteration ranges was `[1, SINT_MAX + 1]`. Its right border was incorrectly interpreted as a negative
value in `IntersectRange` function, this lead to a miscompile under which we deleted a range check
without inserting a postloop where it was needed.
This patch brings back IRCE for unsigned latch conditions. Now we treat range intersection more
carefully. If the latch condition was unsigned, we only try to consider a range check for deletion if:
1. The range check is also unsigned, or
2. Safe iteration range of the range check lies within `[0, SINT_MAX]`.
The same is done for signed latch.
Values from `[0, SINT_MAX]` are unambiguous, these values are non-negative under any interpretation,
and all values of a range intersected with such range are also non-negative.
We also use signed/unsigned min/max functions for range intersection depending on type of the
latch condition.
Differential Revision: https://reviews.llvm.org/D38581
llvm-svn: 316552
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For a SCEV range, this patch replaces the naive emptiness check for SCEV ranges
which looks like `Begin == End` with a SCEV check. The range is guaranteed to be
empty of `Begin >= End`. We should filter such ranges out and do not try to perform
IRCE for them.
For example, we can get such range when intersecting range `[A, B)` and `[C, D)`
where `A < B < C < D`. The resulting range is `[max(A, C), min(B, D)) = [C, B)`.
This range is empty, but its `Begin` does not match with `End`.
Making IRCE for an empty range is basically safe but unprofitable because we
never actually get into the main loop where the range checks are supposed to
be eliminated. This patch uses SCEV mechanisms to treat loops with proved
`Begin >= End` as empty.
Differential Revision: https://reviews.llvm.org/D39082
llvm-svn: 316550
|
| |
|
|
|
|
| |
warnings; other minor fixes (NFC).
llvm-svn: 316503
|
| |
|
|
| |
llvm-svn: 316146
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
IRCE should not apply when the safe iteration range is proved to be empty.
In this case we do unneeded job creating pre/post loops and then never
go to the main loop.
This patch makes IRCE not apply to empty safe ranges, adds test for this
situation and also modifies one of existing tests where it used to happen
slightly.
Reviewed By: anna
Differential Revision: https://reviews.llvm.org/D38577
llvm-svn: 315437
|
| |
|
|
|
|
|
|
|
|
|
|
| |
We have found some corner cases connected to range intersection where IRCE makes
a bad thing when the latch condition is unsigned. The fix for that will go as a follow up.
This patch temporarily disables IRCE for unsigned latch conditions until the issue is fixed.
The unsigned latch conditions were introduced to IRCE by rL310027.
Differential Revision: https://reviews.llvm.org/D38529
llvm-svn: 314881
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Summary:
And now that we no longer have to explicitly free() the Loop instances, we can
(with more ease) use the destructor of LoopBase to do what LoopBase::clear() was
doing.
Reviewers: chandlerc
Subscribers: mehdi_amini, mcrosier, llvm-commits
Differential Revision: https://reviews.llvm.org/D38201
llvm-svn: 314375
|
| |
|
|
|
|
|
|
|
|
| |
current IV value""
Revert the patch causing the functional failures.
The patch owner is notified with test cases which fail.
Test case has been provided to Maxim offline.
llvm-svn: 313857
|
| |
|
|
|
|
|
|
| |
Re-applying after the found bug was fixed.
Differential Revision: https://reviews.llvm.org/D36215
llvm-svn: 312783
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
index f72a808..9fa49fd 100644
--- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -450,20 +450,10 @@ struct LoopStructure {
// equivalent to:
//
// intN_ty inc = IndVarIncreasing ? 1 : -1;
- // pred_ty predicate = IndVarIncreasing
- // ? IsSignedPredicate ? ICMP_SLT : ICMP_ULT
- // : IsSignedPredicate ? ICMP_SGT : ICMP_UGT;
+ // pred_ty predicate = IndVarIncreasing ? ICMP_SLT : ICMP_SGT;
//
- //
- // for (intN_ty iv = IndVarStart; predicate(IndVarBase, LoopExitAt);
- // iv = IndVarNext)
+ // for (intN_ty iv = IndVarStart; predicate(iv, LoopExitAt); iv = IndVarBase)
// ... body ...
- //
- // Here IndVarBase is either current or next value of the induction variable.
- // in the former case, IsIndVarNext = false and IndVarBase points to the
- // Phi node of the induction variable. Otherwise, IsIndVarNext = true and
- // IndVarBase points to IV increment instruction.
- //
Value *IndVarBase;
Value *IndVarStart;
@@ -471,13 +461,12 @@ struct LoopStructure {
Value *LoopExitAt;
bool IndVarIncreasing;
bool IsSignedPredicate;
- bool IsIndVarNext;
LoopStructure()
: Tag(""), Header(nullptr), Latch(nullptr), LatchBr(nullptr),
LatchExit(nullptr), LatchBrExitIdx(-1), IndVarBase(nullptr),
IndVarStart(nullptr), IndVarStep(nullptr), LoopExitAt(nullptr),
- IndVarIncreasing(false), IsSignedPredicate(true), IsIndVarNext(false) {}
+ IndVarIncreasing(false), IsSignedPredicate(true) {}
template <typename M> LoopStructure map(M Map) const {
LoopStructure Result;
@@ -493,7 +482,6 @@ struct LoopStructure {
Result.LoopExitAt = Map(LoopExitAt);
Result.IndVarIncreasing = IndVarIncreasing;
Result.IsSignedPredicate = IsSignedPredicate;
- Result.IsIndVarNext = IsIndVarNext;
return Result;
}
@@ -841,42 +829,21 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE,
return false;
};
- // `ICI` can either be a comparison against IV or a comparison of IV.next.
- // Depending on the interpretation, we calculate the start value differently.
+ // `ICI` is interpreted as taking the backedge if the *next* value of the
+ // induction variable satisfies some constraint.
- // Pair {IndVarBase; IsIndVarNext} semantically designates whether the latch
- // comparisons happens against the IV before or after its value is
- // incremented. Two valid combinations for them are:
- //
- // 1) { phi [ iv.start, preheader ], [ iv.next, latch ]; false },
- // 2) { iv.next; true }.
- //
- // The latch comparison happens against IndVarBase which can be either current
- // or next value of the induction variable.
const SCEVAddRecExpr *IndVarBase = cast<SCEVAddRecExpr>(LeftSCEV);
bool IsIncreasing = false;
bool IsSignedPredicate = true;
- bool IsIndVarNext = false;
ConstantInt *StepCI;
if (!IsInductionVar(IndVarBase, IsIncreasing, StepCI)) {
FailureReason = "LHS in icmp not induction variable";
return None;
}
- const SCEV *IndVarStart = nullptr;
- // TODO: Currently we only handle comparison against IV, but we can extend
- // this analysis to be able to deal with comparison against sext(iv) and such.
- if (isa<PHINode>(LeftValue) &&
- cast<PHINode>(LeftValue)->getParent() == Header)
- // The comparison is made against current IV value.
- IndVarStart = IndVarBase->getStart();
- else {
- // Assume that the comparison is made against next IV value.
- const SCEV *StartNext = IndVarBase->getStart();
- const SCEV *Addend = SE.getNegativeSCEV(IndVarBase->getStepRecurrence(SE));
- IndVarStart = SE.getAddExpr(StartNext, Addend);
- IsIndVarNext = true;
- }
+ const SCEV *StartNext = IndVarBase->getStart();
+ const SCEV *Addend = SE.getNegativeSCEV(IndVarBase->getStepRecurrence(SE));
+ const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend);
const SCEV *Step = SE.getSCEV(StepCI);
ConstantInt *One = ConstantInt::get(IndVarTy, 1);
@@ -1060,7 +1027,6 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE,
Result.IndVarIncreasing = IsIncreasing;
Result.LoopExitAt = RightValue;
Result.IsSignedPredicate = IsSignedPredicate;
- Result.IsIndVarNext = IsIndVarNext;
FailureReason = nullptr;
@@ -1350,9 +1316,8 @@ LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd(
BranchToContinuation);
NewPHI->addIncoming(PN->getIncomingValueForBlock(Preheader), Preheader);
- auto *FixupValue =
- LS.IsIndVarNext ? PN->getIncomingValueForBlock(LS.Latch) : PN;
- NewPHI->addIncoming(FixupValue, RRI.ExitSelector);
+ NewPHI->addIncoming(PN->getIncomingValueForBlock(LS.Latch),
+ RRI.ExitSelector);
RRI.PHIValuesAtPseudoExit.push_back(NewPHI);
}
@@ -1735,10 +1700,7 @@ bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
}
LoopStructure LS = MaybeLoopStructure.getValue();
const SCEVAddRecExpr *IndVar =
- cast<SCEVAddRecExpr>(SE.getSCEV(LS.IndVarBase));
- if (LS.IsIndVarNext)
- IndVar = cast<SCEVAddRecExpr>(SE.getMinusSCEV(IndVar,
- SE.getSCEV(LS.IndVarStep)));
+ cast<SCEVAddRecExpr>(SE.getMinusSCEV(SE.getSCEV(LS.IndVarBase), SE.getSCEV(LS.IndVarStep)));
Optional<InductiveRangeCheck::Range> SafeIterRange;
Instruction *ExprInsertPt = Preheader->getTerminator();
diff --git a/test/Transforms/IRCE/latch-comparison-against-current-value.ll b/test/Transforms/IRCE/latch-comparison-against-current-value.ll
deleted file mode 100644
index afea0e6..0000000
--- a/test/Transforms/IRCE/latch-comparison-against-current-value.ll
+++ /dev/null
@@ -1,182 +0,0 @@
-; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
-
-; Check that IRCE is able to deal with loops where the latch comparison is
-; done against current value of the IV, not the IV.next.
-
-; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
-; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
-; CHECK-NOT: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
-; CHECK-NOT: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
-
-; SLT condition for increasing loop from 0 to 100.
-define void @test_01(i32* %arr, i32* %a_len_ptr) #0 {
-
-; CHECK: test_01
-; CHECK: entry:
-; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0
-; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp slt i32 0, %exit.mainloop.at
-; CHECK-NEXT: br i1 [[COND2]], label %loop.preheader, label %main.pseudo.exit
-; CHECK: loop:
-; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ]
-; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1
-; CHECK-NEXT: %abc = icmp slt i32 %idx, %exit.mainloop.at
-; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
-; CHECK: in.bounds:
-; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx
-; CHECK-NEXT: store i32 0, i32* %addr
-; CHECK-NEXT: %next = icmp slt i32 %idx, 100
-; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp slt i32 %idx, %exit.mainloop.at
-; CHECK-NEXT: br i1 [[COND3]], label %loop, label %main.exit.selector
-; CHECK: main.exit.selector:
-; CHECK-NEXT: %idx.lcssa = phi i32 [ %idx, %in.bounds ]
-; CHECK-NEXT: [[COND4:%[^ ]+]] = icmp slt i32 %idx.lcssa, 100
-; CHECK-NEXT: br i1 [[COND4]], label %main.pseudo.exit, label %exit
-; CHECK-NOT: loop.preloop:
-; CHECK: loop.postloop:
-; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ]
-; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1
-; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %exit.mainloop.at
-; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit
-
-entry:
- %len = load i32, i32* %a_len_ptr, !range !0
- br label %loop
-
-loop:
- %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
- %idx.next = add nsw nuw i32 %idx, 1
- %abc = icmp slt i32 %idx, %len
- br i1 %abc, label %in.bounds, label %out.of.bounds
-
-in.bounds:
- %addr = getelementptr i32, i32* %arr, i32 %idx
- store i32 0, i32* %addr
- %next = icmp slt i32 %idx, 100
- br i1 %next, label %loop, label %exit
-
-out.of.bounds:
- ret void
-
-exit:
- ret void
-}
-
-; ULT condition for increasing loop from 0 to 100.
-define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
-
-; CHECK: test_02
-; CHECK: entry:
-; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0
-; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at
-; CHECK-NEXT: br i1 [[COND2]], label %loop.preheader, label %main.pseudo.exit
-; CHECK: loop:
-; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ]
-; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1
-; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at
-; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
-; CHECK: in.bounds:
-; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx
-; CHECK-NEXT: store i32 0, i32* %addr
-; CHECK-NEXT: %next = icmp ult i32 %idx, 100
-; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp ult i32 %idx, %exit.mainloop.at
-; CHECK-NEXT: br i1 [[COND3]], label %loop, label %main.exit.selector
-; CHECK: main.exit.selector:
-; CHECK-NEXT: %idx.lcssa = phi i32 [ %idx, %in.bounds ]
-; CHECK-NEXT: [[COND4:%[^ ]+]] = icmp ult i32 %idx.lcssa, 100
-; CHECK-NEXT: br i1 [[COND4]], label %main.pseudo.exit, label %exit
-; CHECK-NOT: loop.preloop:
-; CHECK: loop.postloop:
-; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ]
-; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1
-; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at
-; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit
-
-entry:
- %len = load i32, i32* %a_len_ptr, !range !0
- br label %loop
-
-loop:
- %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
- %idx.next = add nsw nuw i32 %idx, 1
- %abc = icmp ult i32 %idx, %len
- br i1 %abc, label %in.bounds, label %out.of.bounds
-
-in.bounds:
- %addr = getelementptr i32, i32* %arr, i32 %idx
- store i32 0, i32* %addr
- %next = icmp ult i32 %idx, 100
- br i1 %next, label %loop, label %exit
-
-out.of.bounds:
- ret void
-
-exit:
- ret void
-}
-
-; Same as test_01, but comparison happens against IV extended to a wider type.
-; This test ensures that IRCE rejects it and does not falsely assume that it was
-; a comparison against iv.next.
-; TODO: We can actually extend the recognition to cover this case.
-define void @test_03(i32* %arr, i64* %a_len_ptr) #0 {
-
-; CHECK: test_03
-
-entry:
- %len = load i64, i64* %a_len_ptr, !range !1
- br label %loop
-
-loop:
- %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
- %idx.next = add nsw nuw i32 %idx, 1
- %idx.ext = sext i32 %idx to i64
- %abc = icmp slt i64 %idx.ext, %len
- br i1 %abc, label %in.bounds, label %out.of.bounds
-
-in.bounds:
- %addr = getelementptr i32, i32* %arr, i32 %idx
- store i32 0, i32* %addr
- %next = icmp slt i32 %idx, 100
- br i1 %next, label %loop, label %exit
-
-out.of.bounds:
- ret void
-
-exit:
- ret void
-}
-
-; Same as test_02, but comparison happens against IV extended to a wider type.
-; This test ensures that IRCE rejects it and does not falsely assume that it was
-; a comparison against iv.next.
-; TODO: We can actually extend the recognition to cover this case.
-define void @test_04(i32* %arr, i64* %a_len_ptr) #0 {
-
-; CHECK: test_04
-
-entry:
- %len = load i64, i64* %a_len_ptr, !range !1
- br label %loop
-
-loop:
- %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
- %idx.next = add nsw nuw i32 %idx, 1
- %idx.ext = sext i32 %idx to i64
- %abc = icmp ult i64 %idx.ext, %len
- br i1 %abc, label %in.bounds, label %out.of.bounds
-
-in.bounds:
- %addr = getelementptr i32, i32* %arr, i32 %idx
- store i32 0, i32* %addr
- %next = icmp ult i32 %idx, 100
- br i1 %next, label %loop, label %exit
-
-out.of.bounds:
- ret void
-
-exit:
- ret void
-}
-
-!0 = !{i32 0, i32 50}
-!1 = !{i64 0, i64 50}
llvm-svn: 312775
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Current implementation of parseLoopStructure interprets the latch comparison as a
comarison against `iv.next`. If the actual comparison is made against the `iv` current value
then the loop may be rejected, because this misinterpretation leads to incorrect evaluation
of the latch start value.
This patch teaches the IRCE to distinguish this kind of loops and perform the optimization
for them. Now we use `IndVarBase` variable which can be either next or current value of the
induction variable (previously we used `IndVarNext` which was always the value on next iteration).
Differential Revision: https://reviews.llvm.org/D36215
llvm-svn: 312221
|
| |
|
|
|
|
|
|
|
| |
Renaming as a preparation step to generalizing IRCE for comparison not only against
the next value of an indvar, but also against the current.
Differential Revision: https://reviews.llvm.org/D36509
llvm-svn: 312215
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Clamp function was too optimistic when choosing signed or unsigned min/max function for calculations.
In fact, `!IsSignedPredicate` guarantees us that `Smallest` and `Greatest` can be compared safely using unsigned
predicates, but we did not check this for `S` which can in theory be negative.
This patch makes Clamp use signed min/max for cases when it fails to prove `S` being non-negative,
and it adds a test where such situation may lead to incorrect conditions calculation.
Differential Revision: https://reviews.llvm.org/D36873
llvm-svn: 311205
|
| |
|
|
| |
llvm-svn: 310034
|
| |
|
|
|
|
|
|
| |
This patch generalizes IRCE to handle IV steps that are not equal to 1 or -1.
Differential Revision: https://reviews.llvm.org/D35539
llvm-svn: 310032
|
| |
|
|
|
|
|
|
| |
This patch enables recognition of loops with ult/ugt latch conditions.
Differential Revision: https://reviews.llvm.org/D35302
llvm-svn: 310027
|
| |
|
|
|
|
|
| |
One more assertion of this kind. It is a preparation step for generalizing
to the case of stride not equal to +1/-1.
llvm-svn: 309663
|
| |
|
|
|
|
|
| |
We should never return zero steps, ensure this fact by adding
a sanity check when we are analyzing the induction variable.
llvm-svn: 309661
|
| |
|
|
|
|
|
|
|
|
| |
In some particular cases eq/ne conditions can be turned into equivalent
slt/sgt conditions. This patch teaches parseLoopStructure to handle some
of these cases.
Differential Revision: https://reviews.llvm.org/D35010
llvm-svn: 308264
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When iterating through loop
for (int i = INT_MAX; i > 0; i--)
We fail to generate the pre-loop for it. It happens because we use the
overflown value in a comparison predicate when identifying whether or not
we need it.
In old logic, we used SLE predicate against Greatest value which exceeds all
seen values of the IV and might be overflown. Now we use the GreatestSeen
value of this IV with SLT predicate.
Also added a test that ensures that a pre-loop is generated for such loops.
Differential Revision: https://reviews.llvm.org/D35347
llvm-svn: 308001
|
| |
|
|
|
|
|
|
|
| |
A slightly more efficient way to get constant, we avoid resolving in getSCEV and excessive
invocations, and we don't create a ConstantInt if 'true' branch is taken.
Differential Revision: https://reviews.llvm.org/D34672
llvm-svn: 306503
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Summary:
We were canonizalizing the pre loop (into loop-simplify form) before
the post loop blocks were added into parent loop. This is incorrect when IRCE is
done on a subloop. The post-loop blocks are created, but not yet added to the
parent loop. So, loop-simplification on the pre-loop incorrectly updates
LoopInfo.
This patch corrects the ordering so that pre and post loop blocks are added to
parent loop (if any), and then the loops are canonicalized to LCSSA and
LoopSimplifyForm.
Reviewers: reames, sanjoy, apilipenko
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D33846
llvm-svn: 304800
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I did this a long time ago with a janky python script, but now
clang-format has built-in support for this. I fed clang-format every
line with a #include and let it re-sort things according to the precise
LLVM rules for include ordering baked into clang-format these days.
I've reverted a number of files where the results of sorting includes
isn't healthy. Either places where we have legacy code relying on
particular include ordering (where possible, I'll fix these separately)
or where we have particular formatting around #include lines that
I didn't want to disturb in this patch.
This patch is *entirely* mechanical. If you get merge conflicts or
anything, just ignore the changes in this patch and run clang-format
over your #include lines in the files.
Sorry for any noise here, but it is important to keep these things
stable. I was seeing an increasing number of patches with irrelevant
re-ordering of #include lines because clang-format was used. This patch
at least isolates that churn, makes it easy to skip when resolving
conflicts, and gets us to a clean baseline (again).
llvm-svn: 304787
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
having it internally allocate the loop.
This is a much more flexible API and necessary in the new loop unswitch
to reasonably support both new and old PMs in common code. It also just
seems like a cleaner separation of concerns.
NFC, this should just be a pure refactoring.
Differential Revision: https://reviews.llvm.org/D33528
llvm-svn: 303834
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently IRCE relies on the loops it transforms to be (semantically) of
the form:
for (i = START; i < END; i++)
...
or
for (i = START; i > END; i--)
...
However, we were not verifying the presence of the START < END entry
check (i.e. check before the first iteration). We were only verifying
that the backedge was guarded by (i + 1) < END.
Usually this would work "fine" since (especially in Java) most loops do
actually have the START < END check, but of course that is not
guaranteed.
llvm-svn: 294375
|
| |
|
|
|
|
|
| |
This creates non-linear behavior in the inliner (see more details in
r289755's commit thread).
llvm-svn: 290086
|
| |
|
|
|
|
|
|
|
| |
After r289755, the AssumptionCache is no longer needed. Variables affected by
assumptions are now found by using the new operand-bundle-based scheme. This
new scheme is more computationally efficient, and also we need much less
code...
llvm-svn: 289756
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Summary:
This patch will add loop metadata on the pre and post loops generated by IRCE.
Currently, we have metadata for disabling optimizations such as vectorization,
unrolling, loop distribution and LICM versioning (and confirmed that these
optimizations check for the metadata before proceeding with the transformation).
The pre and post loops generated by IRCE need not go through loop opts (since
these are slow paths).
Added two test cases as well.
Reviewers: sanjoy, reames
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D26806
llvm-svn: 289588
|
| |
|
|
| |
llvm-svn: 279079
|
| |
|
|
|
|
|
| |
This is a mechanical change of comments in switches like fallthrough,
fall-through, or fall-thru to use the LLVM_FALLTHROUGH macro instead.
llvm-svn: 278902
|
| |
|
|
|
|
|
|
|
| |
BasicBlock::Create isn't designed to take iterators (which might be
end()), but pointers (which might be nullptr). Fix the UB that was
converting end() to a BasicBlock* by calling BasicBlock::getNextNode()
in the first place.
llvm-svn: 278883
|
| |
|
|
| |
llvm-svn: 278619
|
| |
|
|
| |
llvm-svn: 278618
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
IRCE has the ability to further version pre-loops and post-loops that it
created, but this isn't useful at all. This change teaches IRCE to
leave behind some metadata in the loops it creates (by cloning the main
loop) so that these new loops are not re-processed by IRCE.
Today this bug is hidden by another bug -- IRCE does not update LoopInfo
properly so the loop pass manager does not re-invoke IRCE on the loops
it split out. However, once the latter is fixed the bug addressed in
this change causes IRCE to infinite-loop in some cases (e.g. it splits
out a pre-loop, a pre-pre-loop from that, a pre-pre-pre-loop from that
and so on).
llvm-svn: 278617
|
| |
|
|
|
|
|
| |
NFC meaning IRCE should not _do_ anything different, but
-debug-only=irce will be a little friendlier.
llvm-svn: 278616
|
| |
|
|
|
|
|
|
| |
Loops containing `indirectbr` may not be in simplified form, even after
running LoopSimplify. Reject then gracefully, instead of tripping an
assert.
llvm-svn: 278611
|
| |
|
|
| |
llvm-svn: 278607
|
| |
|
|
| |
llvm-svn: 278606
|
| |
|
|
| |
llvm-svn: 277892
|
| |
|
|
|
|
|
|
| |
Fixes PR28764. Right now there is no way to test this, but (as
mentioned on the PR) with Michael Zolotukhin's yet to be checked in
LoopSimplify verfier, 8 of the llvm-lit tests for IRCE crash.
llvm-svn: 277891
|
| |
|
|
|
|
| |
There is nothing "Original" about "OriginalLoopInfo".
llvm-svn: 277506
|
| |
|
|
|
|
|
| |
This changes IRCE to "preserve" LCSSA and DomTree by recomputing them.
It still does not preserve LoopSimplify.
llvm-svn: 277505
|
| |
|
|
|
|
|
|
| |
If `-irce-skip-profitability-checks` is passed in, IRCE will kick in in
all cases where it is legal for it to kick in. This flag is intended to
help diagnose and analyse performance issues.
llvm-svn: 276372
|
| |
|
|
| |
llvm-svn: 273586
|
| |
|
|
| |
llvm-svn: 270815
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
After this change, we do the expected thing for cases like
```
Check0Passed = /* range check IRCE can optimize */
Check1Passed = /* range check IRCE can optimize */
if (!(Check0Passed && Check1Passed))
throw_Exception();
```
llvm-svn: 270804
|
| |
|
|
|
|
|
| |
This will later hold more general logic to parse conjunctions of range
checks.
llvm-svn: 270802
|