1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py 2; RUN: opt < %s -S -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck %s 3 4declare i1 @cond() 5 6define i32 @test_01(i32 %a, i32 %b) { 7; CHECK-LABEL: 'test_01' 8; CHECK-NEXT: Classifying expressions for: @test_01 9; CHECK-NEXT: %outer.iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.backedge ] 10; CHECK-NEXT: --> %outer.iv U: [0,-2147483647) S: [0,-2147483647) Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant } 11; CHECK-NEXT: %iv = phi i32 [ 0, %outer ], [ %iv.next, %inner.backedge ] 12; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %inner: Computable, %outer: Variant } 13; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1 14; CHECK-NEXT: --> {1,+,1}<nuw><%inner> U: [1,-2147483647) S: [1,-2147483647) Exits: <<Unknown>> LoopDispositions: { %inner: Computable, %outer: Variant } 15; CHECK-NEXT: %inner.loop.cond = call i1 @cond() 16; CHECK-NEXT: --> %inner.loop.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner: Variant, %outer: Variant } 17; CHECK-NEXT: %outer.loop.cond = call i1 @cond() 18; CHECK-NEXT: --> %outer.loop.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant } 19; CHECK-NEXT: Determining loop execution counts for: @test_01 20; CHECK-NEXT: Loop %inner: <multiple exits> Unpredictable backedge-taken count. 21; CHECK-NEXT: exit count for inner: %b 22; CHECK-NEXT: exit count for inner.backedge: ***COULDNOTCOMPUTE*** 23; CHECK-NEXT: Loop %inner: constant max backedge-taken count is i32 2147483647 24; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is %b 25; CHECK-NEXT: symbolic max exit count for inner: %b 26; CHECK-NEXT: symbolic max exit count for inner.backedge: ***COULDNOTCOMPUTE*** 27; CHECK-NEXT: Loop %outer: <multiple exits> Unpredictable backedge-taken count. 28; CHECK-NEXT: exit count for inner: ***COULDNOTCOMPUTE*** 29; CHECK-NEXT: exit count for outer.backedge: ***COULDNOTCOMPUTE*** 30; CHECK-NEXT: Loop %outer: Unpredictable constant max backedge-taken count. 31; CHECK-NEXT: Loop %outer: Unpredictable symbolic max backedge-taken count. 32; CHECK-NEXT: symbolic max exit count for inner: ***COULDNOTCOMPUTE*** 33; CHECK-NEXT: symbolic max exit count for outer.backedge: ***COULDNOTCOMPUTE*** 34; 35entry: 36 %b_is_non_negative = icmp sge i32 %b, 0 37 br i1 %b_is_non_negative, label %outer, label %failure 38 39outer: 40 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 41 br label %inner 42 43inner: 44 %iv = phi i32 [0, %outer], [%iv.next, %inner.backedge] 45 %signed_cond = icmp slt i32 %iv, %b 46 br i1 %signed_cond, label %inner.backedge, label %side.exit 47 48inner.backedge: 49 %iv.next = add nuw nsw i32 %iv, 1 50 %inner.loop.cond = call i1 @cond() 51 br i1 %inner.loop.cond, label %inner, label %outer.backedge 52 53outer.backedge: 54 %outer.loop.cond = call i1 @cond() 55 br i1 %outer.loop.cond, label %outer, label %exit 56 57failure: 58 unreachable 59 60side.exit: 61 ret i32 0 62 63exit: 64 ret i32 1 65} 66 67; FIXME: both outer.iv and iv here can be proved non-negative. 68define i32 @test_02(i32 %a, i32 %b) { 69; CHECK-LABEL: 'test_02' 70; CHECK-NEXT: Classifying expressions for: @test_02 71; CHECK-NEXT: %outer.iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.backedge ] 72; CHECK-NEXT: --> %outer.iv U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant } 73; CHECK-NEXT: %iv = phi i32 [ %outer.iv, %outer ], [ %iv.next, %inner.backedge ] 74; CHECK-NEXT: --> {%outer.iv,+,1}<nuw><nsw><%inner> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner: Computable, %outer: Variant } 75; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1 76; CHECK-NEXT: --> {(1 + %outer.iv),+,1}<nw><%inner> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner: Computable, %outer: Variant } 77; CHECK-NEXT: %inner.loop.cond = call i1 @cond() 78; CHECK-NEXT: --> %inner.loop.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner: Variant, %outer: Variant } 79; CHECK-NEXT: %outer.loop.cond = call i1 @cond() 80; CHECK-NEXT: --> %outer.loop.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant } 81; CHECK-NEXT: Determining loop execution counts for: @test_02 82; CHECK-NEXT: Loop %inner: <multiple exits> Unpredictable backedge-taken count. 83; CHECK-NEXT: exit count for inner: ((-1 * %outer.iv) + (%b smax %outer.iv)) 84; CHECK-NEXT: exit count for inner.backedge: ***COULDNOTCOMPUTE*** 85; CHECK-NEXT: Loop %inner: constant max backedge-taken count is i32 -1 86; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is ((-1 * %outer.iv) + (%b smax %outer.iv)) 87; CHECK-NEXT: symbolic max exit count for inner: ((-1 * %outer.iv) + (%b smax %outer.iv)) 88; CHECK-NEXT: symbolic max exit count for inner.backedge: ***COULDNOTCOMPUTE*** 89; CHECK-NEXT: Loop %outer: <multiple exits> Unpredictable backedge-taken count. 90; CHECK-NEXT: exit count for inner: ***COULDNOTCOMPUTE*** 91; CHECK-NEXT: exit count for outer.backedge: ***COULDNOTCOMPUTE*** 92; CHECK-NEXT: Loop %outer: Unpredictable constant max backedge-taken count. 93; CHECK-NEXT: Loop %outer: Unpredictable symbolic max backedge-taken count. 94; CHECK-NEXT: symbolic max exit count for inner: ***COULDNOTCOMPUTE*** 95; CHECK-NEXT: symbolic max exit count for outer.backedge: ***COULDNOTCOMPUTE*** 96; 97entry: 98 %b_is_non_negative = icmp sge i32 %b, 0 99 br i1 %b_is_non_negative, label %outer, label %failure 100 101outer: 102 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 103 br label %inner 104 105inner: 106 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 107 %signed_cond = icmp slt i32 %iv, %b 108 br i1 %signed_cond, label %inner.backedge, label %side.exit 109 110inner.backedge: 111 %iv.next = add nuw nsw i32 %iv, 1 112 %inner.loop.cond = call i1 @cond() 113 br i1 %inner.loop.cond, label %inner, label %outer.backedge 114 115outer.backedge: 116 %outer.loop.cond = call i1 @cond() 117 br i1 %outer.loop.cond, label %outer, label %exit 118 119failure: 120 unreachable 121 122side.exit: 123 ret i32 0 124 125exit: 126 ret i32 1 127} 128