llvm.org GIT mirror llvm / 9f93d30
ScalarEvolution support for <= and >= loops. Also, generalize ScalarEvolutions's min and max recognition to handle some new forms of min and max that this change makes more common. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102234 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
5 changed file(s) with 138 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
34153415 // fall through
34163416 case ICmpInst::ICMP_SGT:
34173417 case ICmpInst::ICMP_SGE:
3418 if (LHS == U->getOperand(1) && RHS == U->getOperand(2))
3419 return getSMaxExpr(getSCEV(LHS), getSCEV(RHS));
3420 else if (LHS == U->getOperand(2) && RHS == U->getOperand(1))
3421 return getSMinExpr(getSCEV(LHS), getSCEV(RHS));
3418 // a >s b ? a+x : b+x -> smax(a, b)+x
3419 // a >s b ? b+x : a+x -> smin(a, b)+x
3420 if (LHS->getType() == U->getType()) {
3421 const SCEV *LS = getSCEV(LHS);
3422 const SCEV *RS = getSCEV(RHS);
3423 const SCEV *LA = getSCEV(U->getOperand(1));
3424 const SCEV *RA = getSCEV(U->getOperand(2));
3425 const SCEV *LDiff = getMinusSCEV(LA, LS);
3426 const SCEV *RDiff = getMinusSCEV(RA, RS);
3427 if (LDiff == RDiff)
3428 return getAddExpr(getSMaxExpr(LS, RS), LDiff);
3429 LDiff = getMinusSCEV(LA, RS);
3430 RDiff = getMinusSCEV(RA, LS);
3431 if (LDiff == RDiff)
3432 return getAddExpr(getSMinExpr(LS, RS), LDiff);
3433 }
34223434 break;
34233435 case ICmpInst::ICMP_ULT:
34243436 case ICmpInst::ICMP_ULE:
34263438 // fall through
34273439 case ICmpInst::ICMP_UGT:
34283440 case ICmpInst::ICMP_UGE:
3429 if (LHS == U->getOperand(1) && RHS == U->getOperand(2))
3430 return getUMaxExpr(getSCEV(LHS), getSCEV(RHS));
3431 else if (LHS == U->getOperand(2) && RHS == U->getOperand(1))
3432 return getUMinExpr(getSCEV(LHS), getSCEV(RHS));
3441 // a >u b ? a+x : b+x -> umax(a, b)+x
3442 // a >u b ? b+x : a+x -> umin(a, b)+x
3443 if (LHS->getType() == U->getType()) {
3444 const SCEV *LS = getSCEV(LHS);
3445 const SCEV *RS = getSCEV(RHS);
3446 const SCEV *LA = getSCEV(U->getOperand(1));
3447 const SCEV *RA = getSCEV(U->getOperand(2));
3448 const SCEV *LDiff = getMinusSCEV(LA, LS);
3449 const SCEV *RDiff = getMinusSCEV(RA, RS);
3450 if (LDiff == RDiff)
3451 return getAddExpr(getUMaxExpr(LS, RS), LDiff);
3452 LDiff = getMinusSCEV(LA, RS);
3453 RDiff = getMinusSCEV(RA, LS);
3454 if (LDiff == RDiff)
3455 return getAddExpr(getUMinExpr(LS, RS), LDiff);
3456 }
34333457 break;
34343458 case ICmpInst::ICMP_NE:
3435 // n != 0 ? n : 1 -> umax(n, 1)
3436 if (LHS == U->getOperand(1) &&
3437 isa(U->getOperand(2)) &&
3438 cast(U->getOperand(2))->isOne() &&
3459 // n != 0 ? n+x : 1+x -> umax(n, 1)+x
3460 if (LHS->getType() == U->getType() &&
34393461 isa(RHS) &&
3440 cast(RHS)->isZero())
3441 return getUMaxExpr(getSCEV(LHS), getSCEV(U->getOperand(2)));
3462 cast(RHS)->isZero()) {
3463 const SCEV *One = getConstant(LHS->getType(), 1);
3464 const SCEV *LS = getSCEV(LHS);
3465 const SCEV *LA = getSCEV(U->getOperand(1));
3466 const SCEV *RA = getSCEV(U->getOperand(2));
3467 const SCEV *LDiff = getMinusSCEV(LA, LS);
3468 const SCEV *RDiff = getMinusSCEV(RA, One);
3469 if (LDiff == RDiff)
3470 return getAddExpr(getUMaxExpr(LS, One), LDiff);
3471 }
34423472 break;
34433473 case ICmpInst::ICMP_EQ:
3444 // n == 0 ? 1 : n -> umax(n, 1)
3445 if (LHS == U->getOperand(2) &&
3446 isa(U->getOperand(1)) &&
3447 cast(U->getOperand(1))->isOne() &&
3474 // n == 0 ? 1+x : n+x -> umax(n, 1)+x
3475 if (LHS->getType() == U->getType() &&
34483476 isa(RHS) &&
3449 cast(RHS)->isZero())
3450 return getUMaxExpr(getSCEV(LHS), getSCEV(U->getOperand(1)));
3477 cast(RHS)->isZero()) {
3478 const SCEV *One = getConstant(LHS->getType(), 1);
3479 const SCEV *LS = getSCEV(LHS);
3480 const SCEV *LA = getSCEV(U->getOperand(1));
3481 const SCEV *RA = getSCEV(U->getOperand(2));
3482 const SCEV *LDiff = getMinusSCEV(LA, One);
3483 const SCEV *RDiff = getMinusSCEV(RA, LS);
3484 if (LDiff == RDiff)
3485 return getAddExpr(getUMaxExpr(LS, One), LDiff);
3486 }
34513487 break;
34523488 default:
34533489 break;
38843920 if (!isa(Ret)) return Ret;
38853921 }
38863922
3923 // If possible, canonicalize GE/LE comparisons to GT/LT comparisons, by
3924 // adding or subtracting 1 from one of the operands.
3925 switch (Cond) {
3926 case ICmpInst::ICMP_SLE:
3927 if (!getSignedRange(RHS).getSignedMax().isMaxSignedValue()) {
3928 RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS,
3929 /*HasNUW=*/false, /*HasNSW=*/true);
3930 Cond = ICmpInst::ICMP_SLT;
3931 } else if (!getSignedRange(LHS).getSignedMin().isMinSignedValue()) {
3932 LHS = getAddExpr(getConstant(RHS->getType(), -1, true), LHS,
3933 /*HasNUW=*/false, /*HasNSW=*/true);
3934 Cond = ICmpInst::ICMP_SLT;
3935 }
3936 break;
3937 case ICmpInst::ICMP_SGE:
3938 if (!getSignedRange(RHS).getSignedMin().isMinSignedValue()) {
3939 RHS = getAddExpr(getConstant(RHS->getType(), -1, true), RHS,
3940 /*HasNUW=*/false, /*HasNSW=*/true);
3941 Cond = ICmpInst::ICMP_SGT;
3942 } else if (!getSignedRange(LHS).getSignedMax().isMaxSignedValue()) {
3943 LHS = getAddExpr(getConstant(RHS->getType(), 1, true), LHS,
3944 /*HasNUW=*/false, /*HasNSW=*/true);
3945 Cond = ICmpInst::ICMP_SGT;
3946 }
3947 break;
3948 case ICmpInst::ICMP_ULE:
3949 if (!getUnsignedRange(RHS).getUnsignedMax().isMaxValue()) {
3950 RHS = getAddExpr(getConstant(RHS->getType(), 1, false), RHS,
3951 /*HasNUW=*/true, /*HasNSW=*/false);
3952 Cond = ICmpInst::ICMP_ULT;
3953 } else if (!getUnsignedRange(LHS).getUnsignedMin().isMinValue()) {
3954 LHS = getAddExpr(getConstant(RHS->getType(), -1, false), LHS,
3955 /*HasNUW=*/true, /*HasNSW=*/false);
3956 Cond = ICmpInst::ICMP_ULT;
3957 }
3958 break;
3959 case ICmpInst::ICMP_UGE:
3960 if (!getUnsignedRange(RHS).getUnsignedMin().isMinValue()) {
3961 RHS = getAddExpr(getConstant(RHS->getType(), -1, false), RHS,
3962 /*HasNUW=*/true, /*HasNSW=*/false);
3963 Cond = ICmpInst::ICMP_UGT;
3964 } else if (!getUnsignedRange(LHS).getUnsignedMax().isMaxValue()) {
3965 LHS = getAddExpr(getConstant(RHS->getType(), 1, false), LHS,
3966 /*HasNUW=*/true, /*HasNSW=*/false);
3967 Cond = ICmpInst::ICMP_UGT;
3968 }
3969 break;
3970 default:
3971 break;
3972 }
3973
38873974 switch (Cond) {
38883975 case ICmpInst::ICMP_NE: { // while (X != Y)
38893976 // Convert to: while (X-Y != 0)
0 ; RUN: opt < %s -analyze -scalar-evolution |& \
11 ; RUN: grep {Loop %bb: backedge-taken count is (7 + (-1 \\* %argc))}
2 ; XFAIL: *
32
43 define i32 @main(i32 %argc, i8** %argv) nounwind {
54 entry:
0 ; RUN: opt < %s -analyze -scalar-evolution | grep {backedge-taken count is 255}
1 ; XFAIL: *
21
32 define i32 @foo(i32 %x, i32 %y, i32* %lam, i32* %alp) nounwind {
43 bb1.thread:
None ; RUN: opt < %s -analyze -scalar-evolution | grep {0 smax}
1 ; XFAIL: *
0 ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
1
2 ; CHECK: @f
3 ; CHECK: Loop %bb16.preheader: backedge-taken count is (-1 + %c.idx.val)
24
35 define i32 @f(i32 %c.idx.val) {
46
0 ; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
1
2 ; ScalarEvolution should be able to use nsw information to prove that
3 ; this loop has a finite trip count.
4
5 ; CHECK: @le
6 ; CHECK: Loop %for.body: backedge-taken count is %n
7 ; CHECK: Loop %for.body: max backedge-taken count is 9223372036854775807
8
9 define void @le(i64 %n, double* nocapture %p) nounwind {
10 entry:
11 %cmp6 = icmp slt i64 %n, 0 ; [#uses=1]
12 br i1 %cmp6, label %for.end, label %for.body
13
14 for.body: ; preds = %for.body, %entry
15 %i = phi i64 [ %i.next, %for.body ], [ 0, %entry ] ; [#uses=2]
16 %arrayidx = getelementptr double* %p, i64 %i ; [#uses=2]
17 %t4 = load double* %arrayidx ; [#uses=1]
18 %mul = fmul double %t4, 2.200000e+00 ; [#uses=1]
19 store double %mul, double* %arrayidx
20 %i.next = add nsw i64 %i, 1 ; [#uses=2]
21 %cmp = icmp sgt i64 %i.next, %n ; [#uses=1]
22 br i1 %cmp, label %for.end, label %for.body
23
24 for.end: ; preds = %for.body, %entry
25 ret void
26 }