1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py 2; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s 3 4declare i1 @cond() 5 6define i32 @test_simple_case(i32 %start, i32 %len) { 7; CHECK-LABEL: 'test_simple_case' 8; CHECK-NEXT: Classifying expressions for: @test_simple_case 9; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ] 10; CHECK-NEXT: --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 11; CHECK-NEXT: %iv.minus.1 = add i32 %iv, -1 12; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 13; CHECK-NEXT: %iv.next = add i32 %iv, -1 14; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 15; CHECK-NEXT: %loop_cond = call i1 @cond() 16; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 17; CHECK-NEXT: Determining loop execution counts for: @test_simple_case 18; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 19; CHECK-NEXT: exit count for loop: %start 20; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 21; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 22; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 23; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start 24; CHECK-NEXT: symbolic max exit count for loop: %start 25; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 26; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 27; 28entry: 29 br label %loop 30 31loop: 32 %iv = phi i32 [%start, %entry], [%iv.next, %backedge] 33 %zero_check = icmp ne i32 %iv, 0 34 br i1 %zero_check, label %range_check_block, label %failed_1 35 36range_check_block: 37 %iv.minus.1 = add i32 %iv, -1 38 %range_check = icmp ult i32 %iv.minus.1, %len 39 br i1 %range_check, label %backedge, label %failed_2 40 41backedge: 42 %iv.next = add i32 %iv, -1 43 %loop_cond = call i1 @cond() 44 br i1 %loop_cond, label %done, label %loop 45 46done: 47 ret i32 %iv 48 49failed_1: 50 ret i32 -1 51 52failed_2: 53 ret i32 -2 54} 55 56define i32 @test_litter_conditions(i32 %start, i32 %len) { 57; CHECK-LABEL: 'test_litter_conditions' 58; CHECK-NEXT: Classifying expressions for: @test_litter_conditions 59; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ] 60; CHECK-NEXT: --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 61; CHECK-NEXT: %fake_1 = call i1 @cond() 62; CHECK-NEXT: --> %fake_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 63; CHECK-NEXT: %and_1 = and i1 %zero_check, %fake_1 64; CHECK-NEXT: --> (%zero_check umin %fake_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 65; CHECK-NEXT: %iv.minus.1 = add i32 %iv, -1 66; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 67; CHECK-NEXT: %fake_2 = call i1 @cond() 68; CHECK-NEXT: --> %fake_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 69; CHECK-NEXT: %and_2 = and i1 %range_check, %fake_2 70; CHECK-NEXT: --> (%range_check umin %fake_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 71; CHECK-NEXT: %iv.next = add i32 %iv, -1 72; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 73; CHECK-NEXT: %loop_cond = call i1 @cond() 74; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 75; CHECK-NEXT: Determining loop execution counts for: @test_litter_conditions 76; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 77; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 78; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 79; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 80; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 81; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start 82; CHECK-NEXT: symbolic max exit count for loop: %start 83; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 84; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 85; 86entry: 87 br label %loop 88 89loop: 90 %iv = phi i32 [%start, %entry], [%iv.next, %backedge] 91 %zero_check = icmp ne i32 %iv, 0 92 %fake_1 = call i1 @cond() 93 %and_1 = and i1 %zero_check, %fake_1 94 br i1 %and_1, label %range_check_block, label %failed_1 95 96range_check_block: 97 %iv.minus.1 = add i32 %iv, -1 98 %range_check = icmp ult i32 %iv.minus.1, %len 99 %fake_2 = call i1 @cond() 100 %and_2 = and i1 %range_check, %fake_2 101 br i1 %and_2, label %backedge, label %failed_2 102 103backedge: 104 %iv.next = add i32 %iv, -1 105 %loop_cond = call i1 @cond() 106 br i1 %loop_cond, label %done, label %loop 107 108done: 109 ret i32 %iv 110 111failed_1: 112 ret i32 -1 113 114failed_2: 115 ret i32 -2 116} 117 118define i32 @test_litter_conditions_bad_context(i32 %start, i32 %len) { 119; CHECK-LABEL: 'test_litter_conditions_bad_context' 120; CHECK-NEXT: Classifying expressions for: @test_litter_conditions_bad_context 121; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ] 122; CHECK-NEXT: --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 123; CHECK-NEXT: %fake_1 = call i1 @cond() 124; CHECK-NEXT: --> %fake_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 125; CHECK-NEXT: %and_1 = and i1 %zero_check, %fake_1 126; CHECK-NEXT: --> (%zero_check umin %fake_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 127; CHECK-NEXT: %iv.minus.1 = add i32 %iv, -1 128; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 129; CHECK-NEXT: %fake_2 = call i1 @cond() 130; CHECK-NEXT: --> %fake_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 131; CHECK-NEXT: %and_2 = and i1 %range_check, %fake_2 132; CHECK-NEXT: --> (%range_check umin %fake_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 133; CHECK-NEXT: %iv.next = add i32 %iv, -1 134; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 135; CHECK-NEXT: %loop_cond = call i1 @cond() 136; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 137; CHECK-NEXT: Determining loop execution counts for: @test_litter_conditions_bad_context 138; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 139; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 140; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 141; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 142; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 143; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start 144; CHECK-NEXT: symbolic max exit count for loop: %start 145; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 146; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 147; 148entry: 149 br label %loop 150 151loop: 152 %iv = phi i32 [%start, %entry], [%iv.next, %backedge] 153 %zero_check = icmp ne i32 %iv, 0 154 %fake_1 = call i1 @cond() 155 %and_1 = and i1 %zero_check, %fake_1 156 %iv.minus.1 = add i32 %iv, -1 157 %range_check = icmp ult i32 %iv.minus.1, %len 158 %fake_2 = call i1 @cond() 159 %and_2 = and i1 %range_check, %fake_2 160 br i1 %and_1, label %range_check_block, label %failed_1 161 162range_check_block: 163 br i1 %and_2, label %backedge, label %failed_2 164 165backedge: 166 %iv.next = add i32 %iv, -1 167 %loop_cond = call i1 @cond() 168 br i1 %loop_cond, label %done, label %loop 169 170done: 171 ret i32 %iv 172 173failed_1: 174 ret i32 -1 175 176failed_2: 177 ret i32 -2 178} 179 180define i32 @test_and_conditions(i32 %start, i32 %len) { 181; CHECK-LABEL: 'test_and_conditions' 182; CHECK-NEXT: Classifying expressions for: @test_and_conditions 183; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ] 184; CHECK-NEXT: --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 185; CHECK-NEXT: %iv.minus.1 = add i32 %iv, -1 186; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 187; CHECK-NEXT: %both_checks = and i1 %zero_check, %range_check 188; CHECK-NEXT: --> (%range_check umin %zero_check) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 189; CHECK-NEXT: %iv.next = add i32 %iv, -1 190; CHECK-NEXT: --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 191; CHECK-NEXT: %loop_cond = call i1 @cond() 192; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 193; CHECK-NEXT: Determining loop execution counts for: @test_and_conditions 194; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 195; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 196; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 197; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 198; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start 199; CHECK-NEXT: symbolic max exit count for loop: %start 200; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 201; 202entry: 203 br label %loop 204 205loop: 206 %iv = phi i32 [%start, %entry], [%iv.next, %backedge] 207 %zero_check = icmp ne i32 %iv, 0 208 %iv.minus.1 = add i32 %iv, -1 209 %range_check = icmp ult i32 %iv.minus.1, %len 210 %both_checks = and i1 %zero_check, %range_check 211 br i1 %both_checks, label %backedge, label %failed 212 213backedge: 214 %iv.next = add i32 %iv, -1 215 %loop_cond = call i1 @cond() 216 br i1 %loop_cond, label %done, label %loop 217 218done: 219 ret i32 %iv 220 221failed: 222 ret i32 -3 223} 224 225define i32 @test_mixup_constant_symbolic(i32 %end, i32 %len) { 226; CHECK-LABEL: 'test_mixup_constant_symbolic' 227; CHECK-NEXT: Classifying expressions for: @test_mixup_constant_symbolic 228; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 229; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,1001) S: [0,1001) Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 230; CHECK-NEXT: %iv.next = add i32 %iv, 1 231; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,1002) S: [1,1002) Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 232; CHECK-NEXT: %loop_cond = call i1 @cond() 233; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 234; CHECK-NEXT: Determining loop execution counts for: @test_mixup_constant_symbolic 235; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 236; CHECK-NEXT: exit count for loop: %end 237; CHECK-NEXT: exit count for range_check_block: i32 1000 238; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 239; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 1000 240; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (1000 umin %end) 241; CHECK-NEXT: symbolic max exit count for loop: %end 242; CHECK-NEXT: symbolic max exit count for range_check_block: i32 1000 243; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 244; 245entry: 246 br label %loop 247 248loop: 249 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 250 %zero_check = icmp ne i32 %iv, %end 251 br i1 %zero_check, label %range_check_block, label %failed_1 252 253range_check_block: 254 %range_check = icmp ult i32 %iv, 1000 255 br i1 %range_check, label %backedge, label %failed_2 256 257backedge: 258 %iv.next = add i32 %iv, 1 259 %loop_cond = call i1 @cond() 260 br i1 %loop_cond, label %done, label %loop 261 262done: 263 ret i32 %iv 264 265failed_1: 266 ret i32 -1 267 268failed_2: 269 ret i32 -2 270} 271 272define i32 @test_mixup_constant_symbolic_merged(i32 %end, i32 %len) { 273; CHECK-LABEL: 'test_mixup_constant_symbolic_merged' 274; CHECK-NEXT: Classifying expressions for: @test_mixup_constant_symbolic_merged 275; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 276; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,1001) S: [0,1001) Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 277; CHECK-NEXT: %and = and i1 %zero_check, %range_check 278; CHECK-NEXT: --> (%range_check umin %zero_check) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 279; CHECK-NEXT: %iv.next = add i32 %iv, 1 280; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,1002) S: [1,1002) Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 281; CHECK-NEXT: %loop_cond = call i1 @cond() 282; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 283; CHECK-NEXT: Determining loop execution counts for: @test_mixup_constant_symbolic_merged 284; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 285; CHECK-NEXT: exit count for loop: (1000 umin %end) 286; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 287; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 1000 288; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (1000 umin %end) 289; CHECK-NEXT: symbolic max exit count for loop: (1000 umin %end) 290; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 291; 292entry: 293 br label %loop 294 295loop: 296 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 297 %zero_check = icmp ne i32 %iv, %end 298 %range_check = icmp ult i32 %iv, 1000 299 %and = and i1 %zero_check, %range_check 300 br i1 %and, label %backedge, label %failed_1 301 302backedge: 303 %iv.next = add i32 %iv, 1 304 %loop_cond = call i1 @cond() 305 br i1 %loop_cond, label %done, label %loop 306 307done: 308 ret i32 %iv 309 310failed_1: 311 ret i32 -1 312} 313 314define i32 @test_two_phis(i32 %start_1, i32 %start_2, i32 %len) { 315; CHECK-LABEL: 'test_two_phis' 316; CHECK-NEXT: Classifying expressions for: @test_two_phis 317; CHECK-NEXT: %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ] 318; CHECK-NEXT: --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 319; CHECK-NEXT: %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ] 320; CHECK-NEXT: --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 321; CHECK-NEXT: %scam_1 = call i1 @cond() 322; CHECK-NEXT: --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 323; CHECK-NEXT: %c1 = and i1 %zero_check_1, %scam_1 324; CHECK-NEXT: --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 325; CHECK-NEXT: %scam_2 = call i1 @cond() 326; CHECK-NEXT: --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 327; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 328; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 329; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 330; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 331; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 332; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 333; CHECK-NEXT: %iv_2.next = add i32 %iv_2, -1 334; CHECK-NEXT: --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 335; CHECK-NEXT: %loop_cond = call i1 @cond() 336; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 337; CHECK-NEXT: Determining loop execution counts for: @test_two_phis 338; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 339; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 340; CHECK-NEXT: exit count for zero_check_block: ***COULDNOTCOMPUTE*** 341; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 342; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 343; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 344; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2) 345; CHECK-NEXT: symbolic max exit count for loop: %start_1 346; CHECK-NEXT: symbolic max exit count for zero_check_block: %start_2 347; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 348; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 349; 350entry: 351 br label %loop 352 353loop: 354 %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge] 355 %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge] 356 %scam_1 = call i1 @cond() 357 %zero_check_1 = icmp ne i32 %iv_1, 0 358 %c1 = and i1 %zero_check_1, %scam_1 359 br i1 %c1, label %zero_check_block, label %failed_1 360 361zero_check_block: 362 %scam_2 = call i1 @cond() 363 %zero_check_2 = icmp ne i32 %iv_2, 0 364 %c2 = and i1 %zero_check_2, %scam_2 365 br i1 %c2, label %range_check_block, label %failed_1 366 367range_check_block: 368 %iv.minus.1 = add i32 %iv_1, -1 369 %range_check = icmp ult i32 %iv.minus.1, %len 370 br i1 %range_check, label %backedge, label %failed_2 371 372backedge: 373 %iv_1.next = add i32 %iv_1, -1 374 %iv_2.next = add i32 %iv_2, -1 375 %loop_cond = call i1 @cond() 376 br i1 %loop_cond, label %done, label %loop 377 378done: 379 ret i32 %iv_2 380 381failed_1: 382 ret i32 -1 383 384failed_2: 385 ret i32 -2 386} 387 388define i32 @test_two_phis_simple(i32 %start_1, i32 %start_2, i32 %len) { 389; CHECK-LABEL: 'test_two_phis_simple' 390; CHECK-NEXT: Classifying expressions for: @test_two_phis_simple 391; CHECK-NEXT: %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ] 392; CHECK-NEXT: --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: ((-1 * (%start_1 umin_seq %start_2)) + %start_1) LoopDispositions: { %loop: Computable } 393; CHECK-NEXT: %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ] 394; CHECK-NEXT: --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: ((-1 * (%start_1 umin_seq %start_2)) + %start_2) LoopDispositions: { %loop: Computable } 395; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 396; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * (%start_1 umin_seq %start_2)) + %start_1) LoopDispositions: { %loop: Computable } 397; CHECK-NEXT: %iv_2.next = add i32 %iv_2, -1 398; CHECK-NEXT: --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * (%start_1 umin_seq %start_2)) + %start_2) LoopDispositions: { %loop: Computable } 399; CHECK-NEXT: Determining loop execution counts for: @test_two_phis_simple 400; CHECK-NEXT: Loop %loop: <multiple exits> backedge-taken count is (%start_1 umin_seq %start_2) 401; CHECK-NEXT: exit count for loop: %start_1 402; CHECK-NEXT: exit count for backedge: %start_2 403; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 404; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2) 405; CHECK-NEXT: symbolic max exit count for loop: %start_1 406; CHECK-NEXT: symbolic max exit count for backedge: %start_2 407; CHECK-NEXT: Loop %loop: Trip multiple is 1 408; 409entry: 410 br label %loop 411 412loop: 413 %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge] 414 %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge] 415 %zero_check_1 = icmp ne i32 %iv_1, 0 416 br i1 %zero_check_1, label %backedge, label %exit 417 418backedge: 419 %zero_check_2 = icmp ne i32 %iv_2, 0 420 %iv_1.next = add i32 %iv_1, -1 421 %iv_2.next = add i32 %iv_2, -1 422 br i1 %zero_check_2, label %loop, label %exit 423 424exit: 425 ret i32 0 426} 427 428define i32 @test_two_phis_arithmetic_and(i32 %start_1, i32 %start_2, i32 %len) { 429; CHECK-LABEL: 'test_two_phis_arithmetic_and' 430; CHECK-NEXT: Classifying expressions for: @test_two_phis_arithmetic_and 431; CHECK-NEXT: %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ] 432; CHECK-NEXT: --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 433; CHECK-NEXT: %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ] 434; CHECK-NEXT: --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 435; CHECK-NEXT: %scam_1 = call i1 @cond() 436; CHECK-NEXT: --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 437; CHECK-NEXT: %c1 = and i1 %zero_check_1, %scam_1 438; CHECK-NEXT: --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 439; CHECK-NEXT: %scam_2 = call i1 @cond() 440; CHECK-NEXT: --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 441; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 442; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 443; CHECK-NEXT: %merged_cond = and i1 %c1, %c2 444; CHECK-NEXT: --> (%zero_check_1 umin %zero_check_2 umin %scam_1 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 445; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 446; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 447; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 448; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 449; CHECK-NEXT: %iv_2.next = add i32 %iv_2, -1 450; CHECK-NEXT: --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 451; CHECK-NEXT: %loop_cond = call i1 @cond() 452; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 453; CHECK-NEXT: Determining loop execution counts for: @test_two_phis_arithmetic_and 454; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 455; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 456; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 457; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 458; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 459; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%start_1 umin %start_2) 460; CHECK-NEXT: symbolic max exit count for loop: (%start_1 umin %start_2) 461; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 462; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 463; 464entry: 465 br label %loop 466 467loop: 468 %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge] 469 %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge] 470 %scam_1 = call i1 @cond() 471 %zero_check_1 = icmp ne i32 %iv_1, 0 472 %c1 = and i1 %zero_check_1, %scam_1 473 %scam_2 = call i1 @cond() 474 %zero_check_2 = icmp ne i32 %iv_2, 0 475 %c2 = and i1 %zero_check_2, %scam_2 476 %merged_cond = and i1 %c1, %c2 477 br i1 %merged_cond, label %range_check_block, label %failed_1 478 479range_check_block: 480 %iv.minus.1 = add i32 %iv_1, -1 481 %range_check = icmp ult i32 %iv.minus.1, %len 482 br i1 %range_check, label %backedge, label %failed_2 483 484backedge: 485 %iv_1.next = add i32 %iv_1, -1 486 %iv_2.next = add i32 %iv_2, -1 487 %loop_cond = call i1 @cond() 488 br i1 %loop_cond, label %done, label %loop 489 490done: 491 ret i32 %iv_2 492 493failed_1: 494 ret i32 -1 495 496failed_2: 497 ret i32 -2 498} 499 500; TODO: Symbolic max can be start1 umax_seq start2 501define i32 @test_two_phis_logical_or(i32 %start_1, i32 %start_2, i32 %len) { 502; CHECK-LABEL: 'test_two_phis_logical_or' 503; CHECK-NEXT: Classifying expressions for: @test_two_phis_logical_or 504; CHECK-NEXT: %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ] 505; CHECK-NEXT: --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 506; CHECK-NEXT: %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ] 507; CHECK-NEXT: --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 508; CHECK-NEXT: %scam_1 = call i1 @cond() 509; CHECK-NEXT: --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 510; CHECK-NEXT: %c1 = and i1 %zero_check_1, %scam_1 511; CHECK-NEXT: --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 512; CHECK-NEXT: %scam_2 = call i1 @cond() 513; CHECK-NEXT: --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 514; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 515; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 516; CHECK-NEXT: %merged_cond = select i1 %c1, i1 true, i1 %c2 517; CHECK-NEXT: --> (true + ((true + (%zero_check_1 umin %scam_1)) umin_seq (true + (%zero_check_2 umin %scam_2)))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 518; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 519; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 520; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 521; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 522; CHECK-NEXT: %iv_2.next = add i32 %iv_2, -1 523; CHECK-NEXT: --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 524; CHECK-NEXT: %loop_cond = call i1 @cond() 525; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 526; CHECK-NEXT: Determining loop execution counts for: @test_two_phis_logical_or 527; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 528; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 529; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 530; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 531; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. 532; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count. 533; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE*** 534; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 535; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 536; 537entry: 538 br label %loop 539 540loop: 541 %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge] 542 %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge] 543 %scam_1 = call i1 @cond() 544 %zero_check_1 = icmp ne i32 %iv_1, 0 545 %c1 = and i1 %zero_check_1, %scam_1 546 %scam_2 = call i1 @cond() 547 %zero_check_2 = icmp ne i32 %iv_2, 0 548 %c2 = and i1 %zero_check_2, %scam_2 549 %merged_cond = select i1 %c1, i1 true, i1 %c2 550 br i1 %merged_cond, label %range_check_block, label %failed_1 551 552range_check_block: 553 %iv.minus.1 = add i32 %iv_1, -1 554 %range_check = icmp ult i32 %iv.minus.1, %len 555 br i1 %range_check, label %backedge, label %failed_2 556 557backedge: 558 %iv_1.next = add i32 %iv_1, -1 559 %iv_2.next = add i32 %iv_2, -1 560 %loop_cond = call i1 @cond() 561 br i1 %loop_cond, label %done, label %loop 562 563done: 564 ret i32 %iv_2 565 566failed_1: 567 ret i32 -1 568 569failed_2: 570 ret i32 -2 571} 572 573define i32 @test_two_phis_logical_and(i32 %start_1, i32 %start_2, i32 %len) { 574; CHECK-LABEL: 'test_two_phis_logical_and' 575; CHECK-NEXT: Classifying expressions for: @test_two_phis_logical_and 576; CHECK-NEXT: %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ] 577; CHECK-NEXT: --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 578; CHECK-NEXT: %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ] 579; CHECK-NEXT: --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 580; CHECK-NEXT: %scam_1 = call i1 @cond() 581; CHECK-NEXT: --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 582; CHECK-NEXT: %c1 = and i1 %zero_check_1, %scam_1 583; CHECK-NEXT: --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 584; CHECK-NEXT: %scam_2 = call i1 @cond() 585; CHECK-NEXT: --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 586; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 587; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 588; CHECK-NEXT: %merged_cond = select i1 %c1, i1 %c2, i1 false 589; CHECK-NEXT: --> ((%zero_check_1 umin %scam_1) umin_seq (%zero_check_2 umin %scam_2)) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 590; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 591; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 592; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 593; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 594; CHECK-NEXT: %iv_2.next = add i32 %iv_2, -1 595; CHECK-NEXT: --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable } 596; CHECK-NEXT: %loop_cond = call i1 @cond() 597; CHECK-NEXT: --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant } 598; CHECK-NEXT: Determining loop execution counts for: @test_two_phis_logical_and 599; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count. 600; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** 601; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** 602; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** 603; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 604; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2) 605; CHECK-NEXT: symbolic max exit count for loop: (%start_1 umin_seq %start_2) 606; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** 607; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** 608; 609entry: 610 br label %loop 611 612loop: 613 %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge] 614 %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge] 615 %scam_1 = call i1 @cond() 616 %zero_check_1 = icmp ne i32 %iv_1, 0 617 %c1 = and i1 %zero_check_1, %scam_1 618 %scam_2 = call i1 @cond() 619 %zero_check_2 = icmp ne i32 %iv_2, 0 620 %c2 = and i1 %zero_check_2, %scam_2 621 %merged_cond = select i1 %c1, i1 %c2, i1 false 622 br i1 %merged_cond, label %range_check_block, label %failed_1 623 624range_check_block: 625 %iv.minus.1 = add i32 %iv_1, -1 626 %range_check = icmp ult i32 %iv.minus.1, %len 627 br i1 %range_check, label %backedge, label %failed_2 628 629backedge: 630 %iv_1.next = add i32 %iv_1, -1 631 %iv_2.next = add i32 %iv_2, -1 632 %loop_cond = call i1 @cond() 633 br i1 %loop_cond, label %done, label %loop 634 635done: 636 ret i32 %iv_2 637 638failed_1: 639 ret i32 -1 640 641failed_2: 642 ret i32 -2 643} 644