llvm.org GIT mirror llvm / a7af2e0
Revert "[ScalarEvolution] Re-enable Predicate implication from operations" This reverts commit rL298690 Causes failures on clang. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298693 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 3 years ago
4 changed file(s) with 16 addition(s) and 534 deletion(s). Raw diff Collapse all Expand all
977977
978978 /// Test whether the condition described by Pred, LHS, and RHS is true
979979 /// whenever the condition described by Pred, FoundLHS, and FoundRHS is
980 /// true. Here LHS is an operation that includes FoundLHS as one of its
981 /// arguments.
982 bool isImpliedViaOperations(ICmpInst::Predicate Pred,
983 const SCEV *LHS, const SCEV *RHS,
984 const SCEV *FoundLHS, const SCEV *FoundRHS,
985 unsigned Depth = 0);
986
987 /// Test whether the condition described by Pred, LHS, and RHS is true.
988 /// Use only simple non-recursive types of checks, such as range analysis etc.
989 bool isKnownViaSimpleReasoning(ICmpInst::Predicate Pred,
990 const SCEV *LHS, const SCEV *RHS);
991
992 /// Test whether the condition described by Pred, LHS, and RHS is true
993 /// whenever the condition described by Pred, FoundLHS, and FoundRHS is
994980 /// true.
995981 bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS,
996982 const SCEV *RHS, const SCEV *FoundLHS,
11351121 /// represents how SCEV will treat the given type, for which isSCEVable must
11361122 /// return true. For pointer types, this is the pointer-sized integer type.
11371123 Type *getEffectiveSCEVType(Type *Ty) const;
1138
1139 // Returns a wider type among {Ty1, Ty2}.
1140 Type *getWiderType(Type *Ty1, Type *Ty2) const;
11411124
11421125 /// Return true if the SCEV is a scAddRecExpr or it contains
11431126 /// scAddRecExpr. The result will be cached in HasRecMap.
135135 "scalar-evolution-max-scev-compare-depth", cl::Hidden,
136136 cl::desc("Maximum depth of recursive SCEV complexity comparisons"),
137137 cl::init(32));
138
139 static cl::opt MaxSCEVOperationsImplicationDepth(
140 "scalar-evolution-max-scev-operations-implication-depth", cl::Hidden,
141 cl::desc("Maximum depth of recursive SCEV operations implication analysis"),
142 cl::init(4));
143138
144139 static cl::opt MaxValueCompareDepth(
145140 "scalar-evolution-max-value-compare-depth", cl::Hidden,
34223417 return getDataLayout().getIntPtrType(Ty);
34233418 }
34243419
3425 Type *ScalarEvolution::getWiderType(Type *T1, Type *T2) const {
3426 return getTypeSizeInBits(T1) >= getTypeSizeInBits(T2) ? T1 : T2;
3427 }
3428
34293420 const SCEV *ScalarEvolution::getCouldNotCompute() {
34303421 return CouldNotCompute.get();
34313422 }
85678558 llvm_unreachable("covered switch fell through?!");
85688559 }
85698560
8570 bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
8571 const SCEV *LHS, const SCEV *RHS,
8572 const SCEV *FoundLHS,
8573 const SCEV *FoundRHS,
8574 unsigned Depth) {
8575 // We want to avoid hurting the compile time with analysis of too big trees.
8576 if (Depth > MaxSCEVOperationsImplicationDepth)
8577 return false;
8578 // We only want to work with ICMP_SGT comparison so far.
8579 // TODO: Extend to ICMP_UGT?
8580 if (Pred == ICmpInst::ICMP_SLT) {
8581 Pred = ICmpInst::ICMP_SGT;
8582 std::swap(LHS, RHS);
8583 std::swap(FoundLHS, FoundRHS);
8584 }
8585 if (Pred != ICmpInst::ICMP_SGT)
8586 return false;
8587
8588 auto GetOpFromSExt = [&](const SCEV *S) {
8589 if (auto *Ext = dyn_cast(S))
8590 return Ext->getOperand();
8591 // TODO: If S is a SCEVConstant then you can cheaply "strip" the sext off
8592 // the constant in some cases.
8593 return S;
8594 };
8595
8596 // Acquire values from extensions.
8597 auto *OrigFoundLHS = FoundLHS;
8598 LHS = GetOpFromSExt(LHS);
8599 FoundLHS = GetOpFromSExt(FoundLHS);
8600
8601 // Is the SGT predicate can be proved trivially or using the found context.
8602 auto IsSGTViaContext = [&](const SCEV *S1, const SCEV *S2) {
8603 assert(S1->getType() == S2->getType() && "Proving for wrong types?");
8604 return isKnownViaSimpleReasoning(ICmpInst::ICMP_SGT, S1, S2) ||
8605 isImpliedViaOperations(ICmpInst::ICMP_SGT, S1, S2, OrigFoundLHS,
8606 FoundRHS, Depth + 1);
8607 };
8608
8609 if (auto *LHSAddExpr = dyn_cast(LHS)) {
8610 // We want to avoid creation of any new non-constant SCEV. Since we are
8611 // going to compare the operands to RHS, we should be certain that we don't
8612 // need any type conversions for this. So let's decline all cases when the
8613 // types of LHS and RHS do not match.
8614 // TODO: Maybe try to get RHS from sext to catch more cases?
8615 if (LHSAddExpr->getType() != RHS->getType())
8616 return false;
8617
8618 // Should not overflow.
8619 if (!LHSAddExpr->hasNoSignedWrap())
8620 return false;
8621
8622 auto *LL = LHSAddExpr->getOperand(0);
8623 auto *LR = LHSAddExpr->getOperand(1);
8624 auto *MinusOne = getNegativeSCEV(getOne(RHS->getType()));
8625
8626 // Checks that S1 >= 0 && S2 > RHS, trivially or using the found context.
8627 auto IsSumGreaterThanRHS = [&](const SCEV *S1, const SCEV *S2) {
8628 return IsSGTViaContext(S1, MinusOne) && IsSGTViaContext(S2, RHS);
8629 };
8630 // Try to prove the following rule:
8631 // (LHS = LL + LR) && (LL >= 0) && (LR > RHS) => (LHS > RHS).
8632 // (LHS = LL + LR) && (LR >= 0) && (LL > RHS) => (LHS > RHS).
8633 if (IsSumGreaterThanRHS(LL, LR) || IsSumGreaterThanRHS(LR, LL))
8634 return true;
8635 } else if (auto *LHSUnknownExpr = dyn_cast(LHS)) {
8636 Value *LL, *LR;
8637 // FIXME: Once we have SDiv implemented, we can get rid of this matching.
8638 using namespace llvm::PatternMatch;
8639 if (match(LHSUnknownExpr->getValue(), m_SDiv(m_Value(LL), m_Value(LR)))) {
8640 // Rules for division.
8641 // We are going to perform some comparisons with Denominator and its
8642 // derivative expressions. In general case, creating a SCEV for it may
8643 // lead to a complex analysis of the entire graph, and in particular it
8644 // can request trip count recalculation for the same loop. This would
8645 // cache as SCEVCouldNotCompute to avoid the infinite recursion. This is a
8646 // sad thing. To avoid this, we only want to create SCEVs that are
8647 // constants in this section. So we bail if Denominator is not a constant.
8648 if (!isa(LR))
8649 return false;
8650
8651 auto *Denominator = cast(getSCEV(LR));
8652
8653 // We want to make sure that LHS = FoundLHS / Denominator. If it is so,
8654 // then a SCEV for the numerator already exists and matches with FoundLHS.
8655 auto *Numerator = getExistingSCEV(LL);
8656
8657 // Make sure that it exists and has the same type.
8658 if (!Numerator || Numerator->getType() != FoundLHS->getType())
8659 return false;
8660
8661 // Make sure that the numerator matches with FoundLHs and the denominator
8662 // is positive.
8663 if (!HasSameValue(Numerator, FoundLHS) || !isKnownPositive(Denominator))
8664 return false;
8665
8666 // Given that:
8667 // FoundLHS > FoundRHS, LHS = FoundLHS / Denominator, Denominator > 0.
8668 auto *Ty2 = getWiderType(Denominator->getType(), FoundRHS->getType());
8669 auto *DenominatorExt = getNoopOrSignExtend(Denominator, Ty2);
8670 auto *FoundRHSExt = getNoopOrSignExtend(FoundRHS, Ty2);
8671
8672 // Try to prove the following rule:
8673 // (FoundRHS > Denominator - 2) && (RHS <= 0) => (LHS > RHS).
8674 // For example, given that FoundLHS > 2. It means that FoundLHS is at
8675 // least 3. If we divide it by Denominator < 4, we will have at least 1.
8676 auto *DenomMinusTwo = getMinusSCEV(DenominatorExt, getConstant(Ty2, 2));
8677 if (isKnownNonPositive(RHS) &&
8678 IsSGTViaContext(FoundRHSExt, DenomMinusTwo))
8679 return true;
8680
8681 // Try to prove the following rule:
8682 // (FoundRHS > -1 - Denominator) && (RHS < 0) => (LHS > RHS).
8683 // For example, given that FoundLHS > -3. Then FoundLHS is at least -2.
8684 // If we divide it by Denominator > 2, then:
8685 // 1. If FoundLHS is negative, then the result is 0.
8686 // 2. If FoundLHS is non-negative, then the result is non-negative.
8687 // Anyways, the result is non-negative.
8688 auto *MinusOne = getNegativeSCEV(getOne(Ty2));
8689 auto *NegDenomMinusOne = getMinusSCEV(MinusOne, DenominatorExt);
8690 if (isKnownNegative(RHS) &&
8691 IsSGTViaContext(FoundRHSExt, NegDenomMinusOne))
8692 return true;
8693 }
8694 }
8695
8696 return false;
8697 }
8698
8699 bool
8700 ScalarEvolution::isKnownViaSimpleReasoning(ICmpInst::Predicate Pred,
8701 const SCEV *LHS, const SCEV *RHS) {
8702 return isKnownPredicateViaConstantRanges(Pred, LHS, RHS) ||
8703 IsKnownPredicateViaMinOrMax(*this, Pred, LHS, RHS) ||
8704 IsKnownPredicateViaAddRecStart(*this, Pred, LHS, RHS) ||
8705 isKnownPredicateViaNoOverflow(Pred, LHS, RHS);
8706 }
8707
87088561 bool
87098562 ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
87108563 const SCEV *LHS, const SCEV *RHS,
87118564 const SCEV *FoundLHS,
87128565 const SCEV *FoundRHS) {
8566 auto IsKnownPredicateFull =
8567 [this](ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS) {
8568 return isKnownPredicateViaConstantRanges(Pred, LHS, RHS) ||
8569 IsKnownPredicateViaMinOrMax(*this, Pred, LHS, RHS) ||
8570 IsKnownPredicateViaAddRecStart(*this, Pred, LHS, RHS) ||
8571 isKnownPredicateViaNoOverflow(Pred, LHS, RHS);
8572 };
8573
87138574 switch (Pred) {
87148575 default: llvm_unreachable("Unexpected ICmpInst::Predicate value!");
87158576 case ICmpInst::ICMP_EQ:
87198580 break;
87208581 case ICmpInst::ICMP_SLT:
87218582 case ICmpInst::ICMP_SLE:
8722 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&
8723 isKnownViaSimpleReasoning(ICmpInst::ICMP_SGE, RHS, FoundRHS))
8583 if (IsKnownPredicateFull(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&
8584 IsKnownPredicateFull(ICmpInst::ICMP_SGE, RHS, FoundRHS))
87248585 return true;
87258586 break;
87268587 case ICmpInst::ICMP_SGT:
87278588 case ICmpInst::ICMP_SGE:
8728 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&
8729 isKnownViaSimpleReasoning(ICmpInst::ICMP_SLE, RHS, FoundRHS))
8589 if (IsKnownPredicateFull(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&
8590 IsKnownPredicateFull(ICmpInst::ICMP_SLE, RHS, FoundRHS))
87308591 return true;
87318592 break;
87328593 case ICmpInst::ICMP_ULT:
87338594 case ICmpInst::ICMP_ULE:
8734 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&
8735 isKnownViaSimpleReasoning(ICmpInst::ICMP_UGE, RHS, FoundRHS))
8595 if (IsKnownPredicateFull(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&
8596 IsKnownPredicateFull(ICmpInst::ICMP_UGE, RHS, FoundRHS))
87368597 return true;
87378598 break;
87388599 case ICmpInst::ICMP_UGT:
87398600 case ICmpInst::ICMP_UGE:
8740 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&
8741 isKnownViaSimpleReasoning(ICmpInst::ICMP_ULE, RHS, FoundRHS))
8601 if (IsKnownPredicateFull(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&
8602 IsKnownPredicateFull(ICmpInst::ICMP_ULE, RHS, FoundRHS))
87428603 return true;
87438604 break;
87448605 }
8745
8746 // Maybe it can be proved via operations?
8747 if (isImpliedViaOperations(Pred, LHS, RHS, FoundLHS, FoundRHS))
8748 return true;
87498606
87508607 return false;
87518608 }
+0
-27
test/Analysis/ScalarEvolution/implied-via-addition.ll less more
None ; RUN: opt -indvars -S < %s | FileCheck %s
1
2 declare void @use(i1)
3
4 declare void @llvm.experimental.guard(i1, ...)
5
6 define void @test_01(i8 %t) {
7 ; CHECK-LABEL: test_01
8 entry:
9 %st = sext i8 %t to i16
10 %cmp1 = icmp slt i16 %st, 42
11 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
12 br label %loop
13
14 loop:
15 ; CHECK-LABEL: loop
16 %idx = phi i8 [ %t, %entry ], [ %idx.inc, %loop ]
17 %idx.inc = add i8 %idx, 1
18 %c = icmp slt i8 %idx, 42
19 ; CHECK: call void @use(i1 true)
20 call void @use(i1 %c)
21 %be = icmp slt i8 %idx.inc, 42
22 br i1 %be, label %loop, label %exit
23
24 exit:
25 ret void
26 }
+0
-331
test/Analysis/ScalarEvolution/implied-via-division.ll less more
None ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
1
2 declare void @llvm.experimental.guard(i1, ...)
3
4 define void @test_1(i32 %n) nounwind {
5 ; Prove that (n > 1) ===> (n / 2 > 0).
6 ; CHECK: Determining loop execution counts for: @test_1
7 ; CHECK: Loop %header: backedge-taken count is (-1 + %n.div.2)
8 entry:
9 %cmp1 = icmp sgt i32 %n, 1
10 %n.div.2 = sdiv i32 %n, 2
11 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
12 br label %header
13
14 header:
15 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
16 %indvar.next = add i32 %indvar, 1
17 %exitcond = icmp sgt i32 %n.div.2, %indvar.next
18 br i1 %exitcond, label %header, label %exit
19
20 exit:
21 ret void
22 }
23
24 define void @test_1neg(i32 %n) nounwind {
25 ; Prove that (n > 0) =\=> (n / 2 > 0).
26 ; CHECK: Determining loop execution counts for: @test_1neg
27 ; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax %n.div.2))
28 entry:
29 %cmp1 = icmp sgt i32 %n, 0
30 %n.div.2 = sdiv i32 %n, 2
31 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
32 br label %header
33
34 header:
35 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
36 %indvar.next = add i32 %indvar, 1
37 %exitcond = icmp sgt i32 %n.div.2, %indvar.next
38 br i1 %exitcond, label %header, label %exit
39
40 exit:
41 ret void
42 }
43
44 define void @test_2(i32 %n) nounwind {
45 ; Prove that (n >= 2) ===> (n / 2 > 0).
46 ; CHECK: Determining loop execution counts for: @test_2
47 ; CHECK: Loop %header: backedge-taken count is (-1 + %n.div.2)
48 entry:
49 %cmp1 = icmp sge i32 %n, 2
50 %n.div.2 = sdiv i32 %n, 2
51 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
52 br label %header
53
54 header:
55 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
56 %indvar.next = add i32 %indvar, 1
57 %exitcond = icmp sgt i32 %n.div.2, %indvar.next
58 br i1 %exitcond, label %header, label %exit
59
60 exit:
61 ret void
62 }
63
64 define void @test_2neg(i32 %n) nounwind {
65 ; Prove that (n >= 1) =\=> (n / 2 > 0).
66 ; CHECK: Determining loop execution counts for: @test_2neg
67 ; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax %n.div.2))
68 entry:
69 %cmp1 = icmp sge i32 %n, 1
70 %n.div.2 = sdiv i32 %n, 2
71 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
72 br label %header
73
74 header:
75 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
76 %indvar.next = add i32 %indvar, 1
77 %exitcond = icmp sgt i32 %n.div.2, %indvar.next
78 br i1 %exitcond, label %header, label %exit
79
80 exit:
81 ret void
82 }
83
84 define void @test_3(i32 %n) nounwind {
85 ; Prove that (n > -2) ===> (n / 2 >= 0).
86 ; CHECK: Determining loop execution counts for: @test_3
87 ; CHECK: Loop %header: backedge-taken count is (1 + %n.div.2)
88 entry:
89 %cmp1 = icmp sgt i32 %n, -2
90 %n.div.2 = sdiv i32 %n, 2
91 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
92 br label %header
93
94 header:
95 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
96 %indvar.next = add i32 %indvar, 1
97 %exitcond = icmp sge i32 %n.div.2, %indvar
98 br i1 %exitcond, label %header, label %exit
99
100 exit:
101 ret void
102 }
103
104 define void @test_3neg(i32 %n) nounwind {
105 ; Prove that (n > -3) =\=> (n / 2 >= 0).
106 ; CHECK: Determining loop execution counts for: @test_3neg
107 ; CHECK: Loop %header: backedge-taken count is (0 smax (1 + %n.div.2))
108 entry:
109 %cmp1 = icmp sgt i32 %n, -3
110 %n.div.2 = sdiv i32 %n, 2
111 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
112 br label %header
113
114 header:
115 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
116 %indvar.next = add i32 %indvar, 1
117 %exitcond = icmp sge i32 %n.div.2, %indvar
118 br i1 %exitcond, label %header, label %exit
119
120 exit:
121 ret void
122 }
123
124 define void @test_4(i32 %n) nounwind {
125 ; Prove that (n >= -1) ===> (n / 2 >= 0).
126 ; CHECK: Determining loop execution counts for: @test_4
127 ; CHECK: Loop %header: backedge-taken count is (1 + %n.div.2)
128 entry:
129 %cmp1 = icmp sge i32 %n, -1
130 %n.div.2 = sdiv i32 %n, 2
131 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
132 br label %header
133
134 header:
135 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
136 %indvar.next = add i32 %indvar, 1
137 %exitcond = icmp sge i32 %n.div.2, %indvar
138 br i1 %exitcond, label %header, label %exit
139
140 exit:
141 ret void
142 }
143
144 define void @test_4neg(i32 %n) nounwind {
145 ; Prove that (n >= -2) =\=> (n / 2 >= 0).
146 ; CHECK: Determining loop execution counts for: @test_4neg
147 ; CHECK: Loop %header: backedge-taken count is (0 smax (1 + %n.div.2))
148 entry:
149 %cmp1 = icmp sge i32 %n, -2
150 %n.div.2 = sdiv i32 %n, 2
151 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
152 br label %header
153
154 header:
155 %indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
156 %indvar.next = add i32 %indvar, 1
157 %exitcond = icmp sge i32 %n.div.2, %indvar
158 br i1 %exitcond, label %header, label %exit
159
160 exit:
161 ret void
162 }
163
164 define void @test_ext_01(i32 %n) nounwind {
165 ; Prove that (n > 1) ===> (n / 2 > 0).
166 ; CHECK: Determining loop execution counts for: @test_ext_01
167 ; CHECK: Loop %header: backedge-taken count is (-1 + (sext i32 %n.div.2 to i64))
168 entry:
169 %cmp1 = icmp sgt i32 %n, 1
170 %n.div.2 = sdiv i32 %n, 2
171 %n.div.2.ext = sext i32 %n.div.2 to i64
172 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
173 br label %header
174
175 header:
176 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
177 %indvar.next = add i64 %indvar, 1
178 %exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
179 br i1 %exitcond, label %header, label %exit
180
181 exit:
182 ret void
183 }
184
185 define void @test_ext_01neg(i32 %n) nounwind {
186 ; Prove that (n > 0) =\=> (n / 2 > 0).
187 ; CHECK: Determining loop execution counts for: @test_ext_01neg
188 ; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax (sext i32 %n.div.2 to i64)))
189 entry:
190 %cmp1 = icmp sgt i32 %n, 0
191 %n.div.2 = sdiv i32 %n, 2
192 %n.div.2.ext = sext i32 %n.div.2 to i64
193 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
194 br label %header
195
196 header:
197 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
198 %indvar.next = add i64 %indvar, 1
199 %exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
200 br i1 %exitcond, label %header, label %exit
201
202 exit:
203 ret void
204 }
205
206 define void @test_ext_02(i32 %n) nounwind {
207 ; Prove that (n >= 2) ===> (n / 2 > 0).
208 ; CHECK: Determining loop execution counts for: @test_ext_02
209 ; CHECK: Loop %header: backedge-taken count is (-1 + (sext i32 %n.div.2 to i64))
210 entry:
211 %cmp1 = icmp sge i32 %n, 2
212 %n.div.2 = sdiv i32 %n, 2
213 %n.div.2.ext = sext i32 %n.div.2 to i64
214 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
215 br label %header
216
217 header:
218 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
219 %indvar.next = add i64 %indvar, 1
220 %exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
221 br i1 %exitcond, label %header, label %exit
222
223 exit:
224 ret void
225 }
226
227 define void @test_ext_02neg(i32 %n) nounwind {
228 ; Prove that (n >= 1) =\=> (n / 2 > 0).
229 ; CHECK: Determining loop execution counts for: @test_ext_02neg
230 ; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax (sext i32 %n.div.2 to i64)))
231 entry:
232 %cmp1 = icmp sge i32 %n, 1
233 %n.div.2 = sdiv i32 %n, 2
234 %n.div.2.ext = sext i32 %n.div.2 to i64
235 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
236 br label %header
237
238 header:
239 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
240 %indvar.next = add i64 %indvar, 1
241 %exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
242 br i1 %exitcond, label %header, label %exit
243
244 exit:
245 ret void
246 }
247
248 define void @test_ext_03(i32 %n) nounwind {
249 ; Prove that (n > -2) ===> (n / 2 >= 0).
250 ; CHECK: Determining loop execution counts for: @test_ext_03
251 ; CHECK: Loop %header: backedge-taken count is (1 + (sext i32 %n.div.2 to i64))
252 entry:
253 %cmp1 = icmp sgt i32 %n, -2
254 %n.div.2 = sdiv i32 %n, 2
255 %n.div.2.ext = sext i32 %n.div.2 to i64
256 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
257 br label %header
258
259 header:
260 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
261 %indvar.next = add i64 %indvar, 1
262 %exitcond = icmp sge i64 %n.div.2.ext, %indvar
263 br i1 %exitcond, label %header, label %exit
264
265 exit:
266 ret void
267 }
268
269 define void @test_ext_03neg(i32 %n) nounwind {
270 ; Prove that (n > -3) =\=> (n / 2 >= 0).
271 ; CHECK: Determining loop execution counts for: @test_ext_03neg
272 ; CHECK: Loop %header: backedge-taken count is (0 smax (1 + (sext i32 %n.div.2 to i64)))
273 entry:
274 %cmp1 = icmp sgt i32 %n, -3
275 %n.div.2 = sdiv i32 %n, 2
276 %n.div.2.ext = sext i32 %n.div.2 to i64
277 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
278 br label %header
279
280 header:
281 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
282 %indvar.next = add i64 %indvar, 1
283 %exitcond = icmp sge i64 %n.div.2.ext, %indvar
284 br i1 %exitcond, label %header, label %exit
285
286 exit:
287 ret void
288 }
289
290 define void @test_ext_04(i32 %n) nounwind {
291 ; Prove that (n >= -1) ===> (n / 2 >= 0).
292 ; CHECK: Determining loop execution counts for: @test_ext_04
293 ; CHECK: Loop %header: backedge-taken count is (1 + (sext i32 %n.div.2 to i64))
294 entry:
295 %cmp1 = icmp sge i32 %n, -1
296 %n.div.2 = sdiv i32 %n, 2
297 %n.div.2.ext = sext i32 %n.div.2 to i64
298 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
299 br label %header
300
301 header:
302 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
303 %indvar.next = add i64 %indvar, 1
304 %exitcond = icmp sge i64 %n.div.2.ext, %indvar
305 br i1 %exitcond, label %header, label %exit
306
307 exit:
308 ret void
309 }
310
311 define void @test_ext_04neg(i32 %n) nounwind {
312 ; Prove that (n >= -2) =\=> (n / 2 >= 0).
313 ; CHECK: Determining loop execution counts for: @test_ext_04neg
314 ; CHECK: Loop %header: backedge-taken count is (0 smax (1 + (sext i32 %n.div.2 to i64)))
315 entry:
316 %cmp1 = icmp sge i32 %n, -2
317 %n.div.2 = sdiv i32 %n, 2
318 %n.div.2.ext = sext i32 %n.div.2 to i64
319 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
320 br label %header
321
322 header:
323 %indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
324 %indvar.next = add i64 %indvar, 1
325 %exitcond = icmp sge i64 %n.div.2.ext, %indvar
326 br i1 %exitcond, label %header, label %exit
327
328 exit:
329 ret void
330 }