// getSCEV(Base)->getType() has the same address space as Base->getType()
// because SCEV::getType() preserves the address space.
Type *IntIdxTy = getEffectiveSCEVType(BaseExpr->getType());
- // FIXME(PR23527): Don't blindly transfer the inbounds flag from the GEP
- // instruction to its SCEV, because the Instruction may be guarded by control
- // flow and the no-overflow bits may not be valid for the expression in any
- // context. This can be fixed similarly to how these flags are handled for
- // adds.
+ const bool AssumeInBoundsFlags = [&]() {
+ if (!GEP->isInBounds())
+ return false;
+
+ // We'd like to propagate flags from the IR to the corresponding SCEV nodes,
+ // but to do that, we have to ensure that said flag is valid in the entire
+ // defined scope of the SCEV.
+ auto *GEPI = dyn_cast<Instruction>(GEP);
+ // TODO: non-instructions have global scope. We might be able to prove
+ // some global scope cases
+ return GEPI && isSCEVExprNeverPoison(GEPI);
+ }();
+
SCEV::NoWrapFlags OffsetWrap =
- GEP->isInBounds() ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
+ AssumeInBoundsFlags ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
Type *CurTy = GEP->getType();
bool FirstIter = true;
// Add the base address and the offset. We cannot use the nsw flag, as the
// base address is unsigned. However, if we know that the offset is
// non-negative, we can use nuw.
- SCEV::NoWrapFlags BaseWrap = GEP->isInBounds() && isKnownNonNegative(Offset)
+ SCEV::NoWrapFlags BaseWrap = AssumeInBoundsFlags && isKnownNonNegative(Offset)
? SCEV::FlagNUW : SCEV::FlagAnyWrap;
auto *GEPExpr = getAddExpr(BaseExpr, Offset, BaseWrap);
assert(BaseExpr->getType() == GEPExpr->getType() &&
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
; CHECK: Expressions re-written:
; CHECK-NEXT: [PSE] %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom:
-; CHECK-NEXT: ((4 * (zext i32 {1,+,1}<%for.body> to i64))<nuw><nsw> + %a)<nuw>
+; CHECK-NEXT: ((4 * (zext i32 {1,+,1}<%for.body> to i64))<nuw><nsw> + %a)
; CHECK-NEXT: --> {(4 + %a),+,4}<%for.body>
; CHECK-NEXT: [PSE] %arrayidx4 = getelementptr inbounds i32, i32* %b, i64 %conv11:
-; CHECK-NEXT: ((4 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %b)<nuw>
+; CHECK-NEXT: ((4 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %b)
; CHECK-NEXT: --> {%b,+,4}<%for.body>
define void @test1(i64 %x, i32* %a, i32* %b) {
entry:
; }
; }
-; CHECK-DAG: Loop 'for.i' has cost = 20600
-; CHECK-DAG: Loop 'for.j' has cost = 800
+; CHECK-DAG: Loop 'for.i' has cost = 20300
+; CHECK-DAG: Loop 'for.j' has cost = 700
define void @foo(i64 %n, i64 %m, i32* %A, i32* %B, i32* %C) {
entry:
; CHECK-NEXT: %n.01 = phi %struct.ListNode* [ bitcast ({ %struct.ListNode*, i32, [4 x i8] }* @node5 to %struct.ListNode*), %entry ], [ %1, %for.body ]
; CHECK-NEXT: --> %n.01 U: full-set S: full-set Exits: @node1 LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %i = getelementptr inbounds %struct.ListNode, %struct.ListNode* %n.01, i64 0, i32 1
-; CHECK-NEXT: --> (4 + %n.01)<nuw> U: [4,0) S: [4,0) Exits: (4 + @node1)<nuw><nsw> LoopDispositions: { %for.body: Variant }
+; CHECK-NEXT: --> (4 + %n.01) U: full-set S: full-set Exits: (4 + @node1)<nuw><nsw> LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %0 = load i32, i32* %i, align 4
; CHECK-NEXT: --> %0 U: full-set S: full-set Exits: 0 LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %add = add nsw i32 %0, %sum.02
; CHECK-NEXT: %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
; CHECK-NEXT: --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-2 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
-; CHECK-NEXT: --> {(1 + %ptr)<nuw>,+,1}<nuw><%while.body125> U: [1,0) S: [1,0) Exits: {(-1 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
+; CHECK-NEXT: --> {(1 + %ptr),+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-1 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: Determining loop execution counts for: @crash
; CHECK-NEXT: Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
; CHECK-NEXT: Loop %while.body125: max backedge-taken count is -2
; CHECK-NEXT: %sunkaddr3 = mul i64 %add4.zext, 4
; CHECK-NEXT: --> (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> U: [0,17179869169) S: [0,17179869181)
; CHECK-NEXT: %sunkaddr4 = getelementptr inbounds i8, i8* bitcast ({ %union, [2000 x i8] }* @tmp_addr to i8*), i64 %sunkaddr3
-; CHECK-NEXT: --> ((4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> ((4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %sunkaddr5 = getelementptr inbounds i8, i8* %sunkaddr4, i64 4096
-; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [4096,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %addr4.cast = bitcast i8* %sunkaddr5 to i32*
-; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [4096,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %addr4.incr = getelementptr i32, i32* %addr4.cast, i64 1
; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %add5 = add i32 %mul, 5
; CHECK-NEXT: %sunkaddr0 = mul i64 %add5.zext, 4
; CHECK-NEXT: --> (4 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw>)<nuw><nsw> U: [4,17179869173) S: [4,17179869185)
; CHECK-NEXT: %sunkaddr1 = getelementptr inbounds i8, i8* bitcast ({ %union, [2000 x i8] }* @tmp_addr to i8*), i64 %sunkaddr0
-; CHECK-NEXT: --> (4 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [4,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %sunkaddr2 = getelementptr inbounds i8, i8* %sunkaddr1, i64 4096
-; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %addr5.cast = bitcast i8* %sunkaddr2 to i32*
-; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: Determining loop execution counts for: @f3
;
entry:
; CHECK-LABEL: 'pointer_iv_nowrap'
; CHECK-NEXT: Classifying expressions for: @pointer_iv_nowrap
; CHECK-NEXT: %init = getelementptr inbounds i8, i8* %startptr, i64 2000
-; CHECK-NEXT: --> (2000 + %startptr)<nuw> U: [2000,0) S: [2000,0)
+; CHECK-NEXT: --> (2000 + %startptr) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i8* [ %init, %entry ], [ %iv.next, %loop ]
-; CHECK-NEXT: --> {(2000 + %startptr)<nuw>,+,1}<nuw><%loop> U: [2000,0) S: [2000,0) Exits: ((-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)) + %startptr) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {(2000 + %startptr),+,1}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = getelementptr inbounds i8, i8* %iv, i64 1
-; CHECK-NEXT: --> {(2001 + %startptr)<nuw>,+,1}<nuw><%loop> U: [2001,0) S: [2001,0) Exits: (1 + (-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)) + %startptr) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {(2001 + %startptr),+,1}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @pointer_iv_nowrap
-; CHECK-NEXT: Loop %loop: backedge-taken count is (-2000 + (-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)))
-; CHECK-NEXT: Loop %loop: max backedge-taken count is -2001
-; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-2000 + (-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)))
-; CHECK-NEXT: Predicates:
-; CHECK: Loop %loop: Trip multiple is 1
+; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count.
;
entry:
%init = getelementptr inbounds i8, i8* %startptr, i64 2000
; CHECK-LABEL: 'pointer_iv_nowrap_guard'
; CHECK-NEXT: Classifying expressions for: @pointer_iv_nowrap_guard
; CHECK-NEXT: %init = getelementptr inbounds i32, i32* %startptr, i64 2000
-; CHECK-NEXT: --> (8000 + %startptr)<nuw> U: [8000,0) S: [8000,0)
+; CHECK-NEXT: --> (8000 + %startptr) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i32* [ %init, %entry ], [ %iv.next, %loop ]
-; CHECK-NEXT: --> {(8000 + %startptr)<nuw>,+,4}<nuw><%loop> U: [8000,0) S: [8000,0) Exits: (8000 + (4 * ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + (ptrtoint i32* %endptr to i64)) /u 4))<nuw> + %startptr) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {(8000 + %startptr),+,4}<nuw><%loop> U: full-set S: full-set Exits: (8000 + (4 * ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + ((8004 + (ptrtoint i32* %startptr to i64)) umax (ptrtoint i32* %endptr to i64))) /u 4))<nuw> + %startptr) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = getelementptr inbounds i32, i32* %iv, i64 1
-; CHECK-NEXT: --> {(8004 + %startptr)<nuw>,+,4}<nuw><%loop> U: [8004,0) S: [8004,0) Exits: (8004 + (4 * ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + (ptrtoint i32* %endptr to i64)) /u 4))<nuw> + %startptr) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {(8004 + %startptr),+,4}<nuw><%loop> U: full-set S: full-set Exits: (8004 + (4 * ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + ((8004 + (ptrtoint i32* %startptr to i64)) umax (ptrtoint i32* %endptr to i64))) /u 4))<nuw> + %startptr) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @pointer_iv_nowrap_guard
-; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + (ptrtoint i32* %endptr to i64)) /u 4)
-; CHECK-NEXT: Loop %loop: max backedge-taken count is 4611686018427385902
-; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + (ptrtoint i32* %endptr to i64)) /u 4)
+; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + ((8004 + (ptrtoint i32* %startptr to i64)) umax (ptrtoint i32* %endptr to i64))) /u 4)
+; CHECK-NEXT: Loop %loop: max backedge-taken count is 4611686018427387903
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((-8001 + (-1 * (ptrtoint i32* %startptr to i64)) + ((8004 + (ptrtoint i32* %startptr to i64)) umax (ptrtoint i32* %endptr to i64))) /u 4)
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
;
; CHECK-NEXT: %phitmp = sext i32 %tmp8 to i64
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%bb> U: [1,-9223372036854775808) S: [1,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %bb: Computable }
; CHECK-NEXT: %tmp9 = getelementptr inbounds double, double* %p, i64 %phitmp
-; CHECK-NEXT: --> {(8 + %p)<nuw>,+,8}<nuw><%bb> U: [8,0) S: [8,0) Exits: <<Unknown>> LoopDispositions: { %bb: Computable }
+; CHECK-NEXT: --> {(8 + %p),+,8}<%bb> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test1
; CHECK-NEXT: Loop %bb: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %bb: Unpredictable max backedge-taken count.
; CHECK-NEXT: %__first.addr.02.i.i = phi i32* [ %begin, %for.body.lr.ph.i.i ], [ %ptrincdec.i.i, %for.body.i.i ]
; CHECK-NEXT: --> {%begin,+,4}<nuw><%for.body.i.i> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4))<nuw> + %begin) LoopDispositions: { %for.body.i.i: Computable }
; CHECK-NEXT: %ptrincdec.i.i = getelementptr inbounds i32, i32* %__first.addr.02.i.i, i64 1
-; CHECK-NEXT: --> {(4 + %begin)<nuw>,+,4}<nuw><%for.body.i.i> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4))<nuw> + %begin) LoopDispositions: { %for.body.i.i: Computable }
+; CHECK-NEXT: --> {(4 + %begin),+,4}<nuw><%for.body.i.i> U: full-set S: full-set Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4))<nuw> + %begin) LoopDispositions: { %for.body.i.i: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test2
; CHECK-NEXT: Loop %for.body.i.i: backedge-taken count is ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4)
; CHECK-NEXT: Loop %for.body.i.i: max backedge-taken count is 4611686018427387903
; CHECK-LABEL: 'test3'
; CHECK-NEXT: Classifying expressions for: @test3
; CHECK-NEXT: %indvar.i.i = phi i64 [ %tmp, %for.body.i.i ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body.i.i> U: [0,4611686018427387904) S: [0,4611686018427387904) Exits: ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4) LoopDispositions: { %for.body.i.i: Computable }
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body.i.i> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %for.body.i.i: Computable }
; CHECK-NEXT: %tmp = add nsw i64 %indvar.i.i, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%for.body.i.i> U: [1,4611686018427387905) S: [1,4611686018427387905) Exits: (1 + ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4))<nuw><nsw> LoopDispositions: { %for.body.i.i: Computable }
+; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%for.body.i.i> U: [1,-9223372036854775808) S: [1,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %for.body.i.i: Computable }
; CHECK-NEXT: %ptrincdec.i.i = getelementptr inbounds i32, i32* %begin, i64 %tmp
-; CHECK-NEXT: --> {(4 + %begin)<nuw>,+,4}<nuw><%for.body.i.i> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4))<nuw> + %begin) LoopDispositions: { %for.body.i.i: Computable }
+; CHECK-NEXT: --> {(4 + %begin),+,4}<%for.body.i.i> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.body.i.i: Computable }
; CHECK-NEXT: %__first.addr.08.i.i = getelementptr inbounds i32, i32* %begin, i64 %indvar.i.i
-; CHECK-NEXT: --> {%begin,+,4}<nuw><%for.body.i.i> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4))<nuw> + %begin) LoopDispositions: { %for.body.i.i: Computable }
+; CHECK-NEXT: --> {%begin,+,4}<nuw><%for.body.i.i> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.body.i.i: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test3
-; CHECK-NEXT: Loop %for.body.i.i: backedge-taken count is ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4)
-; CHECK-NEXT: Loop %for.body.i.i: max backedge-taken count is 4611686018427387903
-; CHECK-NEXT: Loop %for.body.i.i: Predicated backedge-taken count is ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4)
-; CHECK-NEXT: Predicates:
-; CHECK: Loop %for.body.i.i: Trip multiple is 1
+; CHECK-NEXT: Loop %for.body.i.i: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %for.body.i.i: Unpredictable max backedge-taken count.
+; CHECK-NEXT: Loop %for.body.i.i: Unpredictable predicated backedge-taken count.
;
entry:
%cmp7.i.i = icmp eq i32* %begin, %end
; CHECK-LABEL: 'PR12375'
; CHECK-NEXT: Classifying expressions for: @PR12375
; CHECK-NEXT: %tmp = getelementptr inbounds i32, i32* %arg, i64 2
-; CHECK-NEXT: --> (8 + %arg)<nuw> U: [8,0) S: [8,0)
+; CHECK-NEXT: --> (8 + %arg) U: full-set S: full-set
; CHECK-NEXT: %tmp2 = phi i32* [ %arg, %bb ], [ %tmp5, %bb1 ]
-; CHECK-NEXT: --> {%arg,+,4}<nuw><%bb1> U: full-set S: full-set Exits: (4 + %arg)<nuw> LoopDispositions: { %bb1: Computable }
+; CHECK-NEXT: --> {%arg,+,4}<nuw><%bb1> U: full-set S: full-set Exits: ((4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (8 + (ptrtoint i32* %arg to i64)))) /u 4))<nuw> + %arg) LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: %tmp3 = phi i32 [ 0, %bb ], [ %tmp4, %bb1 ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb1> U: [0,-2147483648) S: [0,-2147483648) Exits: 1 LoopDispositions: { %bb1: Computable }
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb1> U: [0,-2147483648) S: [0,-2147483648) Exits: (trunc i64 ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (8 + (ptrtoint i32* %arg to i64)))) /u 4) to i32) LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: %tmp4 = add nsw i32 %tmp3, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%bb1> U: [1,0) S: [1,0) Exits: 2 LoopDispositions: { %bb1: Computable }
+; CHECK-NEXT: --> {1,+,1}<nuw><%bb1> U: [1,0) S: [1,0) Exits: (1 + (trunc i64 ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (8 + (ptrtoint i32* %arg to i64)))) /u 4) to i32)) LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: %tmp5 = getelementptr inbounds i32, i32* %tmp2, i64 1
-; CHECK-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb1> U: [4,0) S: [4,0) Exits: (8 + %arg)<nuw> LoopDispositions: { %bb1: Computable }
+; CHECK-NEXT: --> {(4 + %arg),+,4}<nuw><%bb1> U: full-set S: full-set Exits: (4 + (4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (8 + (ptrtoint i32* %arg to i64)))) /u 4))<nuw> + %arg) LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: Determining loop execution counts for: @PR12375
-; CHECK-NEXT: Loop %bb1: backedge-taken count is 1
-; CHECK-NEXT: Loop %bb1: max backedge-taken count is 1
-; CHECK-NEXT: Loop %bb1: Predicated backedge-taken count is 1
+; CHECK-NEXT: Loop %bb1: backedge-taken count is ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (8 + (ptrtoint i32* %arg to i64)))) /u 4)
+; CHECK-NEXT: Loop %bb1: max backedge-taken count is 1, actual taken count either this or zero.
+; CHECK-NEXT: Loop %bb1: Predicated backedge-taken count is ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (8 + (ptrtoint i32* %arg to i64)))) /u 4)
; CHECK-NEXT: Predicates:
-; CHECK: Loop %bb1: Trip multiple is 2
+; CHECK: Loop %bb1: Trip multiple is 1
;
bb:
%tmp = getelementptr inbounds i32, i32* %arg, i64 2
; CHECK-LABEL: 'PR12376'
; CHECK-NEXT: Classifying expressions for: @PR12376
; CHECK-NEXT: %tmp = phi i32* [ %arg, %bb ], [ %tmp4, %bb2 ]
-; CHECK-NEXT: --> {%arg,+,4}<nuw><%bb2> U: full-set S: full-set Exits: ((4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64))<nuw> umax (ptrtoint i32* %arg1 to i64))) /u 4))<nuw> + %arg) LoopDispositions: { %bb2: Computable }
+; CHECK-NEXT: --> {%arg,+,4}<nuw><%bb2> U: full-set S: full-set Exits: ((4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (ptrtoint i32* %arg1 to i64))) /u 4))<nuw> + %arg) LoopDispositions: { %bb2: Computable }
; CHECK-NEXT: %tmp4 = getelementptr inbounds i32, i32* %tmp, i64 1
-; CHECK-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb2> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64))<nuw> umax (ptrtoint i32* %arg1 to i64))) /u 4))<nuw> + %arg) LoopDispositions: { %bb2: Computable }
+; CHECK-NEXT: --> {(4 + %arg),+,4}<nuw><%bb2> U: full-set S: full-set Exits: (4 + (4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (ptrtoint i32* %arg1 to i64))) /u 4))<nuw> + %arg) LoopDispositions: { %bb2: Computable }
; CHECK-NEXT: Determining loop execution counts for: @PR12376
-; CHECK-NEXT: Loop %bb2: backedge-taken count is ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64))<nuw> umax (ptrtoint i32* %arg1 to i64))) /u 4)
-; CHECK-NEXT: Loop %bb2: max backedge-taken count is 4611686018427387902
-; CHECK-NEXT: Loop %bb2: Predicated backedge-taken count is ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64))<nuw> umax (ptrtoint i32* %arg1 to i64))) /u 4)
+; CHECK-NEXT: Loop %bb2: backedge-taken count is ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (ptrtoint i32* %arg1 to i64))) /u 4)
+; CHECK-NEXT: Loop %bb2: max backedge-taken count is 4611686018427387903
+; CHECK-NEXT: Loop %bb2: Predicated backedge-taken count is ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64)) umax (ptrtoint i32* %arg1 to i64))) /u 4)
; CHECK-NEXT: Predicates:
; CHECK: Loop %bb2: Trip multiple is 1
;
; X64-LABEL: 'ptrtoint_of_gep'
; X64-NEXT: Classifying expressions for: @ptrtoint_of_gep
; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
-; X64-NEXT: --> (42 + %in)<nuw> U: [42,0) S: [42,0)
+; X64-NEXT: --> (42 + %in) U: full-set S: full-set
; X64-NEXT: %p0 = ptrtoint i8* %in_adj to i64
-; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64))<nuw> U: [42,0) S: [42,0)
+; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64)) U: full-set S: full-set
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
;
; X32-LABEL: 'ptrtoint_of_gep'
; X32-NEXT: Classifying expressions for: @ptrtoint_of_gep
; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
-; X32-NEXT: --> (42 + %in)<nuw> U: [42,0) S: [42,0)
+; X32-NEXT: --> (42 + %in) U: full-set S: full-set
; X32-NEXT: %p0 = ptrtoint i8* %in_adj to i64
-; X32-NEXT: --> (42 + (zext i32 (ptrtoint i8* %in to i32) to i64))<nuw><nsw> U: [42,4294967338) S: [42,4294967338)
+; X32-NEXT: --> (zext i32 (42 + (ptrtoint i8* %in to i32)) to i64) U: [0,4294967296) S: [0,4294967296)
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
;
%in_adj = getelementptr inbounds i8, i8* %in, i64 42
; X64-NEXT: %i6 = phi i64 [ 0, %entry ], [ %i9, %loop ]
; X64-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: (-1 + (zext i32 %count to i64))<nsw> LoopDispositions: { %loop: Computable }
; X64-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6
-; X64-NEXT: --> {%in,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) LoopDispositions: { %loop: Computable }
+; X64-NEXT: --> {%in,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) LoopDispositions: { %loop: Computable }
; X64-NEXT: %i8 = ptrtoint i32* %i7 to i64
-; X64-NEXT: --> {(ptrtoint i32* %in to i64),+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + (ptrtoint i32* %in to i64)) LoopDispositions: { %loop: Computable }
+; X64-NEXT: --> {(ptrtoint i32* %in to i64),+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + (ptrtoint i32* %in to i64)) LoopDispositions: { %loop: Computable }
; X64-NEXT: %i9 = add nuw nsw i64 %i6, 1
; X64-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (zext i32 %count to i64) LoopDispositions: { %loop: Computable }
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrec
; X64-NEXT: %i13 = add i8 %i12, %i8
; X64-NEXT: --> (%i12 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i14 = getelementptr inbounds i8, i8* %i7, i64 1
-; X64-NEXT: --> {(1 + %arg)<nuw>,+,1}<nuw><%bb6> U: [1,0) S: [1,0) Exits: ((-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* %arg1 to i64) + %arg) LoopDispositions: { %bb6: Computable }
+; X64-NEXT: --> {(1 + %arg),+,1}<nuw><%bb6> U: full-set S: full-set Exits: ((-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* %arg1 to i64) + %arg) LoopDispositions: { %bb6: Computable }
; X64-NEXT: Determining loop execution counts for: @pr46786_c26_char
; X64-NEXT: Loop %bb6: backedge-taken count is (-1 + (-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* %arg1 to i64))
; X64-NEXT: Loop %bb6: max backedge-taken count is -1
; X32-NEXT: %i13 = add i8 %i12, %i8
; X32-NEXT: --> (%i12 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i14 = getelementptr inbounds i8, i8* %i7, i64 1
-; X32-NEXT: --> {(1 + %arg)<nuw>,+,1}<nuw><%bb6> U: [1,0) S: [1,0) Exits: ((-1 * (ptrtoint i8* %arg to i32)) + (ptrtoint i8* %arg1 to i32) + %arg) LoopDispositions: { %bb6: Computable }
+; X32-NEXT: --> {(1 + %arg),+,1}<nuw><%bb6> U: full-set S: full-set Exits: ((-1 * (ptrtoint i8* %arg to i32)) + (ptrtoint i8* %arg1 to i32) + %arg) LoopDispositions: { %bb6: Computable }
; X32-NEXT: Determining loop execution counts for: @pr46786_c26_char
; X32-NEXT: Loop %bb6: backedge-taken count is (-1 + (-1 * (ptrtoint i8* %arg to i32)) + (ptrtoint i8* %arg1 to i32))
; X32-NEXT: Loop %bb6: max backedge-taken count is -1
; X64-NEXT: %i14 = add nsw i32 %i13, %i8
; X64-NEXT: --> (%i13 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i15 = getelementptr inbounds i32, i32* %i7, i64 1
-; X64-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb6> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* %arg1 to i64)) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
+; X64-NEXT: --> {(4 + %arg),+,4}<nuw><%bb6> U: full-set S: full-set Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* %arg1 to i64)) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
; X64-NEXT: Determining loop execution counts for: @pr46786_c26_int
; X64-NEXT: Loop %bb6: backedge-taken count is ((-4 + (-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* %arg1 to i64)) /u 4)
; X64-NEXT: Loop %bb6: max backedge-taken count is 4611686018427387903
; X32-NEXT: %i11 = ashr exact i64 %i10, 2
; X32-NEXT: --> %i11 U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11
-; X32-NEXT: --> ((4 * (trunc i64 %i11 to i32))<nsw> + %arg2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
+; X32-NEXT: --> ((4 * (trunc i64 %i11 to i32)) + %arg2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i13 = load i32, i32* %i12, align 4
; X32-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i14 = add nsw i32 %i13, %i8
; X32-NEXT: --> (%i13 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i15 = getelementptr inbounds i32, i32* %i7, i64 1
-; X32-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb6> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %arg to i32)) + (ptrtoint i32* %arg1 to i32)) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
+; X32-NEXT: --> {(4 + %arg),+,4}<nuw><%bb6> U: full-set S: full-set Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint i32* %arg to i32)) + (ptrtoint i32* %arg1 to i32)) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
; X32-NEXT: Determining loop execution counts for: @pr46786_c26_int
; X32-NEXT: Loop %bb6: backedge-taken count is ((-4 + (-1 * (ptrtoint i32* %arg to i32)) + (ptrtoint i32* %arg1 to i32)) /u 4)
; X32-NEXT: Loop %bb6: max backedge-taken count is 1073741823
; CHECK-NEXT: %idxprom = sext i32 %rem to i64
; CHECK-NEXT: --> ({0,+,1}<nuw><nsw><%for.cond> /u 2) U: [0,2147483648) S: [0,2147483648) Exits: ((zext i32 %width to i64) /u 2) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %storage, i64 0, i64 %idxprom
-; CHECK-NEXT: --> ((4 * ({0,+,1}<nuw><nsw><%for.cond> /u 2))<nuw><nsw> + %storage)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * ((zext i32 %width to i64) /u 2))<nuw><nsw> + %storage)<nuw> LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT: --> ((4 * ({0,+,1}<nuw><nsw><%for.cond> /u 2))<nuw><nsw> + %storage) U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * ((zext i32 %width to i64) /u 2))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32, i32* %arrayidx, align 4
; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %call = call i32 @_Z3adji(i32 %1)
; CHECK-NEXT: %idxprom = sext i32 %rem to i64
; CHECK-NEXT: --> (zext i1 {false,+,true}<%for.cond> to i64) U: [0,2) S: [0,2) Exits: (zext i1 (trunc i32 %width to i1) to i64) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %storage, i64 0, i64 %idxprom
-; CHECK-NEXT: --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage)<nuw> LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT: --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage) U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32, i32* %arrayidx, align 4
; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %call = call i32 @_Z3adji(i32 %1)
; CHECK: bb3:
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @global, i64 0, i64 2), i64 -1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, i8* [[TMP4]], align 1
-; CHECK-NEXT: br i1 false, label [[BB7:%.*]], label [[BB11:%.*]]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ugt i8* [[TMP4]], getelementptr inbounds ([0 x i8], [0 x i8]* @global, i64 0, i64 500)
+; CHECK-NEXT: br i1 [[TMP5]], label [[BB7:%.*]], label [[BB11:%.*]]
; CHECK: bb7:
; CHECK-NEXT: [[TMP8:%.*]] = zext i8 [[TMP6]] to i64
; CHECK-NEXT: br i1 true, label [[BB11]], label [[BB3]]
; CHECK-NEXT: [[LSR_IV5:%.*]] = phi i64 [ [[LSR_IV_NEXT6:%.*]], [[LOOP_1_HEADER]] ], [ [[START1]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[IV:%.*]] = phi %struct.hoge* [ [[IV_NEXT:%.*]], [[LOOP_1_HEADER]] ], [ [[START]], [[ENTRY]] ]
; CHECK-NEXT: [[IV_NEXT]] = getelementptr inbounds [[STRUCT_HOGE:%.*]], %struct.hoge* [[IV]], i64 1
-; CHECK-NEXT: [[LSR_IV_NEXT6]] = add nuw i64 [[LSR_IV5]], 16
+; CHECK-NEXT: [[LSR_IV_NEXT6]] = add i64 [[LSR_IV5]], 16
; CHECK-NEXT: [[EC:%.*]] = icmp eq %struct.hoge* [[IV_NEXT]], [[END:%.*]]
; CHECK-NEXT: br i1 [[EC]], label [[LOOP_2_PH:%.*]], label [[LOOP_1_HEADER]]
; CHECK: loop.2.ph:
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[i1] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
-; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2305843009213693951 };
+; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] };
; ALL-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
-; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2305843009213693951 };
+; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] };
; ALL-NEXT: }
;
; void f(int *A) {
; CHECK: Assumed Context:
; CHECK-NEXT: { : }
; CHECK-NEXT: Invalid Context:
-; CHECK-NEXT: { : false }
+; CHECK-NEXT: { : N >= 1152921504606846977 and (P < 0 or P > 0) }
; CHECK: Stmt_store
; CHECK: Domain :=
; CHECK: Invariant Accesses: {
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] -> MemRef_A[o0] : -2 + 5N <= 3o0 <= 5N };
-; CHECK-NEXT: Execution Context: [N] -> { : 0 < N <= 1844674407370955161 }
+; CHECK-NEXT: Execution Context: [N] -> { : 0 < N <= 1383505805528216371 }
; CHECK-NEXT: }
;
; CHECK: Assumed Context:
; CHECK-NEXT: [N] -> { : }
; CHECK-NEXT: Invalid Context:
-; CHECK-NEXT: [N] -> { : N >= 1844674407370955162 }
+; CHECK-NEXT: [N] -> { : N >= 1383505805528216372 }
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] -> MemRef_A[o0] : -2 + i0 <= 3o0 <= i0 };