1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=indvars -S | FileCheck %s 3 4declare i1 @cond() 5declare i32 @llvm.smax.i32(i32, i32) 6 7; FIXME: In all tests in this file, signed_cond is equivalent to unsigned_cond, and therefore 8; one of the checks in the inner loop can be removed. The key to proving it is to prove that 9; %iv starts from something that is non-negative and only goes up. The positivity of its start 10; follows from the fact that %outer.iv also starts from somethign non-negative and only goes 11; up or remains same between iterations. 12define i32 @test_01(i32 %a, i32 %b) { 13; CHECK-LABEL: @test_01( 14; CHECK-NEXT: entry: 15; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0 16; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]] 17; CHECK: outer.preheader: 18; CHECK-NEXT: br label [[OUTER:%.*]] 19; CHECK: outer: 20; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ] 21; CHECK-NEXT: br label [[INNER:%.*]] 22; CHECK: inner: 23; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 24; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 25; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 26; CHECK: inner.1: 27; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 28; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 29; CHECK: inner.backedge: 30; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 31; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 32; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 33; CHECK: outer.backedge: 34; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 35; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 36; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 37; CHECK: failure: 38; CHECK-NEXT: unreachable 39; CHECK: side.exit: 40; CHECK-NEXT: ret i32 0 41; CHECK: exit: 42; CHECK-NEXT: ret i32 1 43; 44entry: 45 %b_is_non_negative = icmp sge i32 %b, 0 46 br i1 %b_is_non_negative, label %outer, label %failure 47 48outer: 49 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 50 br label %inner 51 52 53inner: 54 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 55 %signed_cond = icmp slt i32 %iv, %b 56 br i1 %signed_cond, label %inner.1, label %side.exit 57 58inner.1: 59 %unsigned_cond = icmp ult i32 %iv, %b 60 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 61 62inner.backedge: 63 %iv.next = add nuw nsw i32 %iv, 1 64 %inner.loop.cond = call i1 @cond() 65 br i1 %inner.loop.cond, label %inner, label %outer.backedge 66 67outer.backedge: 68 %outer.loop.cond = call i1 @cond() 69 br i1 %outer.loop.cond, label %outer, label %exit 70 71failure: 72 unreachable 73 74side.exit: 75 ret i32 0 76 77exit: 78 ret i32 1 79} 80 81; FIXME: iv <u b, b >=s 0 --> iv <s b. We should be able to remove the 2nd check. 82define i32 @test_01a(i32 %a, i32 %b) { 83; CHECK-LABEL: @test_01a( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0 86; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]] 87; CHECK: outer.preheader: 88; CHECK-NEXT: br label [[OUTER:%.*]] 89; CHECK: outer: 90; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ] 91; CHECK-NEXT: br label [[INNER:%.*]] 92; CHECK: inner: 93; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 94; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 95; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 96; CHECK: inner.1: 97; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 98; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 99; CHECK: inner.backedge: 100; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 101; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 102; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 103; CHECK: outer.backedge: 104; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 105; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 106; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 107; CHECK: failure: 108; CHECK-NEXT: unreachable 109; CHECK: side.exit: 110; CHECK-NEXT: ret i32 0 111; CHECK: exit: 112; CHECK-NEXT: ret i32 1 113; 114entry: 115 %b_is_non_negative = icmp sge i32 %b, 0 116 br i1 %b_is_non_negative, label %outer, label %failure 117 118outer: 119 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 120 br label %inner 121 122 123inner: 124 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 125 %signed_cond = icmp ult i32 %iv, %b 126 br i1 %signed_cond, label %inner.1, label %side.exit 127 128inner.1: 129 %unsigned_cond = icmp slt i32 %iv, %b 130 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 131 132inner.backedge: 133 %iv.next = add nuw nsw i32 %iv, 1 134 %inner.loop.cond = call i1 @cond() 135 br i1 %inner.loop.cond, label %inner, label %outer.backedge 136 137outer.backedge: 138 %outer.loop.cond = call i1 @cond() 139 br i1 %outer.loop.cond, label %outer, label %exit 140 141failure: 142 unreachable 143 144side.exit: 145 ret i32 0 146 147exit: 148 ret i32 1 149} 150 151define i32 @test_02(i32 %a, i32 %b) { 152; CHECK-LABEL: @test_02( 153; CHECK-NEXT: entry: 154; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0 155; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]] 156; CHECK: outer.preheader: 157; CHECK-NEXT: br label [[OUTER:%.*]] 158; CHECK: outer: 159; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ] 160; CHECK-NEXT: br label [[INNER:%.*]] 161; CHECK: inner: 162; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 163; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 164; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 165; CHECK: inner.1: 166; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 167; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 168; CHECK: inner.backedge: 169; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 170; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 171; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 172; CHECK: outer.backedge: 173; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 174; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 175; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 176; CHECK: failure: 177; CHECK-NEXT: unreachable 178; CHECK: side.exit: 179; CHECK-NEXT: ret i32 0 180; CHECK: exit: 181; CHECK-NEXT: ret i32 1 182; 183entry: 184 %b_is_non_negative = icmp sge i32 %b, 0 185 br i1 %b_is_non_negative, label %outer, label %failure 186 187outer: 188 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge] 189 br label %inner 190 191 192inner: 193 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 194 %signed_cond = icmp slt i32 %iv, %b 195 br i1 %signed_cond, label %inner.1, label %side.exit 196 197inner.1: 198 %unsigned_cond = icmp ult i32 %iv, %b 199 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 200 201inner.backedge: 202 %iv.next = add nuw nsw i32 %iv, 1 203 %inner.loop.cond = call i1 @cond() 204 br i1 %inner.loop.cond, label %inner, label %outer.backedge 205 206outer.backedge: 207 %outer.merge = phi i32 [%iv.next, %inner.backedge] 208 %outer.loop.cond = call i1 @cond() 209 br i1 %outer.loop.cond, label %outer, label %exit 210 211failure: 212 unreachable 213 214side.exit: 215 ret i32 0 216 217exit: 218 ret i32 1 219} 220 221define i32 @test_03(i32 %a, i32 %b) { 222; CHECK-LABEL: @test_03( 223; CHECK-NEXT: entry: 224; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0 225; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]] 226; CHECK: outer.preheader: 227; CHECK-NEXT: br label [[OUTER:%.*]] 228; CHECK: outer: 229; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ] 230; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond() 231; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]] 232; CHECK: inner.preheader: 233; CHECK-NEXT: br label [[INNER:%.*]] 234; CHECK: no_inner: 235; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond() 236; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 237; CHECK: inner: 238; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ] 239; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 240; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 241; CHECK: inner.1: 242; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 243; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 244; CHECK: inner.backedge: 245; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 246; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 247; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]] 248; CHECK: outer.backedge.loopexit: 249; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 250; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 251; CHECK: outer.backedge: 252; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[OUTER_IV]], [[NO_INNER]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ] 253; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 254; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 255; CHECK: failure: 256; CHECK-NEXT: unreachable 257; CHECK: side.exit: 258; CHECK-NEXT: ret i32 0 259; CHECK: exit: 260; CHECK-NEXT: ret i32 1 261; 262entry: 263 %b_is_non_negative = icmp sge i32 %b, 0 264 br i1 %b_is_non_negative, label %outer, label %failure 265 266outer: 267 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge] 268 %outer_cond_1 = call i1 @cond() 269 br i1 %outer_cond_1, label %inner, label %no_inner 270 271no_inner: 272 %outer_cond_2 = call i1 @cond() 273 br label %outer.backedge 274 275inner: 276 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 277 %signed_cond = icmp slt i32 %iv, %b 278 br i1 %signed_cond, label %inner.1, label %side.exit 279 280inner.1: 281 %unsigned_cond = icmp ult i32 %iv, %b 282 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 283 284inner.backedge: 285 %iv.next = add nuw nsw i32 %iv, 1 286 %inner.loop.cond = call i1 @cond() 287 br i1 %inner.loop.cond, label %inner, label %outer.backedge 288 289outer.backedge: 290 %outer.merge = phi i32 [%outer.iv, %no_inner], [%iv.next, %inner.backedge] 291 %outer.loop.cond = call i1 @cond() 292 br i1 %outer.loop.cond, label %outer, label %exit 293 294failure: 295 unreachable 296 297side.exit: 298 ret i32 0 299 300exit: 301 ret i32 1 302} 303 304define i32 @test_04(i32 %a, i32 %b) { 305; CHECK-LABEL: @test_04( 306; CHECK-NEXT: entry: 307; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0 308; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]] 309; CHECK: outer.preheader: 310; CHECK-NEXT: br label [[OUTER:%.*]] 311; CHECK: outer: 312; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ] 313; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond() 314; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]] 315; CHECK: inner.preheader: 316; CHECK-NEXT: br label [[INNER:%.*]] 317; CHECK: no_inner: 318; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond() 319; CHECK-NEXT: br i1 [[OUTER_COND_2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 320; CHECK: if.true: 321; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 [[OUTER_IV]]) 322; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 323; CHECK: if.false: 324; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 325; CHECK: inner: 326; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ] 327; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 328; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 329; CHECK: inner.1: 330; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 331; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 332; CHECK: inner.backedge: 333; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 334; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 335; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]] 336; CHECK: outer.backedge.loopexit: 337; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 338; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 339; CHECK: outer.backedge: 340; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[SMAX]], [[IF_TRUE]] ], [ [[OUTER_IV]], [[IF_FALSE]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ] 341; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 342; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 343; CHECK: failure: 344; CHECK-NEXT: unreachable 345; CHECK: side.exit: 346; CHECK-NEXT: ret i32 0 347; CHECK: exit: 348; CHECK-NEXT: ret i32 1 349; 350entry: 351 %b_is_non_negative = icmp sge i32 %b, 0 352 br i1 %b_is_non_negative, label %outer, label %failure 353 354outer: 355 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge] 356 %outer_cond_1 = call i1 @cond() 357 br i1 %outer_cond_1, label %inner, label %no_inner 358 359no_inner: 360 %outer_cond_2 = call i1 @cond() 361 br i1 %outer_cond_2, label %if.true, label %if.false 362 363if.true: 364 %smax = call i32 @llvm.smax.i32(i32 %a, i32 %outer.iv) 365 br label %outer.backedge 366 367if.false: 368 br label %outer.backedge 369 370inner: 371 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 372 %signed_cond = icmp slt i32 %iv, %b 373 br i1 %signed_cond, label %inner.1, label %side.exit 374 375inner.1: 376 %unsigned_cond = icmp ult i32 %iv, %b 377 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 378 379inner.backedge: 380 %iv.next = add nuw nsw i32 %iv, 1 381 %inner.loop.cond = call i1 @cond() 382 br i1 %inner.loop.cond, label %inner, label %outer.backedge 383 384outer.backedge: 385 %outer.merge = phi i32 [%smax, %if.true], [%outer.iv, %if.false], [%iv.next, %inner.backedge] 386 %outer.loop.cond = call i1 @cond() 387 br i1 %outer.loop.cond, label %outer, label %exit 388 389failure: 390 unreachable 391 392side.exit: 393 ret i32 0 394 395exit: 396 ret i32 1 397} 398 399; Same as test_01, but non-negativity of %b is known without context. 400; FIXME: We can remove 2nd check in loop. 401define i32 @test_05(i32 %a, ptr %bp) { 402; CHECK-LABEL: @test_05( 403; CHECK-NEXT: entry: 404; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0:![0-9]+]] 405; CHECK-NEXT: br label [[OUTER:%.*]] 406; CHECK: outer: 407; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 408; CHECK-NEXT: br label [[INNER:%.*]] 409; CHECK: inner: 410; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 411; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 412; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 413; CHECK: inner.1: 414; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] 415; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 416; CHECK: inner.backedge: 417; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 418; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 419; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 420; CHECK: outer.backedge: 421; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 422; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 423; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 424; CHECK: side.exit: 425; CHECK-NEXT: ret i32 0 426; CHECK: exit: 427; CHECK-NEXT: ret i32 1 428; 429entry: 430 %b = load i32, ptr %bp, !range !0 431 br label %outer 432 433outer: 434 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 435 br label %inner 436 437 438inner: 439 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 440 %signed_cond = icmp slt i32 %iv, %b 441 br i1 %signed_cond, label %inner.1, label %side.exit 442 443inner.1: 444 %unsigned_cond = icmp ult i32 %iv, %b 445 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 446 447inner.backedge: 448 %iv.next = add nuw nsw i32 %iv, 1 449 %inner.loop.cond = call i1 @cond() 450 br i1 %inner.loop.cond, label %inner, label %outer.backedge 451 452outer.backedge: 453 %outer.loop.cond = call i1 @cond() 454 br i1 %outer.loop.cond, label %outer, label %exit 455 456side.exit: 457 ret i32 0 458 459exit: 460 ret i32 1 461} 462 463 464; Same as test_01a, but non-negativity of %b is known without context. 465define i32 @test_05a(i32 %a, ptr %bp) { 466; CHECK-LABEL: @test_05a( 467; CHECK-NEXT: entry: 468; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 469; CHECK-NEXT: br label [[OUTER:%.*]] 470; CHECK: outer: 471; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 472; CHECK-NEXT: br label [[INNER:%.*]] 473; CHECK: inner: 474; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 475; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 476; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 477; CHECK: inner.1: 478; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 479; CHECK: inner.backedge: 480; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 481; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 482; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 483; CHECK: outer.backedge: 484; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 485; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 486; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 487; CHECK: side.exit: 488; CHECK-NEXT: ret i32 0 489; CHECK: exit: 490; CHECK-NEXT: ret i32 1 491; 492entry: 493 %b = load i32, ptr %bp, !range !0 494 br label %outer 495 496outer: 497 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 498 br label %inner 499 500 501inner: 502 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 503 %unsigned_cond = icmp ult i32 %iv, %b 504 br i1 %unsigned_cond, label %inner.1, label %side.exit 505 506inner.1: 507 %signed_cond = icmp slt i32 %iv, %b 508 br i1 %signed_cond, label %inner.backedge, label %side.exit 509 510inner.backedge: 511 %iv.next = add nuw nsw i32 %iv, 1 512 %inner.loop.cond = call i1 @cond() 513 br i1 %inner.loop.cond, label %inner, label %outer.backedge 514 515outer.backedge: 516 %outer.loop.cond = call i1 @cond() 517 br i1 %outer.loop.cond, label %outer, label %exit 518 519side.exit: 520 ret i32 0 521 522exit: 523 ret i32 1 524} 525 526; Similar to test_05a, but inverted 2nd condition. 527define i32 @test_05b(i32 %a, ptr %bp) { 528; CHECK-LABEL: @test_05b( 529; CHECK-NEXT: entry: 530; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 531; CHECK-NEXT: br label [[OUTER:%.*]] 532; CHECK: outer: 533; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 534; CHECK-NEXT: br label [[INNER:%.*]] 535; CHECK: inner: 536; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 537; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] 538; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 539; CHECK: inner.1: 540; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 541; CHECK: inner.backedge: 542; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 543; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 544; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 545; CHECK: outer.backedge: 546; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 547; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 548; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 549; CHECK: side.exit: 550; CHECK-NEXT: ret i32 0 551; CHECK: exit: 552; CHECK-NEXT: ret i32 1 553; 554entry: 555 %b = load i32, ptr %bp, !range !0 556 br label %outer 557 558outer: 559 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 560 br label %inner 561 562 563inner: 564 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 565 %unsigned_cond = icmp ult i32 %iv, %b 566 br i1 %unsigned_cond, label %inner.1, label %side.exit 567 568inner.1: 569 %signed_cond = icmp sgt i32 %b, %iv 570 br i1 %signed_cond, label %inner.backedge, label %side.exit 571 572inner.backedge: 573 %iv.next = add nuw nsw i32 %iv, 1 574 %inner.loop.cond = call i1 @cond() 575 br i1 %inner.loop.cond, label %inner, label %outer.backedge 576 577outer.backedge: 578 %outer.loop.cond = call i1 @cond() 579 br i1 %outer.loop.cond, label %outer, label %exit 580 581side.exit: 582 ret i32 0 583 584exit: 585 ret i32 1 586} 587 588; We should prove implication: iv <s b, b <s 0 => iv <u b. 589define i32 @test_05c(i32 %a, ptr %bp) { 590; CHECK-LABEL: @test_05c( 591; CHECK-NEXT: entry: 592; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1:![0-9]+]] 593; CHECK-NEXT: br label [[OUTER:%.*]] 594; CHECK: outer: 595; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 596; CHECK-NEXT: br label [[INNER:%.*]] 597; CHECK: inner: 598; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 599; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 600; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 601; CHECK: inner.1: 602; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 603; CHECK: inner.backedge: 604; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 605; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 606; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 607; CHECK: outer.backedge: 608; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 609; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 610; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 611; CHECK: side.exit: 612; CHECK-NEXT: ret i32 0 613; CHECK: exit: 614; CHECK-NEXT: ret i32 1 615; 616entry: 617 %b = load i32, ptr %bp, !range !1 618 br label %outer 619 620outer: 621 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 622 br label %inner 623 624 625inner: 626 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 627 %signed_cond = icmp slt i32 %iv, %b 628 br i1 %signed_cond, label %inner.1, label %side.exit 629 630inner.1: 631 %unsigned_cond = icmp ult i32 %iv, %b 632 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 633 634inner.backedge: 635 %iv.next = add nuw nsw i32 %iv, 1 636 %inner.loop.cond = call i1 @cond() 637 br i1 %inner.loop.cond, label %inner, label %outer.backedge 638 639outer.backedge: 640 %outer.loop.cond = call i1 @cond() 641 br i1 %outer.loop.cond, label %outer, label %exit 642 643side.exit: 644 ret i32 0 645 646exit: 647 ret i32 1 648} 649 650; Same as test_05c, but 2nd condition reversed. 651define i32 @test_05d(i32 %a, ptr %bp) { 652; CHECK-LABEL: @test_05d( 653; CHECK-NEXT: entry: 654; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]] 655; CHECK-NEXT: br label [[OUTER:%.*]] 656; CHECK: outer: 657; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 658; CHECK-NEXT: br label [[INNER:%.*]] 659; CHECK: inner: 660; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 661; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 662; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 663; CHECK: inner.1: 664; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 665; CHECK: inner.backedge: 666; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 667; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 668; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 669; CHECK: outer.backedge: 670; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 671; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 672; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 673; CHECK: side.exit: 674; CHECK-NEXT: ret i32 0 675; CHECK: exit: 676; CHECK-NEXT: ret i32 1 677; 678entry: 679 %b = load i32, ptr %bp, !range !1 680 br label %outer 681 682outer: 683 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 684 br label %inner 685 686 687inner: 688 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 689 %signed_cond = icmp slt i32 %iv, %b 690 br i1 %signed_cond, label %inner.1, label %side.exit 691 692inner.1: 693 %unsigned_cond = icmp ugt i32 %b, %iv 694 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 695 696inner.backedge: 697 %iv.next = add nuw nsw i32 %iv, 1 698 %inner.loop.cond = call i1 @cond() 699 br i1 %inner.loop.cond, label %inner, label %outer.backedge 700 701outer.backedge: 702 %outer.loop.cond = call i1 @cond() 703 br i1 %outer.loop.cond, label %outer, label %exit 704 705side.exit: 706 ret i32 0 707 708exit: 709 ret i32 1 710} 711 712 713; Same as test_05a, but 1st condition inverted. 714define i32 @test_05e(i32 %a, ptr %bp) { 715; CHECK-LABEL: @test_05e( 716; CHECK-NEXT: entry: 717; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 718; CHECK-NEXT: br label [[OUTER:%.*]] 719; CHECK: outer: 720; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 721; CHECK-NEXT: br label [[INNER:%.*]] 722; CHECK: inner: 723; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 724; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ugt i32 [[B]], [[IV]] 725; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 726; CHECK: inner.1: 727; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 728; CHECK: inner.backedge: 729; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 730; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 731; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 732; CHECK: outer.backedge: 733; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 734; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 735; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 736; CHECK: side.exit: 737; CHECK-NEXT: ret i32 0 738; CHECK: exit: 739; CHECK-NEXT: ret i32 1 740; 741entry: 742 %b = load i32, ptr %bp, !range !0 743 br label %outer 744 745outer: 746 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 747 br label %inner 748 749 750inner: 751 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 752 %unsigned_cond = icmp ugt i32 %b, %iv 753 br i1 %unsigned_cond, label %inner.1, label %side.exit 754 755inner.1: 756 %signed_cond = icmp slt i32 %iv, %b 757 br i1 %signed_cond, label %inner.backedge, label %side.exit 758 759inner.backedge: 760 %iv.next = add nuw nsw i32 %iv, 1 761 %inner.loop.cond = call i1 @cond() 762 br i1 %inner.loop.cond, label %inner, label %outer.backedge 763 764outer.backedge: 765 %outer.loop.cond = call i1 @cond() 766 br i1 %outer.loop.cond, label %outer, label %exit 767 768side.exit: 769 ret i32 0 770 771exit: 772 ret i32 1 773} 774 775; Same as test_05b, but 1st condition inverted. 776define i32 @test_05f(i32 %a, ptr %bp) { 777; CHECK-LABEL: @test_05f( 778; CHECK-NEXT: entry: 779; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 780; CHECK-NEXT: br label [[OUTER:%.*]] 781; CHECK: outer: 782; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 783; CHECK-NEXT: br label [[INNER:%.*]] 784; CHECK: inner: 785; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 786; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ugt i32 [[B]], [[IV]] 787; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 788; CHECK: inner.1: 789; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 790; CHECK: inner.backedge: 791; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 792; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 793; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 794; CHECK: outer.backedge: 795; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 796; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 797; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 798; CHECK: side.exit: 799; CHECK-NEXT: ret i32 0 800; CHECK: exit: 801; CHECK-NEXT: ret i32 1 802; 803entry: 804 %b = load i32, ptr %bp, !range !0 805 br label %outer 806 807outer: 808 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 809 br label %inner 810 811 812inner: 813 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 814 %unsigned_cond = icmp ugt i32 %b, %iv 815 br i1 %unsigned_cond, label %inner.1, label %side.exit 816 817inner.1: 818 %signed_cond = icmp sgt i32 %b, %iv 819 br i1 %signed_cond, label %inner.backedge, label %side.exit 820 821inner.backedge: 822 %iv.next = add nuw nsw i32 %iv, 1 823 %inner.loop.cond = call i1 @cond() 824 br i1 %inner.loop.cond, label %inner, label %outer.backedge 825 826outer.backedge: 827 %outer.loop.cond = call i1 @cond() 828 br i1 %outer.loop.cond, label %outer, label %exit 829 830side.exit: 831 ret i32 0 832 833exit: 834 ret i32 1 835} 836 837; Same as test_05c, but 1st condition inverted. 838define i32 @test_05g(i32 %a, ptr %bp) { 839; CHECK-LABEL: @test_05g( 840; CHECK-NEXT: entry: 841; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]] 842; CHECK-NEXT: br label [[OUTER:%.*]] 843; CHECK: outer: 844; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 845; CHECK-NEXT: br label [[INNER:%.*]] 846; CHECK: inner: 847; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 848; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp sgt i32 [[B]], [[IV]] 849; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 850; CHECK: inner.1: 851; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 852; CHECK: inner.backedge: 853; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 854; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 855; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 856; CHECK: outer.backedge: 857; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 858; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 859; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 860; CHECK: side.exit: 861; CHECK-NEXT: ret i32 0 862; CHECK: exit: 863; CHECK-NEXT: ret i32 1 864; 865entry: 866 %b = load i32, ptr %bp, !range !1 867 br label %outer 868 869outer: 870 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 871 br label %inner 872 873 874inner: 875 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 876 %signed_cond = icmp sgt i32 %b, %iv 877 br i1 %signed_cond, label %inner.1, label %side.exit 878 879inner.1: 880 %unsigned_cond = icmp ult i32 %iv, %b 881 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 882 883inner.backedge: 884 %iv.next = add nuw nsw i32 %iv, 1 885 %inner.loop.cond = call i1 @cond() 886 br i1 %inner.loop.cond, label %inner, label %outer.backedge 887 888outer.backedge: 889 %outer.loop.cond = call i1 @cond() 890 br i1 %outer.loop.cond, label %outer, label %exit 891 892side.exit: 893 ret i32 0 894 895exit: 896 ret i32 1 897} 898 899; Same as test_05d, but 1st condition inverted. 900define i32 @test_05h(i32 %a, ptr %bp) { 901; CHECK-LABEL: @test_05h( 902; CHECK-NEXT: entry: 903; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]] 904; CHECK-NEXT: br label [[OUTER:%.*]] 905; CHECK: outer: 906; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ] 907; CHECK-NEXT: br label [[INNER:%.*]] 908; CHECK: inner: 909; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 910; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp sgt i32 [[B]], [[IV]] 911; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 912; CHECK: inner.1: 913; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 914; CHECK: inner.backedge: 915; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 916; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 917; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 918; CHECK: outer.backedge: 919; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 920; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 921; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 922; CHECK: side.exit: 923; CHECK-NEXT: ret i32 0 924; CHECK: exit: 925; CHECK-NEXT: ret i32 1 926; 927entry: 928 %b = load i32, ptr %bp, !range !1 929 br label %outer 930 931outer: 932 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge] 933 br label %inner 934 935 936inner: 937 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 938 %signed_cond = icmp sgt i32 %b, %iv 939 br i1 %signed_cond, label %inner.1, label %side.exit 940 941inner.1: 942 %unsigned_cond = icmp ugt i32 %b, %iv 943 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 944 945inner.backedge: 946 %iv.next = add nuw nsw i32 %iv, 1 947 %inner.loop.cond = call i1 @cond() 948 br i1 %inner.loop.cond, label %inner, label %outer.backedge 949 950outer.backedge: 951 %outer.loop.cond = call i1 @cond() 952 br i1 %outer.loop.cond, label %outer, label %exit 953 954side.exit: 955 ret i32 0 956 957exit: 958 ret i32 1 959} 960 961; Same as test_02, but non-negativity of %b is known without context. 962; FIXME: We can remove 2nd check in loop. 963define i32 @test_06(i32 %a, ptr %bp) { 964; CHECK-LABEL: @test_06( 965; CHECK-NEXT: entry: 966; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 967; CHECK-NEXT: br label [[OUTER:%.*]] 968; CHECK: outer: 969; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ] 970; CHECK-NEXT: br label [[INNER:%.*]] 971; CHECK: inner: 972; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ] 973; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 974; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 975; CHECK: inner.1: 976; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] 977; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 978; CHECK: inner.backedge: 979; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 980; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 981; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]] 982; CHECK: outer.backedge: 983; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 984; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 985; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 986; CHECK: side.exit: 987; CHECK-NEXT: ret i32 0 988; CHECK: exit: 989; CHECK-NEXT: ret i32 1 990; 991entry: 992 %b = load i32, ptr %bp, !range !0 993 br label %outer 994 995outer: 996 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge] 997 br label %inner 998 999 1000inner: 1001 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 1002 %signed_cond = icmp slt i32 %iv, %b 1003 br i1 %signed_cond, label %inner.1, label %side.exit 1004 1005inner.1: 1006 %unsigned_cond = icmp ult i32 %iv, %b 1007 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 1008 1009inner.backedge: 1010 %iv.next = add nuw nsw i32 %iv, 1 1011 %inner.loop.cond = call i1 @cond() 1012 br i1 %inner.loop.cond, label %inner, label %outer.backedge 1013 1014outer.backedge: 1015 %outer.merge = phi i32 [%iv.next, %inner.backedge] 1016 %outer.loop.cond = call i1 @cond() 1017 br i1 %outer.loop.cond, label %outer, label %exit 1018 1019side.exit: 1020 ret i32 0 1021 1022exit: 1023 ret i32 1 1024} 1025 1026; Same as test_03, but non-negativity of %b is known without context. 1027; FIXME: We can remove 2nd check in loop. 1028define i32 @test_07(i32 %a, ptr %bp) { 1029; CHECK-LABEL: @test_07( 1030; CHECK-NEXT: entry: 1031; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 1032; CHECK-NEXT: br label [[OUTER:%.*]] 1033; CHECK: outer: 1034; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ] 1035; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond() 1036; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]] 1037; CHECK: inner.preheader: 1038; CHECK-NEXT: br label [[INNER:%.*]] 1039; CHECK: no_inner: 1040; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond() 1041; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 1042; CHECK: inner: 1043; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ] 1044; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 1045; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 1046; CHECK: inner.1: 1047; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] 1048; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 1049; CHECK: inner.backedge: 1050; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 1051; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 1052; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]] 1053; CHECK: outer.backedge.loopexit: 1054; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 1055; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 1056; CHECK: outer.backedge: 1057; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[OUTER_IV]], [[NO_INNER]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ] 1058; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 1059; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 1060; CHECK: side.exit: 1061; CHECK-NEXT: ret i32 0 1062; CHECK: exit: 1063; CHECK-NEXT: ret i32 1 1064; 1065entry: 1066 %b = load i32, ptr %bp, !range !0 1067 br label %outer 1068 1069outer: 1070 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge] 1071 %outer_cond_1 = call i1 @cond() 1072 br i1 %outer_cond_1, label %inner, label %no_inner 1073 1074no_inner: 1075 %outer_cond_2 = call i1 @cond() 1076 br label %outer.backedge 1077 1078inner: 1079 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 1080 %signed_cond = icmp slt i32 %iv, %b 1081 br i1 %signed_cond, label %inner.1, label %side.exit 1082 1083inner.1: 1084 %unsigned_cond = icmp ult i32 %iv, %b 1085 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 1086 1087inner.backedge: 1088 %iv.next = add nuw nsw i32 %iv, 1 1089 %inner.loop.cond = call i1 @cond() 1090 br i1 %inner.loop.cond, label %inner, label %outer.backedge 1091 1092outer.backedge: 1093 %outer.merge = phi i32 [%outer.iv, %no_inner], [%iv.next, %inner.backedge] 1094 %outer.loop.cond = call i1 @cond() 1095 br i1 %outer.loop.cond, label %outer, label %exit 1096 1097side.exit: 1098 ret i32 0 1099 1100exit: 1101 ret i32 1 1102} 1103 1104; Same as test_04, but non-negativity of %b is known without context. 1105; FIXME: We can remove 2nd check in loop. 1106define i32 @test_08(i32 %a, ptr %bp) { 1107; CHECK-LABEL: @test_08( 1108; CHECK-NEXT: entry: 1109; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]] 1110; CHECK-NEXT: br label [[OUTER:%.*]] 1111; CHECK: outer: 1112; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ] 1113; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond() 1114; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]] 1115; CHECK: inner.preheader: 1116; CHECK-NEXT: br label [[INNER:%.*]] 1117; CHECK: no_inner: 1118; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond() 1119; CHECK-NEXT: br i1 [[OUTER_COND_2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1120; CHECK: if.true: 1121; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 [[OUTER_IV]]) 1122; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 1123; CHECK: if.false: 1124; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 1125; CHECK: inner: 1126; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ] 1127; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] 1128; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] 1129; CHECK: inner.1: 1130; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] 1131; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] 1132; CHECK: inner.backedge: 1133; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 1134; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond() 1135; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]] 1136; CHECK: outer.backedge.loopexit: 1137; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ] 1138; CHECK-NEXT: br label [[OUTER_BACKEDGE]] 1139; CHECK: outer.backedge: 1140; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[SMAX]], [[IF_TRUE]] ], [ [[OUTER_IV]], [[IF_FALSE]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ] 1141; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond() 1142; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]] 1143; CHECK: side.exit: 1144; CHECK-NEXT: ret i32 0 1145; CHECK: exit: 1146; CHECK-NEXT: ret i32 1 1147; 1148entry: 1149 %b = load i32, ptr %bp, !range !0 1150 br label %outer 1151 1152outer: 1153 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge] 1154 %outer_cond_1 = call i1 @cond() 1155 br i1 %outer_cond_1, label %inner, label %no_inner 1156 1157no_inner: 1158 %outer_cond_2 = call i1 @cond() 1159 br i1 %outer_cond_2, label %if.true, label %if.false 1160 1161if.true: 1162 %smax = call i32 @llvm.smax.i32(i32 %a, i32 %outer.iv) 1163 br label %outer.backedge 1164 1165if.false: 1166 br label %outer.backedge 1167 1168inner: 1169 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge] 1170 %signed_cond = icmp slt i32 %iv, %b 1171 br i1 %signed_cond, label %inner.1, label %side.exit 1172 1173inner.1: 1174 %unsigned_cond = icmp ult i32 %iv, %b 1175 br i1 %unsigned_cond, label %inner.backedge, label %side.exit 1176 1177inner.backedge: 1178 %iv.next = add nuw nsw i32 %iv, 1 1179 %inner.loop.cond = call i1 @cond() 1180 br i1 %inner.loop.cond, label %inner, label %outer.backedge 1181 1182outer.backedge: 1183 %outer.merge = phi i32 [%smax, %if.true], [%outer.iv, %if.false], [%iv.next, %inner.backedge] 1184 %outer.loop.cond = call i1 @cond() 1185 br i1 %outer.loop.cond, label %outer, label %exit 1186 1187side.exit: 1188 ret i32 0 1189 1190exit: 1191 ret i32 1 1192} 1193 1194!0 = !{i32 0, i32 2147483647} 1195!1 = !{i32 -2147483648, i32 0} 1196