1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s 3 4define i32 @f0(i32 %x, i32 %y) { 5; CHECK-LABEL: 'f0' 6; CHECK-NEXT: Classifying expressions for: @f0 7; CHECK-NEXT: %sum = add i32 %x, %y 8; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set 9; CHECK-NEXT: %v = phi i32 [ %sum, %add ], [ %x, %entry ] 10; CHECK-NEXT: --> ((0 smax %y) + %x) U: full-set S: full-set 11; CHECK-NEXT: Determining loop execution counts for: @f0 12; 13entry: 14 %c = icmp sgt i32 %y, 0 15 br i1 %c, label %add, label %merge 16 17add: 18 %sum = add i32 %x, %y 19 br label %merge 20 21merge: 22 %v = phi i32 [ %sum, %add ], [ %x, %entry ] 23 ret i32 %v 24} 25 26define i32 @f1(i32 %x, i32 %y) { 27; CHECK-LABEL: 'f1' 28; CHECK-NEXT: Classifying expressions for: @f1 29; CHECK-NEXT: %sum = add i32 %x, %y 30; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set 31; CHECK-NEXT: %v = phi i32 [ %sum, %add ], [ %x, %entry ] 32; CHECK-NEXT: --> ((0 smax %y) + %x) U: full-set S: full-set 33; CHECK-NEXT: Determining loop execution counts for: @f1 34; 35entry: 36 %c = icmp sge i32 %y, 0 37 br i1 %c, label %add, label %merge 38 39add: 40 %sum = add i32 %x, %y 41 br label %merge 42 43merge: 44 %v = phi i32 [ %sum, %add ], [ %x, %entry ] 45 ret i32 %v 46} 47 48define i32 @f2(i32 %x, i32 %y, ptr %ptr) { 49; CHECK-LABEL: 'f2' 50; CHECK-NEXT: Classifying expressions for: @f2 51; CHECK-NEXT: %lv = load i32, ptr %ptr, align 4 52; CHECK-NEXT: --> %lv U: full-set S: full-set 53; CHECK-NEXT: %v = phi i32 [ %lv, %add ], [ %x, %entry ] 54; CHECK-NEXT: --> %v U: full-set S: full-set 55; CHECK-NEXT: Determining loop execution counts for: @f2 56; 57entry: 58 %c = icmp sge i32 %y, 0 59 br i1 %c, label %add, label %merge 60 61add: 62 %lv = load i32, ptr %ptr 63 br label %merge 64 65merge: 66 %v = phi i32 [ %lv, %add ], [ %x, %entry ] 67 ret i32 %v 68} 69 70define i32 @f3(i32 %x, i32 %init, i32 %lim) { 71; CHECK-LABEL: 'f3' 72; CHECK-NEXT: Classifying expressions for: @f3 73; CHECK-NEXT: %iv = phi i32 [ %init, %entry ], [ %iv.inc, %merge ] 74; CHECK-NEXT: --> {%init,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 75; CHECK-NEXT: %iv.inc = add i32 %iv, 1 76; CHECK-NEXT: --> {(1 + %init),+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 77; CHECK-NEXT: %sum = add i32 %x, %iv 78; CHECK-NEXT: --> {(%x + %init),+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 79; CHECK-NEXT: %v = phi i32 [ %sum, %add ], [ %x, %loop ] 80; CHECK-NEXT: --> ((0 smax {%init,+,1}<%loop>) + %x) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 81; CHECK-NEXT: Determining loop execution counts for: @f3 82; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. 83; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. 84; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count. 85; 86entry: 87 br label %loop 88 89loop: 90 %iv = phi i32 [ %init, %entry ], [ %iv.inc, %merge ] 91 %iv.inc = add i32 %iv, 1 92 %c = icmp sge i32 %iv, 0 93 br i1 %c, label %add, label %merge 94 95add: 96 %sum = add i32 %x, %iv 97 br label %merge 98 99merge: 100 %v = phi i32 [ %sum, %add ], [ %x, %loop ] 101 %be.cond = icmp eq i32 %iv.inc, %lim 102 br i1 %be.cond, label %loop, label %leave 103 104leave: 105 ret i32 0 106} 107 108define i32 @f4(i32 %x, i32 %init, i32 %lim) { 109; CHECK-LABEL: 'f4' 110; CHECK-NEXT: Classifying expressions for: @f4 111; CHECK-NEXT: %iv = phi i32 [ %init, %add ], [ %iv.inc, %loop ] 112; CHECK-NEXT: --> {%init,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 113; CHECK-NEXT: %iv.inc = add i32 %iv, 1 114; CHECK-NEXT: --> {(1 + %init),+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 115; CHECK-NEXT: %sum = add i32 %x, %iv 116; CHECK-NEXT: --> {(%x + %init),+,1}<%loop> U: full-set S: full-set 117; CHECK-NEXT: %v = phi i32 [ %sum, %add.cont ], [ %x, %entry ] 118; CHECK-NEXT: --> %v U: full-set S: full-set 119; CHECK-NEXT: Determining loop execution counts for: @f4 120; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. 121; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. 122; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count. 123; 124entry: 125 %c = icmp sge i32 %init, 0 126 br i1 %c, label %add, label %merge 127 128add: 129 br label %loop 130 131loop: 132 %iv = phi i32 [ %init, %add ], [ %iv.inc, %loop ] 133 %iv.inc = add i32 %iv, 1 134 %be.cond = icmp eq i32 %iv.inc, %lim 135 br i1 %be.cond, label %loop, label %add.cont 136 137add.cont: 138 %sum = add i32 %x, %iv 139 br label %merge 140 141merge: 142 %v = phi i32 [ %sum, %add.cont ], [ %x, %entry ] 143 ret i32 %v 144} 145 146; It's okay to match "through" %init, as SCEV expressions don't preserve LCSSA. 147define i32 @f5(ptr %val) { 148; CHECK-LABEL: 'f5' 149; CHECK-NEXT: Classifying expressions for: @f5 150; CHECK-NEXT: %inc = load i32, ptr %val, align 4 151; CHECK-NEXT: --> %inc U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.end: Variant } 152; CHECK-NEXT: %init = phi i32 [ 0, %for.condt ], [ %inc, %for.end ] 153; CHECK-NEXT: --> %inc U: full-set S: full-set 154; CHECK-NEXT: Determining loop execution counts for: @f5 155; CHECK-NEXT: Loop %for.end: <multiple exits> backedge-taken count is i1 false 156; CHECK-NEXT: exit count for for.end: i1 false 157; CHECK-NEXT: exit count for for.condt: i1 false 158; CHECK-NEXT: Loop %for.end: constant max backedge-taken count is i1 false 159; CHECK-NEXT: Loop %for.end: symbolic max backedge-taken count is i1 false 160; CHECK-NEXT: symbolic max exit count for for.end: i1 false 161; CHECK-NEXT: symbolic max exit count for for.condt: i1 false 162; CHECK-NEXT: Loop %for.end: Trip multiple is 1 163; 164entry: 165 br label %for.end 166 167for.condt: 168 br i1 true, label %for.cond.0, label %for.end 169 170for.end: 171 %inc = load i32, ptr %val 172 br i1 false, label %for.condt, label %for.cond.0 173 174for.cond.0: 175 %init = phi i32 [ 0, %for.condt ], [ %inc, %for.end ] 176 ret i32 %init 177} 178 179; Do the right thing for unreachable code: 180define i32 @f6(i32 %x, i32 %y) { 181; CHECK-LABEL: 'f6' 182; CHECK-NEXT: Classifying expressions for: @f6 183; CHECK-NEXT: %sum = add i32 %x, %y 184; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set 185; CHECK-NEXT: %v0 = phi i32 [ %sum, %entry ], [ %v1, %unreachable ] 186; CHECK-NEXT: --> %v0 U: full-set S: full-set 187; CHECK-NEXT: %v1 = phi i32 [ %v0, %merge ], [ 0, %leave_0_cond ] 188; CHECK-NEXT: --> %v1 U: full-set S: full-set 189; CHECK-NEXT: Determining loop execution counts for: @f6 190; 191entry: 192 %c0 = icmp sgt i32 %y, 0 193 %sum = add i32 %x, %y 194 br i1 %c0, label %merge, label %leave_1 195 196merge: 197 %v0 = phi i32 [ %sum, %entry ], [ %v1, %unreachable ] 198 %c1 = icmp slt i32 %y, 0 199 br i1 %c1, label %leave_0, label %leave_0_cond 200 201leave_0_cond: 202 br label %leave_0 203 204leave_0: 205 %v1 = phi i32 [ %v0, %merge ], [ 0, %leave_0_cond ] 206 ret i32 0 207 208leave_1: 209 ret i32 0 210 211unreachable: 212 br label %merge 213} 214