llvm.org GIT mirror llvm / 85ae85b
[ScalarEvolution] Re-enable Predicate implication from operations The patch rL298481 was reverted due to crash on clang-with-lto-ubuntu build. The reason of the crash was type mismatch between either a or b and RHS in the following situation: LHS = sext(a +nsw b) > RHS. This is quite rare, but still possible situation. Normally we need to cast all {a, b, RHS} to their widest type. But we try to avoid creation of new SCEV that are not constants to avoid initiating recursive analysis that can take a lot of time and/or cache a bad value for iterations number. To deal with this, in this patch we reject this case and will not try to analyze it if the type of sum doesn't match with the type of RHS. In this situation we don't need to create any non-constant SCEVs. This patch also adds an assertion to the method IsProvedViaContext so that we could fail on it and not go further into range analysis etc (because in some situations these analyzes succeed even when the passed arguments have wrong types, what should not normally happen). The patch also contains a fix for a problem with too narrow scope of the analysis caused by wrong usage of predicates in recursive invocations. The regression test on the said failure: test/Analysis/ScalarEvolution/implied-via-addition.ll Reviewers: reames, apilipenko, anna, sanjoy Reviewed By: sanjoy Subscribers: mzolotukhin, mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D31238 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299205 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 3 years ago
4 changed file(s) with 569 addition(s) and 16 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
980994 /// true.
981995 bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS,
982996 const SCEV *RHS, const SCEV *FoundLHS,
11211135 /// represents how SCEV will treat the given type, for which isSCEVable must
11221136 /// return true. For pointer types, this is the pointer-sized integer type.
11231137 Type *getEffectiveSCEVType(Type *Ty) const;
1138
1139 // Returns a wider type among {Ty1, Ty2}.
1140 Type *getWiderType(Type *Ty1, Type *Ty2) const;
11241141
11251142 /// Return true if the SCEV is a scAddRecExpr or it contains
11261143 /// 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(2));
138143
139144 static cl::opt MaxValueCompareDepth(
140145 "scalar-evolution-max-value-compare-depth", cl::Hidden,
34173422 return getDataLayout().getIntPtrType(Ty);
34183423 }
34193424
3425 Type *ScalarEvolution::getWiderType(Type *T1, Type *T2) const {
3426 return getTypeSizeInBits(T1) >= getTypeSizeInBits(T2) ? T1 : T2;
3427 }
3428
34203429 const SCEV *ScalarEvolution::getCouldNotCompute() {
34213430 return CouldNotCompute.get();
34223431 }
85588567 llvm_unreachable("covered switch fell through?!");
85598568 }
85608569
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 assert(getTypeSizeInBits(LHS->getType()) ==
8576 getTypeSizeInBits(RHS->getType()) &&
8577 "LHS and RHS have different sizes?");
8578 assert(getTypeSizeInBits(FoundLHS->getType()) ==
8579 getTypeSizeInBits(FoundRHS->getType()) &&
8580 "FoundLHS and FoundRHS have different sizes?");
8581 // We want to avoid hurting the compile time with analysis of too big trees.
8582 if (Depth > MaxSCEVOperationsImplicationDepth)
8583 return false;
8584 // We only want to work with ICMP_SGT comparison so far.
8585 // TODO: Extend to ICMP_UGT?
8586 if (Pred == ICmpInst::ICMP_SLT) {
8587 Pred = ICmpInst::ICMP_SGT;
8588 std::swap(LHS, RHS);
8589 std::swap(FoundLHS, FoundRHS);
8590 }
8591 if (Pred != ICmpInst::ICMP_SGT)
8592 return false;
8593
8594 auto GetOpFromSExt = [&](const SCEV *S) {
8595 if (auto *Ext = dyn_cast(S))
8596 return Ext->getOperand();
8597 // TODO: If S is a SCEVConstant then you can cheaply "strip" the sext off
8598 // the constant in some cases.
8599 return S;
8600 };
8601
8602 // Acquire values from extensions.
8603 auto *OrigFoundLHS = FoundLHS;
8604 LHS = GetOpFromSExt(LHS);
8605 FoundLHS = GetOpFromSExt(FoundLHS);
8606
8607 // Is the SGT predicate can be proved trivially or using the found context.
8608 auto IsSGTViaContext = [&](const SCEV *S1, const SCEV *S2) {
8609 return isKnownViaSimpleReasoning(ICmpInst::ICMP_SGT, S1, S2) ||
8610 isImpliedViaOperations(ICmpInst::ICMP_SGT, S1, S2, OrigFoundLHS,
8611 FoundRHS, Depth + 1);
8612 };
8613
8614 if (auto *LHSAddExpr = dyn_cast(LHS)) {
8615 // We want to avoid creation of any new non-constant SCEV. Since we are
8616 // going to compare the operands to RHS, we should be certain that we don't
8617 // need any size extensions for this. So let's decline all cases when the
8618 // sizes of types of LHS and RHS do not match.
8619 // TODO: Maybe try to get RHS from sext to catch more cases?
8620 if (getTypeSizeInBits(LHS->getType()) != getTypeSizeInBits(RHS->getType()))
8621 return false;
8622
8623 // Should not overflow.
8624 if (!LHSAddExpr->hasNoSignedWrap())
8625 return false;
8626
8627 auto *LL = LHSAddExpr->getOperand(0);
8628 auto *LR = LHSAddExpr->getOperand(1);
8629 auto *MinusOne = getNegativeSCEV(getOne(RHS->getType()));
8630
8631 // Checks that S1 >= 0 && S2 > RHS, trivially or using the found context.
8632 auto IsSumGreaterThanRHS = [&](const SCEV *S1, const SCEV *S2) {
8633 return IsSGTViaContext(S1, MinusOne) && IsSGTViaContext(S2, RHS);
8634 };
8635 // Try to prove the following rule:
8636 // (LHS = LL + LR) && (LL >= 0) && (LR > RHS) => (LHS > RHS).
8637 // (LHS = LL + LR) && (LR >= 0) && (LL > RHS) => (LHS > RHS).
8638 if (IsSumGreaterThanRHS(LL, LR) || IsSumGreaterThanRHS(LR, LL))
8639 return true;
8640 } else if (auto *LHSUnknownExpr = dyn_cast(LHS)) {
8641 Value *LL, *LR;
8642 // FIXME: Once we have SDiv implemented, we can get rid of this matching.
8643 using namespace llvm::PatternMatch;
8644 if (match(LHSUnknownExpr->getValue(), m_SDiv(m_Value(LL), m_Value(LR)))) {
8645 // Rules for division.
8646 // We are going to perform some comparisons with Denominator and its
8647 // derivative expressions. In general case, creating a SCEV for it may
8648 // lead to a complex analysis of the entire graph, and in particular it
8649 // can request trip count recalculation for the same loop. This would
8650 // cache as SCEVCouldNotCompute to avoid the infinite recursion. To avoid
8651 // this, we only want to create SCEVs that are constants in this section.
8652 // So we bail if Denominator is not a constant.
8653 if (!isa(LR))
8654 return false;
8655
8656 auto *Denominator = cast(getSCEV(LR));
8657
8658 // We want to make sure that LHS = FoundLHS / Denominator. If it is so,
8659 // then a SCEV for the numerator already exists and matches with FoundLHS.
8660 auto *Numerator = getExistingSCEV(LL);
8661 if (!Numerator || Numerator->getType() != FoundLHS->getType())
8662 return false;
8663
8664 // Make sure that the numerator matches with FoundLHS and the denominator
8665 // is positive.
8666 if (!HasSameValue(Numerator, FoundLHS) || !isKnownPositive(Denominator))
8667 return false;
8668
8669 auto *DTy = Denominator->getType();
8670 auto *FRHSTy = FoundRHS->getType();
8671 if (DTy->isPointerTy() != FRHSTy->isPointerTy())
8672 // One of types is a pointer and another one is not. We cannot extend
8673 // them properly to a wider type, so let us just reject this case.
8674 // TODO: Usage of getEffectiveSCEVType for DTy, FRHSTy etc should help
8675 // to avoid this check.
8676 return false;
8677
8678 // Given that:
8679 // FoundLHS > FoundRHS, LHS = FoundLHS / Denominator, Denominator > 0.
8680 auto *WTy = getWiderType(DTy, FRHSTy);
8681 auto *DenominatorExt = getNoopOrSignExtend(Denominator, WTy);
8682 auto *FoundRHSExt = getNoopOrSignExtend(FoundRHS, WTy);
8683
8684 // Try to prove the following rule:
8685 // (FoundRHS > Denominator - 2) && (RHS <= 0) => (LHS > RHS).
8686 // For example, given that FoundLHS > 2. It means that FoundLHS is at
8687 // least 3. If we divide it by Denominator < 4, we will have at least 1.
8688 auto *DenomMinusTwo = getMinusSCEV(DenominatorExt, getConstant(WTy, 2));
8689 if (isKnownNonPositive(RHS) &&
8690 IsSGTViaContext(FoundRHSExt, DenomMinusTwo))
8691 return true;
8692
8693 // Try to prove the following rule:
8694 // (FoundRHS > -1 - Denominator) && (RHS < 0) => (LHS > RHS).
8695 // For example, given that FoundLHS > -3. Then FoundLHS is at least -2.
8696 // If we divide it by Denominator > 2, then:
8697 // 1. If FoundLHS is negative, then the result is 0.
8698 // 2. If FoundLHS is non-negative, then the result is non-negative.
8699 // Anyways, the result is non-negative.
8700 auto *MinusOne = getNegativeSCEV(getOne(WTy));
8701 auto *NegDenomMinusOne = getMinusSCEV(MinusOne, DenominatorExt);
8702 if (isKnownNegative(RHS) &&
8703 IsSGTViaContext(FoundRHSExt, NegDenomMinusOne))
8704 return true;
8705 }
8706 }
8707
8708 return false;
8709 }
8710
8711 bool
8712 ScalarEvolution::isKnownViaSimpleReasoning(ICmpInst::Predicate Pred,
8713 const SCEV *LHS, const SCEV *RHS) {
8714 return isKnownPredicateViaConstantRanges(Pred, LHS, RHS) ||
8715 IsKnownPredicateViaMinOrMax(*this, Pred, LHS, RHS) ||
8716 IsKnownPredicateViaAddRecStart(*this, Pred, LHS, RHS) ||
8717 isKnownPredicateViaNoOverflow(Pred, LHS, RHS);
8718 }
8719
85618720 bool
85628721 ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
85638722 const SCEV *LHS, const SCEV *RHS,
85648723 const SCEV *FoundLHS,
85658724 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
85748725 switch (Pred) {
85758726 default: llvm_unreachable("Unexpected ICmpInst::Predicate value!");
85768727 case ICmpInst::ICMP_EQ:
85808731 break;
85818732 case ICmpInst::ICMP_SLT:
85828733 case ICmpInst::ICMP_SLE:
8583 if (IsKnownPredicateFull(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&
8584 IsKnownPredicateFull(ICmpInst::ICMP_SGE, RHS, FoundRHS))
8734 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&
8735 isKnownViaSimpleReasoning(ICmpInst::ICMP_SGE, RHS, FoundRHS))
85858736 return true;
85868737 break;
85878738 case ICmpInst::ICMP_SGT:
85888739 case ICmpInst::ICMP_SGE:
8589 if (IsKnownPredicateFull(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&
8590 IsKnownPredicateFull(ICmpInst::ICMP_SLE, RHS, FoundRHS))
8740 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&
8741 isKnownViaSimpleReasoning(ICmpInst::ICMP_SLE, RHS, FoundRHS))
85918742 return true;
85928743 break;
85938744 case ICmpInst::ICMP_ULT:
85948745 case ICmpInst::ICMP_ULE:
8595 if (IsKnownPredicateFull(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&
8596 IsKnownPredicateFull(ICmpInst::ICMP_UGE, RHS, FoundRHS))
8746 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&
8747 isKnownViaSimpleReasoning(ICmpInst::ICMP_UGE, RHS, FoundRHS))
85978748 return true;
85988749 break;
85998750 case ICmpInst::ICMP_UGT:
86008751 case ICmpInst::ICMP_UGE:
8601 if (IsKnownPredicateFull(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&
8602 IsKnownPredicateFull(ICmpInst::ICMP_ULE, RHS, FoundRHS))
8752 if (isKnownViaSimpleReasoning(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&
8753 isKnownViaSimpleReasoning(ICmpInst::ICMP_ULE, RHS, FoundRHS))
86038754 return true;
86048755 break;
86058756 }
8757
8758 // Maybe it can be proved via operations?
8759 if (isImpliedViaOperations(Pred, LHS, RHS, FoundLHS, FoundRHS))
8760 return true;
86068761
86078762 return false;
86088763 }
0 ; 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 }
27
28 define void @test_02(i8 %t) {
29 ; CHECK-LABEL: test_02
30 entry:
31 %t.ptr = inttoptr i8 %t to i8*
32 %p.42 = inttoptr i8 42 to i8*
33 %cmp1 = icmp slt i8* %t.ptr, %p.42
34 call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
35 br label %loop
36
37 loop:
38 ; CHECK-LABEL: loop
39 %idx = phi i8* [ %t.ptr, %entry ], [ %snext, %loop ]
40 %snext = getelementptr inbounds i8, i8* %idx, i64 1
41 %c = icmp slt i8* %idx, %p.42
42 ; CHECK: call void @use(i1 true)
43 call void @use(i1 %c)
44 %be = icmp slt i8* %snext, %p.42
45 br i1 %be, label %loop, label %exit
46
47 exit:
48 ret void
49 }
0 ; 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 }