1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=indvars -S | FileCheck %s 3 4; Provide legal integer types. 5target datalayout = "n8:16:32:64" 6 7; CHECK-NOT: sext 8 9define i64 @test(ptr nocapture %first, i32 %count) nounwind readonly { 10; CHECK-LABEL: @test( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[COUNT:%.*]], 0 13; CHECK-NEXT: br i1 [[T0]], label [[BB_NPH:%.*]], label [[BB2:%.*]] 14; CHECK: bb.nph: 15; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[COUNT]] to i64 16; CHECK-NEXT: br label [[BB:%.*]] 17; CHECK: bb: 18; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BB1:%.*]] ], [ 0, [[BB_NPH]] ] 19; CHECK-NEXT: [[RESULT_02:%.*]] = phi i64 [ [[T5:%.*]], [[BB1]] ], [ 0, [[BB_NPH]] ] 20; CHECK-NEXT: [[T2:%.*]] = getelementptr i64, ptr [[FIRST:%.*]], i64 [[INDVARS_IV]] 21; CHECK-NEXT: [[T3:%.*]] = load i64, ptr [[T2]], align 8 22; CHECK-NEXT: [[T4:%.*]] = lshr i64 [[T3]], 4 23; CHECK-NEXT: [[T5]] = add i64 [[T4]], [[RESULT_02]] 24; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 25; CHECK-NEXT: br label [[BB1]] 26; CHECK: bb1: 27; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 28; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB]], label [[BB1_BB2_CRIT_EDGE:%.*]] 29; CHECK: bb1.bb2_crit_edge: 30; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i64 [ [[T5]], [[BB1]] ] 31; CHECK-NEXT: br label [[BB2]] 32; CHECK: bb2: 33; CHECK-NEXT: [[RESULT_0_LCSSA:%.*]] = phi i64 [ [[DOTLCSSA]], [[BB1_BB2_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ] 34; CHECK-NEXT: ret i64 [[RESULT_0_LCSSA]] 35; 36entry: 37 %t0 = icmp sgt i32 %count, 0 ; <i1> [#uses=1] 38 br i1 %t0, label %bb.nph, label %bb2 39 40bb.nph: ; preds = %entry 41 br label %bb 42 43bb: ; preds = %bb1, %bb.nph 44 %result.02 = phi i64 [ %t5, %bb1 ], [ 0, %bb.nph ] ; <i64> [#uses=1] 45 %n.01 = phi i32 [ %t6, %bb1 ], [ 0, %bb.nph ] ; <i32> [#uses=2] 46 %t1 = sext i32 %n.01 to i64 ; <i64> [#uses=1] 47 %t2 = getelementptr i64, ptr %first, i64 %t1 ; <ptr> [#uses=1] 48 %t3 = load i64, ptr %t2, align 8 ; <i64> [#uses=1] 49 %t4 = lshr i64 %t3, 4 ; <i64> [#uses=1] 50 %t5 = add i64 %t4, %result.02 ; <i64> [#uses=2] 51 %t6 = add i32 %n.01, 1 ; <i32> [#uses=2] 52 br label %bb1 53 54bb1: ; preds = %bb 55 %t7 = icmp slt i32 %t6, %count ; <i1> [#uses=1] 56 br i1 %t7, label %bb, label %bb1.bb2_crit_edge 57 58bb1.bb2_crit_edge: ; preds = %bb1 59 %.lcssa = phi i64 [ %t5, %bb1 ] ; <i64> [#uses=1] 60 br label %bb2 61 62bb2: ; preds = %bb1.bb2_crit_edge, %entry 63 %result.0.lcssa = phi i64 [ %.lcssa, %bb1.bb2_crit_edge ], [ 0, %entry ] ; <i64> [#uses=1] 64 ret i64 %result.0.lcssa 65} 66 67define void @foo(i16 signext %N, ptr nocapture %P) nounwind { 68; CHECK-LABEL: @foo( 69; CHECK-NEXT: entry: 70; CHECK-NEXT: [[T0:%.*]] = icmp sgt i16 [[N:%.*]], 0 71; CHECK-NEXT: br i1 [[T0]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] 72; CHECK: bb.nph: 73; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i16 [[N]] to i64 74; CHECK-NEXT: br label [[BB:%.*]] 75; CHECK: bb: 76; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BB1:%.*]] ], [ 0, [[BB_NPH]] ] 77; CHECK-NEXT: [[T2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDVARS_IV]] 78; CHECK-NEXT: store i32 123, ptr [[T2]], align 4 79; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 80; CHECK-NEXT: br label [[BB1]] 81; CHECK: bb1: 82; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 83; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB]], label [[BB1_RETURN_CRIT_EDGE:%.*]] 84; CHECK: bb1.return_crit_edge: 85; CHECK-NEXT: br label [[RETURN]] 86; CHECK: return: 87; CHECK-NEXT: ret void 88; 89entry: 90 %t0 = icmp sgt i16 %N, 0 ; <i1> [#uses=1] 91 br i1 %t0, label %bb.nph, label %return 92 93bb.nph: ; preds = %entry 94 br label %bb 95 96bb: ; preds = %bb1, %bb.nph 97 %i.01 = phi i16 [ %t3, %bb1 ], [ 0, %bb.nph ] ; <i16> [#uses=2] 98 %t1 = sext i16 %i.01 to i64 ; <i64> [#uses=1] 99 %t2 = getelementptr i32, ptr %P, i64 %t1 ; <ptr> [#uses=1] 100 store i32 123, ptr %t2, align 4 101 %t3 = add i16 %i.01, 1 ; <i16> [#uses=2] 102 br label %bb1 103 104bb1: ; preds = %bb 105 %t4 = icmp slt i16 %t3, %N ; <i1> [#uses=1] 106 br i1 %t4, label %bb, label %bb1.return_crit_edge 107 108bb1.return_crit_edge: ; preds = %bb1 109 br label %return 110 111return: ; preds = %bb1.return_crit_edge, %entry 112 ret void 113} 114 115; Test cases from PR1301: 116 117define void @kinds__srangezero(ptr nocapture %a) nounwind { 118; CHECK-LABEL: @kinds__srangezero( 119; CHECK-NEXT: bb.thread: 120; CHECK-NEXT: br label [[BB:%.*]] 121; CHECK: bb: 122; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[BB]] ], [ -10, [[BB_THREAD:%.*]] ] 123; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[INDVARS_IV]], 10 124; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [21 x i32], ptr [[A:%.*]], i32 0, i32 [[TMP4]] 125; CHECK-NEXT: store i32 0, ptr [[TMP5]], align 4 126; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], 1 127; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 11 128; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[BB]] 129; CHECK: return: 130; CHECK-NEXT: ret void 131; 132bb.thread: 133 br label %bb 134 135bb: ; preds = %bb, %bb.thread 136 %i.0.reg2mem.0 = phi i8 [ -10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2] 137 %tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1] 138 %tmp4 = add i32 %tmp12, 10 ; <i32> [#uses=1] 139 %tmp5 = getelementptr [21 x i32], ptr %a, i32 0, i32 %tmp4 ; <ptr> [#uses=1] 140 store i32 0, ptr %tmp5 141 %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2] 142 %0 = icmp sgt i8 %tmp7, 10 ; <i1> [#uses=1] 143 br i1 %0, label %return, label %bb 144 145return: ; preds = %bb 146 ret void 147} 148 149define void @kinds__urangezero(ptr nocapture %a) nounwind { 150; CHECK-LABEL: @kinds__urangezero( 151; CHECK-NEXT: bb.thread: 152; CHECK-NEXT: br label [[BB:%.*]] 153; CHECK: bb: 154; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[BB]] ], [ 10, [[BB_THREAD:%.*]] ] 155; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[INDVARS_IV]], -10 156; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [21 x i32], ptr [[A:%.*]], i32 0, i32 [[TMP4]] 157; CHECK-NEXT: store i32 0, ptr [[TMP5]], align 4 158; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1 159; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 31 160; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[BB]] 161; CHECK: return: 162; CHECK-NEXT: ret void 163; 164bb.thread: 165 br label %bb 166 167bb: ; preds = %bb, %bb.thread 168 %i.0.reg2mem.0 = phi i8 [ 10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2] 169 %tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1] 170 %tmp4 = add i32 %tmp12, -10 ; <i32> [#uses=1] 171 %tmp5 = getelementptr [21 x i32], ptr %a, i32 0, i32 %tmp4 ; <ptr> [#uses=1] 172 store i32 0, ptr %tmp5 173 %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2] 174 %0 = icmp sgt i8 %tmp7, 30 ; <i1> [#uses=1] 175 br i1 %0, label %return, label %bb 176 177return: ; preds = %bb 178 ret void 179} 180 181define void @promote_latch_condition_decrementing_loop_01(ptr %p, ptr %a) { 182; CHECK-LABEL: @promote_latch_condition_decrementing_loop_01( 183; CHECK-NEXT: entry: 184; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0:![0-9]+]] 185; CHECK-NEXT: [[LEN_MINUS_1:%.*]] = add nsw i32 [[LEN]], -1 186; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0 187; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]] 188; CHECK: preheader: 189; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[LEN_MINUS_1]] to i64 190; CHECK-NEXT: br label [[LOOP:%.*]] 191; CHECK: loopexit.loopexit: 192; CHECK-NEXT: br label [[LOOPEXIT]] 193; CHECK: loopexit: 194; CHECK-NEXT: ret void 195; CHECK: loop: 196; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ] 197; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 198; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 199; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 200; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 201; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] 202; 203 204entry: 205 %len = load i32, ptr %p, align 4, !range !0 206 %len.minus.1 = add nsw i32 %len, -1 207 %zero_check = icmp eq i32 %len, 0 208 br i1 %zero_check, label %loopexit, label %preheader 209 210preheader: 211 br label %loop 212 213loopexit: 214 ret void 215 216loop: 217 %iv = phi i32 [ %iv.next, %loop ], [ %len.minus.1, %preheader ] 218 %iv.wide = zext i32 %iv to i64 219 %el = getelementptr inbounds i32, ptr %a, i64 %iv.wide 220 store atomic i32 0, ptr %el unordered, align 4 221 %iv.next = add nsw i32 %iv, -1 222 %loopcond = icmp slt i32 %iv, 1 223 br i1 %loopcond, label %loopexit, label %loop 224} 225 226define void @promote_latch_condition_decrementing_loop_02(ptr %p, ptr %a) { 227; CHECK-LABEL: @promote_latch_condition_decrementing_loop_02( 228; CHECK-NEXT: entry: 229; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]] 230; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0 231; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]] 232; CHECK: preheader: 233; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[LEN]] to i64 234; CHECK-NEXT: br label [[LOOP:%.*]] 235; CHECK: loopexit.loopexit: 236; CHECK-NEXT: br label [[LOOPEXIT]] 237; CHECK: loopexit: 238; CHECK-NEXT: ret void 239; CHECK: loop: 240; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ] 241; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 242; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 243; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 244; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 245; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] 246; 247 248entry: 249 %len = load i32, ptr %p, align 4, !range !0 250 %zero_check = icmp eq i32 %len, 0 251 br i1 %zero_check, label %loopexit, label %preheader 252 253preheader: 254 br label %loop 255 256loopexit: 257 ret void 258 259loop: 260 %iv = phi i32 [ %iv.next, %loop ], [ %len, %preheader ] 261 %iv.wide = zext i32 %iv to i64 262 %el = getelementptr inbounds i32, ptr %a, i64 %iv.wide 263 store atomic i32 0, ptr %el unordered, align 4 264 %iv.next = add nsw i32 %iv, -1 265 %loopcond = icmp slt i32 %iv, 1 266 br i1 %loopcond, label %loopexit, label %loop 267} 268 269define void @promote_latch_condition_decrementing_loop_03(ptr %p, ptr %a) { 270; CHECK-LABEL: @promote_latch_condition_decrementing_loop_03( 271; CHECK-NEXT: entry: 272; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]] 273; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0 274; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]] 275; CHECK: preheader: 276; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[LEN]] to i64 277; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 1 278; CHECK-NEXT: br label [[LOOP:%.*]] 279; CHECK: loopexit.loopexit: 280; CHECK-NEXT: br label [[LOOPEXIT]] 281; CHECK: loopexit: 282; CHECK-NEXT: ret void 283; CHECK: loop: 284; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP1]], [[PREHEADER]] ] 285; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 286; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 287; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 288; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 289; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] 290; 291 292entry: 293 %len = load i32, ptr %p, align 4, !range !0 294 %len.plus.1 = add i32 %len, 1 295 %zero_check = icmp eq i32 %len, 0 296 br i1 %zero_check, label %loopexit, label %preheader 297 298preheader: 299 br label %loop 300 301loopexit: 302 ret void 303 304loop: 305 %iv = phi i32 [ %iv.next, %loop ], [ %len.plus.1, %preheader ] 306 %iv.wide = zext i32 %iv to i64 307 %el = getelementptr inbounds i32, ptr %a, i64 %iv.wide 308 store atomic i32 0, ptr %el unordered, align 4 309 %iv.next = add nsw i32 %iv, -1 310 %loopcond = icmp slt i32 %iv, 1 311 br i1 %loopcond, label %loopexit, label %loop 312} 313 314define void @promote_latch_condition_decrementing_loop_04(ptr %p, ptr %a, i1 %cond) { 315; CHECK-LABEL: @promote_latch_condition_decrementing_loop_04( 316; CHECK-NEXT: entry: 317; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]] 318; CHECK-NEXT: [[LEN_MINUS_1:%.*]] = add nsw i32 [[LEN]], -1 319; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 320; CHECK: if.true: 321; CHECK-NEXT: br label [[MERGE:%.*]] 322; CHECK: if.false: 323; CHECK-NEXT: br label [[MERGE]] 324; CHECK: merge: 325; CHECK-NEXT: [[IV_START:%.*]] = phi i32 [ [[LEN]], [[IF_TRUE]] ], [ [[LEN_MINUS_1]], [[IF_FALSE]] ] 326; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0 327; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]] 328; CHECK: preheader: 329; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[IV_START]] to i64 330; CHECK-NEXT: br label [[LOOP:%.*]] 331; CHECK: loopexit.loopexit: 332; CHECK-NEXT: br label [[LOOPEXIT]] 333; CHECK: loopexit: 334; CHECK-NEXT: ret void 335; CHECK: loop: 336; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ] 337; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 338; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 339; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 340; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 341; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] 342; 343 344entry: 345 %len = load i32, ptr %p, align 4, !range !0 346 %len.minus.1 = add nsw i32 %len, -1 347 br i1 %cond, label %if.true, label %if.false 348 349if.true: 350 br label %merge 351 352if.false: 353 br label %merge 354 355merge: 356 %iv_start = phi i32 [ %len, %if.true ], [%len.minus.1, %if.false ] 357 %zero_check = icmp eq i32 %len, 0 358 br i1 %zero_check, label %loopexit, label %preheader 359 360preheader: 361 br label %loop 362 363loopexit: 364 ret void 365 366loop: 367 %iv = phi i32 [ %iv.next, %loop ], [ %iv_start, %preheader ] 368 %iv.wide = zext i32 %iv to i64 369 %el = getelementptr inbounds i32, ptr %a, i64 %iv.wide 370 store atomic i32 0, ptr %el unordered, align 4 371 %iv.next = add nsw i32 %iv, -1 372 %loopcond = icmp slt i32 %iv, 1 373 br i1 %loopcond, label %loopexit, label %loop 374} 375 376define void @promote_latch_condition_decrementing_loop_05(ptr %p, ptr %a, i1 %cond) { 377; CHECK-LABEL: @promote_latch_condition_decrementing_loop_05( 378; CHECK-NEXT: entry: 379; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]] 380; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 381; CHECK: if.true: 382; CHECK-NEXT: br label [[MERGE:%.*]] 383; CHECK: if.false: 384; CHECK-NEXT: [[LEN_MINUS_1:%.*]] = add nsw i32 [[LEN]], -1 385; CHECK-NEXT: br label [[MERGE]] 386; CHECK: merge: 387; CHECK-NEXT: [[IV_START:%.*]] = phi i32 [ [[LEN]], [[IF_TRUE]] ], [ [[LEN_MINUS_1]], [[IF_FALSE]] ] 388; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0 389; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]] 390; CHECK: preheader: 391; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[IV_START]] to i64 392; CHECK-NEXT: br label [[LOOP:%.*]] 393; CHECK: loopexit.loopexit: 394; CHECK-NEXT: br label [[LOOPEXIT]] 395; CHECK: loopexit: 396; CHECK-NEXT: ret void 397; CHECK: loop: 398; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ] 399; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 400; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 401; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 402; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 403; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] 404; 405 406entry: 407 %len = load i32, ptr %p, align 4, !range !0 408 br i1 %cond, label %if.true, label %if.false 409 410if.true: 411 br label %merge 412 413if.false: 414 %len.minus.1 = add nsw i32 %len, -1 415 br label %merge 416 417merge: 418 %iv_start = phi i32 [ %len, %if.true ], [%len.minus.1, %if.false ] 419 %zero_check = icmp eq i32 %len, 0 420 br i1 %zero_check, label %loopexit, label %preheader 421 422preheader: 423 br label %loop 424 425loopexit: 426 ret void 427 428loop: 429 %iv = phi i32 [ %iv.next, %loop ], [ %iv_start, %preheader ] 430 %iv.wide = zext i32 %iv to i64 431 %el = getelementptr inbounds i32, ptr %a, i64 %iv.wide 432 store atomic i32 0, ptr %el unordered, align 4 433 %iv.next = add nsw i32 %iv, -1 434 %loopcond = icmp slt i32 %iv, 1 435 br i1 %loopcond, label %loopexit, label %loop 436} 437 438!0 = !{i32 0, i32 2147483647} 439