1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5 6 7declare void @use(ptr) 8declare i1 @cond() 9 10define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start) { 11; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge( 12; CHECK-NEXT: loop.ph: 13; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 10 14; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 15; CHECK: loop.header: 16; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 17; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 18; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 19; CHECK: for.body: 20; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 21; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 22; CHECK: loop.latch: 23; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 24; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 25; CHECK-NEXT: br label [[LOOP_HEADER]] 26; CHECK: exit: 27; CHECK-NEXT: ret void 28; 29loop.ph: 30 %upper = getelementptr inbounds i32, ptr %start, i16 10 31 br label %loop.header 32 33loop.header: 34 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 35 %c = icmp eq ptr %ptr.iv, %upper 36 br i1 %c, label %exit, label %for.body 37 38for.body: 39 %t.1 = icmp uge ptr %ptr.iv, %start 40 %t.2 = icmp ult ptr %ptr.iv, %upper 41 %and = and i1 %t.1, %t.2 42 br i1 %and, label %loop.latch, label %exit 43 44loop.latch: 45 call void @use(ptr %ptr.iv) 46 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 47 br label %loop.header 48 49exit: 50 ret void 51} 52 53define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_1(ptr %start) { 54; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_1( 55; CHECK-NEXT: loop.ph: 56; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15 57; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 58; CHECK: loop.header: 59; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 60; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 61; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 62; CHECK: for.body: 63; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 64; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 65; CHECK: loop.latch: 66; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 67; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 68; CHECK-NEXT: br label [[LOOP_HEADER]] 69; CHECK: exit: 70; CHECK-NEXT: ret void 71; 72loop.ph: 73 %upper = getelementptr inbounds i8, ptr %start, i16 15 74 br label %loop.header 75 76loop.header: 77 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 78 %c = icmp eq ptr %ptr.iv, %upper 79 br i1 %c, label %exit, label %for.body 80 81for.body: 82 %t.1 = icmp uge ptr %ptr.iv, %start 83 %t.2 = icmp ult ptr %ptr.iv, %upper 84 %and = and i1 %t.1, %t.2 85 br i1 %and, label %loop.latch, label %exit 86 87loop.latch: 88 call void @use(ptr %ptr.iv) 89 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 90 br label %loop.header 91 92exit: 93 ret void 94} 95 96define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_2(ptr %start) { 97; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_2( 98; CHECK-NEXT: loop.ph: 99; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 16 100; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 101; CHECK: loop.header: 102; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 103; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 104; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 105; CHECK: for.body: 106; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 107; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 108; CHECK: loop.latch: 109; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 110; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1 111; CHECK-NEXT: br label [[LOOP_HEADER]] 112; CHECK: exit: 113; CHECK-NEXT: ret void 114; 115loop.ph: 116 %upper = getelementptr inbounds i8, ptr %start, i16 16 117 br label %loop.header 118 119loop.header: 120 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 121 %c = icmp eq ptr %ptr.iv, %upper 122 br i1 %c, label %exit, label %for.body 123 124for.body: 125 %t.1 = icmp uge ptr %ptr.iv, %start 126 %t.2 = icmp ult ptr %ptr.iv, %upper 127 %and = and i1 %t.1, %t.2 128 br i1 %and, label %loop.latch, label %exit 129 130loop.latch: 131 call void @use(ptr %ptr.iv) 132 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1 133 br label %loop.header 134 135exit: 136 ret void 137} 138 139define void @test_monotonic_ptr_iv_inc_upper_is_not_multiple_1(ptr %start) { 140; CHECK-LABEL: @test_monotonic_ptr_iv_inc_upper_is_not_multiple_1( 141; CHECK-NEXT: loop.ph: 142; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15 143; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 144; CHECK: loop.header: 145; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 146; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 147; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 148; CHECK: for.body: 149; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 150; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 151; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 152; CHECK: loop.latch: 153; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 154; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 155; CHECK-NEXT: br label [[LOOP_HEADER]] 156; CHECK: exit: 157; CHECK-NEXT: ret void 158; 159loop.ph: 160 %upper = getelementptr inbounds i8, ptr %start, i16 15 161 br label %loop.header 162 163loop.header: 164 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 165 %c = icmp eq ptr %ptr.iv, %upper 166 br i1 %c, label %exit, label %for.body 167 168for.body: 169 %t.1 = icmp uge ptr %ptr.iv, %start 170 %t.2 = icmp ult ptr %ptr.iv, %upper 171 %and = and i1 %t.1, %t.2 172 br i1 %and, label %loop.latch, label %exit 173 174loop.latch: 175 call void @use(ptr %ptr.iv) 176 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 177 br label %loop.header 178 179exit: 180 ret void 181} 182 183define void @test_monotonic_ptr_iv_inc_upper_is_not_multiple_2(ptr %start) { 184; CHECK-LABEL: @test_monotonic_ptr_iv_inc_upper_is_not_multiple_2( 185; CHECK-NEXT: loop.ph: 186; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15 187; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 188; CHECK: loop.header: 189; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 190; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 191; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 192; CHECK: for.body: 193; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 194; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 195; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 196; CHECK: loop.latch: 197; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 198; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 199; CHECK-NEXT: br label [[LOOP_HEADER]] 200; CHECK: exit: 201; CHECK-NEXT: ret void 202; 203loop.ph: 204 %upper = getelementptr inbounds i8, ptr %start, i16 15 205 br label %loop.header 206 207loop.header: 208 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 209 %c = icmp eq ptr %ptr.iv, %upper 210 br i1 %c, label %exit, label %for.body 211 212for.body: 213 %t.1 = icmp uge ptr %ptr.iv, %start 214 %t.2 = icmp ult ptr %ptr.iv, %upper 215 %and = and i1 %t.1, %t.2 216 br i1 %and, label %loop.latch, label %exit 217 218loop.latch: 219 call void @use(ptr %ptr.iv) 220 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 221 br label %loop.header 222 223exit: 224 ret void 225} 226 227define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_1(ptr %start) { 228; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_1( 229; CHECK-NEXT: loop.ph: 230; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10 231; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 232; CHECK: loop.header: 233; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 234; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 235; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 236; CHECK: for.body: 237; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 238; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 239; CHECK: loop.next: 240; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 241; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 242; CHECK: loop.latch: 243; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 244; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 245; CHECK-NEXT: br label [[LOOP_HEADER]] 246; CHECK: exit: 247; CHECK-NEXT: ret void 248; 249loop.ph: 250 %upper = getelementptr inbounds i8, ptr %start, i16 10 251 br label %loop.header 252 253loop.header: 254 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 255 %c = icmp eq ptr %ptr.iv, %upper 256 br i1 %c, label %exit, label %for.body 257 258for.body: 259 %c.1 = call i1 @cond() 260 br i1 %c.1, label %loop.next, label %exit 261 262loop.next: 263 %t.1 = icmp uge ptr %ptr.iv, %start 264 %t.2 = icmp ult ptr %ptr.iv, %upper 265 %and = and i1 %t.1, %t.2 266 br i1 %and, label %loop.latch, label %exit 267 268loop.latch: 269 call void @use(ptr %ptr.iv) 270 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 271 br label %loop.header 272 273exit: 274 ret void 275} 276 277define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_2(ptr %start) { 278; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_2( 279; CHECK-NEXT: loop.ph: 280; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10 281; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 282; CHECK: loop.header: 283; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 284; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 285; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 286; CHECK: for.body: 287; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 288; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 289; CHECK: loop.next: 290; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 291; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 292; CHECK: loop.latch: 293; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 294; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1 295; CHECK-NEXT: br label [[LOOP_HEADER]] 296; CHECK: exit: 297; CHECK-NEXT: ret void 298; 299loop.ph: 300 %upper = getelementptr inbounds i8, ptr %start, i16 10 301 br label %loop.header 302 303loop.header: 304 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 305 %c = icmp eq ptr %ptr.iv, %upper 306 br i1 %c, label %exit, label %for.body 307 308for.body: 309 %c.1 = call i1 @cond() 310 br i1 %c.1, label %loop.next, label %exit 311 312loop.next: 313 %t.1 = icmp uge ptr %ptr.iv, %start 314 %t.2 = icmp ult ptr %ptr.iv, %upper 315 %and = and i1 %t.1, %t.2 316 br i1 %and, label %loop.latch, label %exit 317 318loop.latch: 319 call void @use(ptr %ptr.iv) 320 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1 321 br label %loop.header 322 323exit: 324 ret void 325} 326 327define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_3(ptr %start) { 328; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_3( 329; CHECK-NEXT: loop.ph: 330; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i16, ptr [[START:%.*]], i16 16 331; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 332; CHECK: loop.header: 333; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 334; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 335; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 336; CHECK: for.body: 337; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 338; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 339; CHECK: loop.next: 340; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 341; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 342; CHECK: loop.latch: 343; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 344; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 345; CHECK-NEXT: br label [[LOOP_HEADER]] 346; CHECK: exit: 347; CHECK-NEXT: ret void 348; 349loop.ph: 350 %upper = getelementptr inbounds i16, ptr %start, i16 16 351 br label %loop.header 352 353loop.header: 354 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 355 %c = icmp eq ptr %ptr.iv, %upper 356 br i1 %c, label %exit, label %for.body 357 358for.body: 359 %c.1 = call i1 @cond() 360 br i1 %c.1, label %loop.next, label %exit 361 362loop.next: 363 %t.1 = icmp uge ptr %ptr.iv, %start 364 %t.2 = icmp ult ptr %ptr.iv, %upper 365 %and = and i1 %t.1, %t.2 366 br i1 %and, label %loop.latch, label %exit 367 368loop.latch: 369 call void @use(ptr %ptr.iv) 370 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 371 br label %loop.header 372 373exit: 374 ret void 375} 376 377define void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_1(ptr %start) { 378; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_1( 379; CHECK-NEXT: loop.ph: 380; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10 381; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 382; CHECK: loop.header: 383; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 384; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 385; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 386; CHECK: for.body: 387; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 388; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 389; CHECK: loop.next: 390; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 391; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 392; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 393; CHECK: loop.latch: 394; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 395; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 396; CHECK-NEXT: br label [[LOOP_HEADER]] 397; CHECK: exit: 398; CHECK-NEXT: ret void 399; 400loop.ph: 401 %upper = getelementptr inbounds i8, ptr %start, i16 10 402 br label %loop.header 403 404loop.header: 405 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 406 %c = icmp eq ptr %ptr.iv, %upper 407 br i1 %c, label %exit, label %for.body 408 409for.body: 410 %c.1 = call i1 @cond() 411 br i1 %c.1, label %loop.next, label %exit 412 413loop.next: 414 %t.1 = icmp uge ptr %ptr.iv, %start 415 %t.2 = icmp ult ptr %ptr.iv, %upper 416 %and = and i1 %t.1, %t.2 417 br i1 %and, label %loop.latch, label %exit 418 419loop.latch: 420 call void @use(ptr %ptr.iv) 421 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 422 br label %loop.header 423 424exit: 425 ret void 426} 427 428define void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_2(ptr %start) { 429; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_2( 430; CHECK-NEXT: loop.ph: 431; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 11 432; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 433; CHECK: loop.header: 434; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 435; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 436; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 437; CHECK: for.body: 438; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 439; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 440; CHECK: loop.next: 441; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 442; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 443; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 444; CHECK: loop.latch: 445; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 446; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1 447; CHECK-NEXT: br label [[LOOP_HEADER]] 448; CHECK: exit: 449; CHECK-NEXT: ret void 450; 451loop.ph: 452 %upper = getelementptr inbounds i8, ptr %start, i16 11 453 br label %loop.header 454 455loop.header: 456 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 457 %c = icmp eq ptr %ptr.iv, %upper 458 br i1 %c, label %exit, label %for.body 459 460for.body: 461 %c.1 = call i1 @cond() 462 br i1 %c.1, label %loop.next, label %exit 463 464loop.next: 465 %t.1 = icmp uge ptr %ptr.iv, %start 466 %t.2 = icmp ult ptr %ptr.iv, %upper 467 %and = and i1 %t.1, %t.2 468 br i1 %and, label %loop.latch, label %exit 469 470loop.latch: 471 call void @use(ptr %ptr.iv) 472 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1 473 br label %loop.header 474 475exit: 476 ret void 477} 478 479define void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_3(ptr %start) { 480; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_3( 481; CHECK-NEXT: loop.ph: 482; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i16, ptr [[START:%.*]], i16 9 483; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 484; CHECK: loop.header: 485; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 486; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 487; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 488; CHECK: for.body: 489; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 490; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 491; CHECK: loop.next: 492; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 493; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 494; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 495; CHECK: loop.latch: 496; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 497; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 498; CHECK-NEXT: br label [[LOOP_HEADER]] 499; CHECK: exit: 500; CHECK-NEXT: ret void 501; 502loop.ph: 503 %upper = getelementptr inbounds i16, ptr %start, i16 9 504 br label %loop.header 505 506loop.header: 507 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 508 %c = icmp eq ptr %ptr.iv, %upper 509 br i1 %c, label %exit, label %for.body 510 511for.body: 512 %c.1 = call i1 @cond() 513 br i1 %c.1, label %loop.next, label %exit 514 515loop.next: 516 %t.1 = icmp uge ptr %ptr.iv, %start 517 %t.2 = icmp ult ptr %ptr.iv, %upper 518 %and = and i1 %t.1, %t.2 519 br i1 %and, label %loop.latch, label %exit 520 521loop.latch: 522 call void @use(ptr %ptr.iv) 523 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 524 br label %loop.header 525 526exit: 527 ret void 528} 529