1; REQUIRES: asserts 2 3; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -debug -disable-output %s 2>&1 | FileCheck %s 4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 6 7@a = common global [2048 x i32] zeroinitializer, align 16 8@b = common global [2048 x i32] zeroinitializer, align 16 9@c = common global [2048 x i32] zeroinitializer, align 16 10 11 12; CHECK-LABEL: LV: Checking a loop in 'sink1' 13; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 14; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 15; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 16; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 17; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 18; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 19; CHECK-EMPTY: 20; CHECK-NEXT: ir-bb<entry>: 21; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 22; CHECK-NEXT: Successor(s): vector.ph 23; CHECK-EMPTY: 24; CHECK-NEXT: vector.ph: 25; CHECK-NEXT: Successor(s): vector loop 26; CHECK-EMPTY: 27; CHECK-NEXT: <x1> vector loop: { 28; CHECK-NEXT: vector.body: 29; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 30; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 31; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 32; CHECK-NEXT: Successor(s): pred.store 33 34; CHECK: <xVFxUF> pred.store: { 35; CHECK-NEXT: pred.store.entry: 36; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 37; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 38 39; CHECK: pred.store.if: 40; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 41; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 42; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> 43; CHECK-NEXT: REPLICATE ir<%add> = add ir<%lv.b>, ir<10> 44; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]] 45; CHECK-NEXT: REPLICATE ir<%mul> = mul ir<2>, ir<%add> 46; CHECK-NEXT: REPLICATE store ir<%mul>, ir<%gep.a> 47; CHECK-NEXT: Successor(s): pred.store.continue 48 49; CHECK: pred.store.continue: 50; CHECK-NEXT: No successors 51; CHECK-NEXT: } 52 53; CHECK: loop.1: 54; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 55; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 56; CHECK-NEXT: No successors 57; CHECK-NEXT: } 58; 59define void @sink1(i32 %k) { 60entry: 61 br label %loop 62 63loop: 64 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 65 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 66 %lv.b = load i32, ptr %gep.b, align 4 67 %add = add i32 %lv.b, 10 68 %mul = mul i32 2, %add 69 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv 70 store i32 %mul, ptr %gep.a, align 4 71 %iv.next = add i32 %iv, 1 72 %large = icmp sge i32 %iv, 8 73 %exitcond = icmp eq i32 %iv, %k 74 %realexit = or i1 %large, %exitcond 75 br i1 %realexit, label %exit, label %loop 76 77exit: 78 ret void 79} 80 81; CHECK-LABEL: LV: Checking a loop in 'sink2' 82; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 83; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 84; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 85; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 86; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 87; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 88; CHECK-EMPTY: 89; CHECK-NEXT: ir-bb<entry>: 90; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 91; CHECK-NEXT: Successor(s): vector.ph 92; CHECK-EMPTY: 93; CHECK-NEXT: vector.ph: 94; CHECK-NEXT: Successor(s): vector loop 95; CHECK-EMPTY: 96; CHECK-NEXT: <x1> vector loop: { 97; CHECK-NEXT: vector.body: 98; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 99; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 100; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 101; CHECK-NEXT: Successor(s): pred.load 102 103; CHECK: <xVFxUF> pred.load: { 104; CHECK-NEXT: pred.load.entry: 105; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 106; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue 107 108; CHECK: pred.load.if: 109; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 110; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 111; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> 112; CHECK-NEXT: Successor(s): pred.load.continue 113 114; CHECK: pred.load.continue: 115; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b> 116; CHECK-NEXT: No successors 117; CHECK-NEXT: } 118 119; CHECK: loop.0: 120; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%iv>, ir<2> 121; CHECK-NEXT: Successor(s): pred.store 122 123; CHECK: <xVFxUF> pred.store: { 124; CHECK-NEXT: pred.store.entry: 125; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 126; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 127 128; CHECK: pred.store.if: 129; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul> 130; CHECK-NEXT: REPLICATE ir<%add> = add vp<[[PRED]]>, ir<10> 131; CHECK-NEXT: REPLICATE store ir<%add>, ir<%gep.a> 132; CHECK-NEXT: Successor(s): pred.store.continue 133 134; CHECK: pred.store.continue: 135; CHECK-NEXT: No successors 136; CHECK-NEXT: } 137 138; CHECK: loop.1: 139; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 140; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 141; CHECK-NEXT: No successors 142; CHECK-NEXT: } 143; 144define void @sink2(i32 %k) { 145entry: 146 br label %loop 147 148loop: 149 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 150 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 151 %lv.b = load i32, ptr %gep.b, align 4 152 %add = add i32 %lv.b, 10 153 %mul = mul i32 %iv, 2 154 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul 155 store i32 %add, ptr %gep.a, align 4 156 %iv.next = add i32 %iv, 1 157 %large = icmp sge i32 %iv, 8 158 %exitcond = icmp eq i32 %iv, %k 159 %realexit = or i1 %large, %exitcond 160 br i1 %realexit, label %exit, label %loop 161 162exit: 163 ret void 164} 165 166; CHECK-LABEL: LV: Checking a loop in 'sink3' 167; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 168; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 169; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 170; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 171; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 172; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 173; CHECK-EMPTY: 174; CHECK-NEXT: ir-bb<entry>: 175; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 176; CHECK-NEXT: Successor(s): vector.ph 177; CHECK-EMPTY: 178; CHECK-NEXT: vector.ph: 179; CHECK-NEXT: Successor(s): vector loop 180; CHECK-EMPTY: 181; CHECK-NEXT: <x1> vector loop: { 182; CHECK-NEXT: vector.body: 183; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 184; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 185; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 186; CHECK-NEXT: Successor(s): pred.load 187 188; CHECK: <xVFxUF> pred.load: { 189; CHECK-NEXT: pred.load.entry: 190; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 191; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue 192 193; CHECK: pred.load.if: 194; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 195; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 196; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V) 197; CHECK-NEXT: Successor(s): pred.load.continue 198 199; CHECK: pred.load.continue: 200; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b> 201; CHECK-NEXT: No successors 202; CHECK-NEXT: } 203 204; CHECK: loop.0: 205; CHECK-NEXT: WIDEN ir<%add> = add vp<[[PRED]]>, ir<10> 206; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%iv>, ir<%add> 207; CHECK-NEXT: Successor(s): pred.store 208 209; CHECK: <xVFxUF> pred.store: { 210; CHECK-NEXT: pred.store.entry: 211; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 212; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 213 214; CHECK: pred.store.if: 215; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul> 216; CHECK-NEXT: REPLICATE store ir<%add>, ir<%gep.a> 217; CHECK-NEXT: Successor(s): pred.store.continue 218 219; CHECK: pred.store.continue: 220; CHECK-NEXT: No successors 221; CHECK-NEXT: } 222 223; CHECK: loop.1: 224; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 225; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 226; CHECK-NEXT: No successors 227; CHECK-NEXT: } 228; 229define void @sink3(i32 %k) { 230entry: 231 br label %loop 232 233loop: 234 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 235 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 236 %lv.b = load i32, ptr %gep.b, align 4 237 %add = add i32 %lv.b, 10 238 %mul = mul i32 %iv, %add 239 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul 240 store i32 %add, ptr %gep.a, align 4 241 %iv.next = add i32 %iv, 1 242 %large = icmp sge i32 %iv, 8 243 %exitcond = icmp eq i32 %iv, %k 244 %realexit = or i1 %large, %exitcond 245 br i1 %realexit, label %exit, label %loop 246 247exit: 248 ret void 249} 250 251; Make sure we do not sink uniform instructions. 252define void @uniform_gep(i64 %k, ptr noalias %A, ptr noalias %B) { 253; CHECK-LABEL: LV: Checking a loop in 'uniform_gep' 254; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 255; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 256; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 257; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 258; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 259; CHECK-NEXT: Live-in ir<11> = original trip-count 260; CHECK-EMPTY: 261; CHECK-NEXT: ir-bb<entry>: 262; CHECK-NEXT: Successor(s): vector.ph 263; CHECK-EMPTY: 264; CHECK-NEXT: vector.ph: 265; CHECK-NEXT: vp<[[END:%.+]]> = DERIVED-IV ir<21> + vp<[[VEC_TC]]> * ir<1> 266; CHECK-NEXT: CLONE ir<%gep.A.uniform> = getelementptr inbounds ir<%A>, ir<0> 267; CHECK-NEXT: Successor(s): vector loop 268; CHECK-EMPTY: 269; CHECK-NEXT: <x1> vector loop: { 270; CHECK-NEXT: vector.body: 271; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 272; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<21>, ir<1>, vp<[[VF]]> 273; CHECK-NEXT: vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<21> + vp<[[CAN_IV]]> * ir<1> 274; CHECK-NEXT: EMIT vp<[[WIDE_CAN_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]> 275; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDE_CAN_IV]]>, vp<[[BTC]]> 276; CHECK-NEXT: CLONE ir<%lv> = load ir<%gep.A.uniform> 277; CHECK-NEXT: WIDEN ir<%cmp> = icmp ult ir<%iv>, ir<%k> 278; CHECK-NEXT: EMIT vp<[[NOT2:%.+]]> = not ir<%cmp> 279; CHECK-NEXT: EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK]]>, vp<[[NOT2]]> 280; CHECK-NEXT: Successor(s): pred.store 281; CHECK-EMPTY: 282; CHECK-NEXT: <xVFxUF> pred.store: { 283; CHECK-NEXT: pred.store.entry: 284; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]> 285; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 286; CHECK-EMPTY: 287; CHECK-NEXT: pred.store.if: 288; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DERIVED_IV]]>, ir<1> 289; CHECK-NEXT: REPLICATE ir<%gep.B> = getelementptr inbounds ir<%B>, vp<[[STEPS]]> 290; CHECK-NEXT: REPLICATE store ir<%lv>, ir<%gep.B> 291; CHECK-NEXT: Successor(s): pred.store.continue 292; CHECK-EMPTY: 293; CHECK-NEXT: pred.store.continue: 294; CHECK-NEXT: No successors 295; CHECK-NEXT: } 296; CHECK-NEXT: Successor(s): loop.then.0 297; CHECK-EMPTY: 298; CHECK-NEXT: loop.then.0: 299; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 300; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 301; CHECK-NEXT: No successors 302; CHECK-NEXT: } 303; 304entry: 305 br label %loop 306 307loop: 308 %iv = phi i64 [ 21, %entry ], [ %iv.next, %loop.latch ] 309 %gep.A.uniform = getelementptr inbounds i16, ptr %A, i64 0 310 %gep.B = getelementptr inbounds i16, ptr %B, i64 %iv 311 %lv = load i16, ptr %gep.A.uniform, align 1 312 %cmp = icmp ult i64 %iv, %k 313 br i1 %cmp, label %loop.latch, label %loop.then 314 315loop.then: 316 store i16 %lv, ptr %gep.B, align 1 317 br label %loop.latch 318 319loop.latch: 320 %iv.next = add nsw i64 %iv, 1 321 %cmp179 = icmp slt i64 %iv.next, 32 322 br i1 %cmp179, label %loop, label %exit 323exit: 324 ret void 325} 326 327; Loop with predicated load. 328define void @pred_cfg1(i32 %k, i32 %j) { 329; CHECK-LABEL: LV: Checking a loop in 'pred_cfg1' 330; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 331; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 332; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 333; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 334; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 335; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 336; CHECK-EMPTY: 337; CHECK-NEXT: ir-bb<entry>: 338; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 339; CHECK-NEXT: Successor(s): vector.ph 340; CHECK-EMPTY: 341; CHECK-NEXT: vector.ph: 342; CHECK-NEXT: Successor(s): vector loop 343; CHECK-EMPTY: 344; CHECK-NEXT: <x1> vector loop: { 345; CHECK-NEXT: vector.body: 346; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 347; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 348; CHECK-NEXT: EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 349; CHECK-NEXT: WIDEN ir<%c.1> = icmp ult ir<%iv>, ir<%j> 350; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%iv>, ir<10> 351; CHECK-NEXT: EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.1> 352; CHECK-NEXT: Successor(s): pred.load 353; CHECK-EMPTY: 354; CHECK-NEXT: <xVFxUF> pred.load: { 355; CHECK-NEXT: pred.load.entry: 356; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]> 357; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue 358; CHECK-EMPTY: 359; CHECK-NEXT: pred.load.if: 360; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 361; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 362; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V) 363; CHECK-NEXT: Successor(s): pred.load.continue 364; CHECK-EMPTY: 365; CHECK-NEXT: pred.load.continue: 366; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b> 367; CHECK-NEXT: No successors 368; CHECK-NEXT: } 369; CHECK-NEXT: Successor(s): then.0.0 370; CHECK-EMPTY: 371; CHECK-NEXT: then.0.0: 372; CHECK-NEXT: BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]> 373; CHECK-NEXT: Successor(s): pred.store 374; CHECK-EMPTY: 375; CHECK-NEXT: <xVFxUF> pred.store: { 376; CHECK-NEXT: pred.store.entry: 377; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK1]]> 378; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 379; CHECK-EMPTY: 380; CHECK-NEXT: pred.store.if: 381; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul> 382; CHECK-NEXT: REPLICATE store ir<%p>, ir<%gep.a> 383; CHECK-NEXT: Successor(s): pred.store.continue 384; CHECK-EMPTY: 385; CHECK-NEXT: pred.store.continue: 386; CHECK-NEXT: No successors 387; CHECK-NEXT: } 388; CHECK-NEXT: Successor(s): next.0.1 389; CHECK-EMPTY: 390; CHECK-NEXT: next.0.1: 391; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 392; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 393; CHECK-NEXT: No successors 394; CHECK-NEXT: } 395; 396entry: 397 br label %loop 398 399loop: 400 %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.0 ] 401 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 402 %c.1 = icmp ult i32 %iv, %j 403 %mul = mul i32 %iv, 10 404 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul 405 br i1 %c.1, label %then.0, label %next.0 406 407then.0: 408 %lv.b = load i32, ptr %gep.b, align 4 409 br label %next.0 410 411next.0: 412 %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ] 413 store i32 %p, ptr %gep.a, align 4 414 %iv.next = add i32 %iv, 1 415 %large = icmp sge i32 %iv, 8 416 %exitcond = icmp eq i32 %iv, %k 417 %realexit = or i1 %large, %exitcond 418 br i1 %realexit, label %exit, label %loop 419 420exit: 421 ret void 422} 423 424; Loop with predicated load and store in separate blocks, store depends on 425; loaded value. 426define void @pred_cfg2(i32 %k, i32 %j) { 427; CHECK-LABEL: LV: Checking a loop in 'pred_cfg2' 428; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 429; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 430; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 431; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 432; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 433; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 434; CHECK-EMPTY: 435; CHECK-NEXT: ir-bb<entry>: 436; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 437; CHECK-NEXT: Successor(s): vector.ph 438; CHECK-EMPTY: 439; CHECK-NEXT: vector.ph: 440; CHECK-NEXT: Successor(s): vector loop 441; CHECK-EMPTY: 442; CHECK-NEXT: <x1> vector loop: { 443; CHECK-NEXT: vector.body: 444; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 445; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 446; CHECK-NEXT: EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 447; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%iv>, ir<10> 448; CHECK-NEXT: WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j> 449; CHECK-NEXT: WIDEN ir<%c.1> = icmp ugt ir<%iv>, ir<%j> 450; CHECK-NEXT: EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.0> 451; CHECK-NEXT: Successor(s): pred.load 452; CHECK-EMPTY: 453; CHECK-NEXT: <xVFxUF> pred.load: { 454; CHECK-NEXT: pred.load.entry: 455; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]> 456; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue 457; CHECK-EMPTY: 458; CHECK-NEXT: pred.load.if: 459; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 460; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 461; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V) 462; CHECK-NEXT: Successor(s): pred.load.continue 463; CHECK-EMPTY: 464; CHECK-NEXT: pred.load.continue: 465; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b> 466; CHECK-NEXT: No successors 467; CHECK-NEXT: } 468; CHECK-NEXT: Successor(s): then.0.0 469; CHECK-EMPTY: 470; CHECK-NEXT: then.0.0: 471; CHECK-NEXT: BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]> 472; CHECK-NEXT: EMIT vp<[[MASK3:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.1> 473; CHECK-NEXT: Successor(s): pred.store 474; CHECK-EMPTY: 475; CHECK-NEXT: <xVFxUF> pred.store: { 476; CHECK-NEXT: pred.store.entry: 477; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK3]]> 478; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 479; CHECK-EMPTY: 480; CHECK-NEXT: pred.store.if: 481; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul> 482; CHECK-NEXT: REPLICATE store ir<%p>, ir<%gep.a> 483; CHECK-NEXT: Successor(s): pred.store.continue 484; CHECK-EMPTY: 485; CHECK-NEXT: pred.store.continue: 486; CHECK-NEXT: No successors 487; CHECK-NEXT: } 488; CHECK-NEXT: Successor(s): then.1.1 489; CHECK-EMPTY: 490; CHECK-NEXT: then.1.1: 491; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 492; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 493; CHECK-NEXT: No successors 494; CHECK-NEXT: } 495; 496entry: 497 br label %loop 498 499loop: 500 %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.1 ] 501 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 502 %mul = mul i32 %iv, 10 503 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul 504 %c.0 = icmp ult i32 %iv, %j 505 %c.1 = icmp ugt i32 %iv, %j 506 br i1 %c.0, label %then.0, label %next.0 507 508then.0: 509 %lv.b = load i32, ptr %gep.b, align 4 510 br label %next.0 511 512next.0: 513 %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ] 514 br i1 %c.1, label %then.1, label %next.1 515 516then.1: 517 store i32 %p, ptr %gep.a, align 4 518 br label %next.1 519 520next.1: 521 %iv.next = add i32 %iv, 1 522 %large = icmp sge i32 %iv, 8 523 %exitcond = icmp eq i32 %iv, %k 524 %realexit = or i1 %large, %exitcond 525 br i1 %realexit, label %exit, label %loop 526 527exit: 528 ret void 529} 530 531; Loop with predicated load and store in separate blocks, store does not depend 532; on loaded value. 533define void @pred_cfg3(i32 %k, i32 %j) { 534; CHECK-LABEL: LV: Checking a loop in 'pred_cfg3' 535; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 536; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 537; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 538; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 539; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 540; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 541; CHECK-EMPTY: 542; CHECK-NEXT: ir-bb<entry>: 543; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 544; CHECK-NEXT: Successor(s): vector.ph 545; CHECK-EMPTY: 546; CHECK-NEXT: vector.ph: 547; CHECK-NEXT: Successor(s): vector loop 548; CHECK-EMPTY: 549; CHECK-NEXT: <x1> vector loop: { 550; CHECK-NEXT: vector.body: 551; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 552; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 553; CHECK-NEXT: EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 554; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%iv>, ir<10> 555; CHECK-NEXT: WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j> 556; CHECK-NEXT: EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1:%.+]]>, ir<%c.0> 557; CHECK-NEXT: Successor(s): pred.load 558; CHECK-EMPTY: 559; CHECK-NEXT: <xVFxUF> pred.load: { 560; CHECK-NEXT: pred.load.entry: 561; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]> 562; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue 563; CHECK-EMPTY: 564; CHECK-NEXT: pred.load.if: 565; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 566; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 567; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> 568; CHECK-NEXT: Successor(s): pred.load.continue 569; CHECK-EMPTY: 570; CHECK-NEXT: pred.load.continue: 571; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b> 572; CHECK-NEXT: No successors 573; CHECK-NEXT: } 574; CHECK-NEXT: Successor(s): then.0.0 575; CHECK-EMPTY: 576; CHECK-NEXT: then.0.0: 577; CHECK-NEXT: BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]> 578; CHECK-NEXT: EMIT vp<[[MASK3:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.0> 579; CHECK-NEXT: Successor(s): pred.store 580; CHECK-EMPTY: 581; CHECK-NEXT: <xVFxUF> pred.store: { 582; CHECK-NEXT: pred.store.entry: 583; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK3]]> 584; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 585; CHECK-EMPTY: 586; CHECK-NEXT: pred.store.if: 587; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul> 588; CHECK-NEXT: REPLICATE store ir<0>, ir<%gep.a> 589; CHECK-NEXT: REPLICATE ir<%gep.c> = getelementptr inbounds ir<@c>, ir<0>, ir<%mul> 590; CHECK-NEXT: REPLICATE store ir<%p>, ir<%gep.c> 591; CHECK-NEXT: Successor(s): pred.store.continue 592; CHECK-EMPTY: 593; CHECK-NEXT: pred.store.continue: 594; CHECK-NEXT: No successors 595; CHECK-NEXT: } 596; CHECK-NEXT: Successor(s): then.1.2 597; CHECK-EMPTY: 598; CHECK-NEXT: then.1.2: 599; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 600; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 601; CHECK-NEXT: No successors 602; CHECK-NEXT: } 603; 604entry: 605 br label %loop 606 607loop: 608 %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.1 ] 609 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 610 %mul = mul i32 %iv, 10 611 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul 612 %gep.c = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %mul 613 %c.0 = icmp ult i32 %iv, %j 614 br i1 %c.0, label %then.0, label %next.0 615 616then.0: 617 %lv.b = load i32, ptr %gep.b, align 4 618 br label %next.0 619 620next.0: 621 %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ] 622 br i1 %c.0, label %then.1, label %next.1 623 624then.1: 625 store i32 0, ptr %gep.a, align 4 626 store i32 %p, ptr %gep.c, align 4 627 br label %next.1 628 629next.1: 630 %iv.next = add i32 %iv, 1 631 %large = icmp sge i32 %iv, 8 632 %exitcond = icmp eq i32 %iv, %k 633 %realexit = or i1 %large, %exitcond 634 br i1 %realexit, label %exit, label %loop 635 636exit: 637 ret void 638} 639 640define void @merge_3_replicate_region(i32 %k, i32 %j) { 641; CHECK-LABEL: LV: Checking a loop in 'merge_3_replicate_region' 642; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 643; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 644; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 645; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 646; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 647; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 648; CHECK-EMPTY: 649; CHECK-NEXT: ir-bb<entry>: 650; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 651; CHECK-NEXT: Successor(s): vector.ph 652; CHECK-EMPTY: 653; CHECK-NEXT: vector.ph: 654; CHECK-NEXT: Successor(s): vector loop 655; CHECK-EMPTY: 656; CHECK-NEXT: <x1> vector loop: { 657; CHECK-NEXT: vector.body: 658; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 659; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 660; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 661; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 662; CHECK-NEXT: Successor(s): pred.store 663; CHECK-EMPTY: 664; CHECK-NEXT: <xVFxUF> pred.store: { 665; CHECK-NEXT: pred.store.entry: 666; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 667; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 668; CHECK-EMPTY: 669; CHECK-NEXT: pred.store.if: 670; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]> 671; CHECK-NEXT: REPLICATE ir<%lv.a> = load ir<%gep.a> 672; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]> 673; CHECK-NEXT: REPLICATE ir<%lv.b> = load ir<%gep.b> 674; CHECK-NEXT: REPLICATE ir<%gep.c> = getelementptr inbounds ir<@c>, ir<0>, vp<[[STEPS]]> 675; CHECK-NEXT: REPLICATE store ir<%lv.a>, ir<%gep.c> 676; CHECK-NEXT: REPLICATE store ir<%lv.b>, ir<%gep.a> 677; CHECK-NEXT: Successor(s): pred.store.continue 678; CHECK-EMPTY: 679; CHECK-NEXT: pred.store.continue: 680; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%lv.a> 681; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%lv.b> 682; CHECK-NEXT: No successors 683; CHECK-NEXT: } 684; CHECK-NEXT: Successor(s): loop.3 685; CHECK-EMPTY: 686; CHECK-NEXT: loop.3: 687; CHECK-NEXT: WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j> 688; CHECK-NEXT: EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK]]>, ir<%c.0> 689; CHECK-NEXT: WIDEN ir<%mul> = mul vp<[[PRED1]]>, vp<[[PRED2]]> 690; CHECK-NEXT: Successor(s): pred.store 691; CHECK-EMPTY: 692; CHECK-NEXT: <xVFxUF> pred.store: { 693; CHECK-NEXT: pred.store.entry: 694; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]> 695; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 696; CHECK-EMPTY: 697; CHECK-NEXT: pred.store.if: 698; CHECK-NEXT: REPLICATE ir<%gep.c.1> = getelementptr inbounds ir<@c>, ir<0>, vp<[[STEPS]]> 699; CHECK-NEXT: REPLICATE store ir<%mul>, ir<%gep.c.1> 700; CHECK-NEXT: Successor(s): pred.store.continue 701; CHECK-EMPTY: 702; CHECK-NEXT: pred.store.continue: 703; CHECK-NEXT: No successors 704; CHECK-NEXT: } 705; CHECK-NEXT: Successor(s): then.0.4 706; CHECK-EMPTY: 707; CHECK-NEXT: then.0.4: 708; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 709; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 710; CHECK-NEXT: No successors 711; CHECK-NEXT: } 712; 713entry: 714 br label %loop 715 716loop: 717 %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ] 718 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv 719 %lv.a = load i32, ptr %gep.a, align 4 720 %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv 721 %lv.b = load i32, ptr %gep.b, align 4 722 %gep.c = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %iv 723 store i32 %lv.a, ptr %gep.c, align 4 724 store i32 %lv.b, ptr %gep.a, align 4 725 %c.0 = icmp ult i32 %iv, %j 726 br i1 %c.0, label %then.0, label %latch 727 728then.0: 729 %mul = mul i32 %lv.a, %lv.b 730 %gep.c.1 = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %iv 731 store i32 %mul, ptr %gep.c.1, align 4 732 br label %latch 733 734latch: 735 %iv.next = add i32 %iv, 1 736 %large = icmp sge i32 %iv, 8 737 %exitcond = icmp eq i32 %iv, %k 738 %realexit = or i1 %large, %exitcond 739 br i1 %realexit, label %exit, label %loop 740 741exit: 742 ret void 743} 744 745 746define void @update_2_uses_in_same_recipe_in_merged_block(i32 %k) { 747; CHECK-LABEL: LV: Checking a loop in 'update_2_uses_in_same_recipe_in_merged_block' 748; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 749; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 750; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 751; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 752; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 753; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 754; CHECK-EMPTY: 755; CHECK-NEXT: ir-bb<entry>: 756; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 757; CHECK-NEXT: Successor(s): vector.ph 758; CHECK-EMPTY: 759; CHECK-NEXT: vector.ph: 760; CHECK-NEXT: Successor(s): vector loop 761; CHECK-EMPTY: 762; CHECK-NEXT: <x1> vector loop: { 763; CHECK-NEXT: vector.body: 764; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 765; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 766; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 767; CHECK-NEXT: Successor(s): pred.store 768; CHECK-EMPTY: 769; CHECK-NEXT: <xVFxUF> pred.store: { 770; CHECK-NEXT: pred.store.entry: 771; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 772; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 773; CHECK-EMPTY: 774; CHECK-NEXT: pred.store.if: 775; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 776; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]> 777; CHECK-NEXT: REPLICATE ir<%lv.a> = load ir<%gep.a> 778; CHECK-NEXT: REPLICATE ir<%div> = sdiv ir<%lv.a>, ir<%lv.a> 779; CHECK-NEXT: REPLICATE store ir<%div>, ir<%gep.a> 780; CHECK-NEXT: Successor(s): pred.store.continue 781; CHECK-EMPTY: 782; CHECK-NEXT: pred.store.continue: 783; CHECK-NEXT: No successors 784; CHECK-NEXT: } 785; CHECK-NEXT: Successor(s): loop.2 786; CHECK-EMPTY: 787; CHECK-NEXT: loop.2: 788; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 789; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 790; CHECK-NEXT: No successors 791; CHECK-NEXT: } 792; 793entry: 794 br label %loop 795 796loop: 797 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 798 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv 799 %lv.a = load i32, ptr %gep.a, align 4 800 %div = sdiv i32 %lv.a, %lv.a 801 store i32 %div, ptr %gep.a, align 4 802 %iv.next = add i32 %iv, 1 803 %large = icmp sge i32 %iv, 8 804 %exitcond = icmp eq i32 %iv, %k 805 %realexit = or i1 %large, %exitcond 806 br i1 %realexit, label %exit, label %loop 807 808exit: 809 ret void 810} 811 812define void @recipe_in_merge_candidate_used_by_first_order_recurrence(i32 %k) { 813; CHECK-LABEL: LV: Checking a loop in 'recipe_in_merge_candidate_used_by_first_order_recurrence' 814; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 815; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 816; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 817; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 818; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 819; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 820; CHECK-EMPTY: 821; CHECK-NEXT: ir-bb<entry>: 822; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw> 823; CHECK-NEXT: Successor(s): vector.ph 824; CHECK-EMPTY: 825; CHECK-NEXT: vector.ph: 826; CHECK-NEXT: Successor(s): vector loop 827; CHECK-EMPTY: 828; CHECK-NEXT: <x1> vector loop: { 829; CHECK-NEXT: vector.body: 830; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 831; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]> 832; CHECK-NEXT: FIRST-ORDER-RECURRENCE-PHI ir<%for> = phi ir<0>, vp<[[PRED:%.+]]> 833; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 834; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]> 835; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]> 836; CHECK-NEXT: Successor(s): pred.load 837; CHECK-EMPTY: 838; CHECK-NEXT: <xVFxUF> pred.load: { 839; CHECK-NEXT: pred.load.entry: 840; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 841; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue 842; CHECK-EMPTY: 843; CHECK-NEXT: pred.load.if: 844; CHECK-NEXT: REPLICATE ir<%lv.a> = load ir<%gep.a> 845; CHECK-NEXT: Successor(s): pred.load.continue 846; CHECK-EMPTY: 847; CHECK-NEXT: pred.load.continue: 848; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED]]> = ir<%lv.a> 849; CHECK-NEXT: No successors 850; CHECK-NEXT: } 851; CHECK-NEXT: Successor(s): loop.0 852; CHECK-EMPTY: 853; CHECK-NEXT: loop.0: 854; CHECK-NEXT: EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%for>, vp<[[PRED]]> 855; CHECK-NEXT: Successor(s): pred.store 856; CHECK-EMPTY: 857; CHECK-NEXT: <xVFxUF> pred.store: { 858; CHECK-NEXT: pred.store.entry: 859; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 860; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 861; CHECK-EMPTY: 862; CHECK-NEXT: pred.store.if: 863; CHECK-NEXT: REPLICATE ir<%div> = sdiv vp<[[SPLICE]]>, vp<[[PRED]]> 864; CHECK-NEXT: REPLICATE store ir<%div>, ir<%gep.a> 865; CHECK-NEXT: Successor(s): pred.store.continue 866; CHECK-EMPTY: 867; CHECK-NEXT: pred.store.continue: 868; CHECK-NEXT: No successors 869; CHECK-NEXT: } 870; CHECK-NEXT: Successor(s): loop.2 871; CHECK-EMPTY: 872; CHECK-NEXT: loop.2: 873; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 874; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 875; CHECK-NEXT: No successors 876; CHECK-NEXT: } 877; 878entry: 879 br label %loop 880 881loop: 882 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 883 %for = phi i32 [ 0, %entry ], [ %lv.a, %loop ] 884 %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv 885 %lv.a = load i32, ptr %gep.a, align 4 886 %div = sdiv i32 %for, %lv.a 887 store i32 %div, ptr %gep.a, align 4 888 %iv.next = add i32 %iv, 1 889 %large = icmp sge i32 %iv, 8 890 %exitcond = icmp eq i32 %iv, %k 891 %realexit = or i1 %large, %exitcond 892 br i1 %realexit, label %exit, label %loop 893 894exit: 895 ret void 896} 897 898define void @update_multiple_users(ptr noalias %src, ptr noalias %dst, i1 %c) { 899; CHECK-LABEL: LV: Checking a loop in 'update_multiple_users' 900; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 901; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 902; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 903; CHECK-NEXT: Live-in ir<999> = original trip-count 904; CHECK-EMPTY: 905; CHECK-NEXT: ir-bb<entry>: 906; CHECK-NEXT: Successor(s): vector.ph 907; CHECK-EMPTY: 908; CHECK-NEXT: vector.ph: 909; CHECK-NEXT: Successor(s): vector loop 910; CHECK-EMPTY: 911; CHECK-NEXT: <x1> vector loop: { 912; CHECK-NEXT: vector.body: 913; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 914; CHECK-NEXT: Successor(s): pred.store 915; CHECK-EMPTY: 916; CHECK-NEXT: <xVFxUF> pred.store: { 917; CHECK-NEXT: pred.store.entry: 918; CHECK-NEXT: BRANCH-ON-MASK ir<%c> 919; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 920; CHECK-EMPTY: 921; CHECK-NEXT: pred.store.if: 922; CHECK-NEXT: REPLICATE ir<%l1> = load ir<%src> 923; CHECK-NEXT: REPLICATE ir<%l2> = trunc ir<%l1> 924; CHECK-NEXT: REPLICATE ir<%cmp> = icmp eq ir<%l1>, ir<0> 925; CHECK-NEXT: REPLICATE ir<%sel> = select ir<%cmp>, ir<5>, ir<%l2> 926; CHECK-NEXT: REPLICATE store ir<%sel>, ir<%dst> 927; CHECK-NEXT: Successor(s): pred.store.continue 928; CHECK-EMPTY: 929; CHECK-NEXT: pred.store.continue: 930; CHECK-NEXT: No successors 931; CHECK-NEXT: } 932; CHECK-NEXT: Successor(s): loop.then.1 933; CHECK-EMPTY: 934; CHECK-NEXT: loop.then.1: 935; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 936; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 937; CHECK-NEXT: No successors 938; CHECK-NEXT: } 939; 940entry: 941 br label %loop.header 942 943loop.header: 944 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 945 br i1 %c, label %loop.then, label %loop.latch 946 947loop.then: 948 %l1 = load i16, ptr %src, align 2 949 %l2 = trunc i16 %l1 to i8 950 %cmp = icmp eq i16 %l1, 0 951 %sel = select i1 %cmp, i8 5, i8 %l2 952 store i8 %sel, ptr %dst, align 1 953 %sext.l1 = sext i16 %l1 to i32 954 br label %loop.latch 955 956loop.latch: 957 %iv.next = add nsw i64 %iv, 1 958 %ec = icmp eq i64 %iv.next, 999 959 br i1 %ec, label %exit, label %loop.header 960 961exit: 962 ret void 963} 964 965define void @sinking_requires_duplication(ptr %addr) { 966; CHECK-LABEL: LV: Checking a loop in 'sinking_requires_duplication' 967; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 968; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 969; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 970; CHECK-NEXT: Live-in ir<201> = original trip-count 971; CHECK-EMPTY: 972; CHECK-NEXT: ir-bb<entry>: 973; CHECK-NEXT: Successor(s): vector.ph 974; CHECK-EMPTY: 975; CHECK-NEXT: vector.ph: 976; CHECK-NEXT: Successor(s): vector loop 977; CHECK-EMPTY: 978; CHECK-NEXT: <x1> vector loop: { 979; CHECK-NEXT: vector.body: 980; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 981; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1> 982; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%addr>, vp<[[STEPS]]> 983; CHECK-NEXT: vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep> 984; CHECK-NEXT: WIDEN ir<%0> = load vp<[[VEC_PTR]]> 985; CHECK-NEXT: WIDEN ir<%pred> = fcmp oeq ir<%0>, ir<0.000000e+00> 986; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = not ir<%pred> 987; CHECK-NEXT: Successor(s): pred.store 988; CHECK-EMPTY: 989; CHECK-NEXT: <xVFxUF> pred.store: { 990; CHECK-NEXT: pred.store.entry: 991; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 992; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 993; CHECK-EMPTY: 994; CHECK-NEXT: pred.store.if: 995; CHECK-NEXT: REPLICATE ir<%gep>.1 = getelementptr ir<%addr>, vp<[[STEPS]]> 996; CHECK-NEXT: REPLICATE store ir<1.000000e+01>, ir<%gep>.1 997; CHECK-NEXT: Successor(s): pred.store.continue 998; CHECK-EMPTY: 999; CHECK-NEXT: pred.store.continue: 1000; CHECK-NEXT: No successors 1001; CHECK-NEXT: } 1002; CHECK-NEXT: Successor(s): then.0 1003; CHECK-EMPTY: 1004; CHECK-NEXT: then.0: 1005; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 1006; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 1007; CHECK-NEXT: No successors 1008; CHECK-NEXT: } 1009; 1010entry: 1011 br label %loop.header 1012 1013loop.header: 1014 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1015 %gep = getelementptr float, ptr %addr, i64 %iv 1016 %exitcond.not = icmp eq i64 %iv, 200 1017 br i1 %exitcond.not, label %exit, label %loop.body 1018 1019loop.body: 1020 %0 = load float, ptr %gep, align 4 1021 %pred = fcmp oeq float %0, 0.0 1022 br i1 %pred, label %loop.latch, label %then 1023 1024then: 1025 store float 10.0, ptr %gep, align 4 1026 br label %loop.latch 1027 1028loop.latch: 1029 %iv.next = add nuw nsw i64 %iv, 1 1030 br label %loop.header 1031 1032exit: 1033 ret void 1034} 1035 1036; Test case with a dead GEP between the load and store regions. Dead recipes 1037; need to be removed before merging. 1038define void @merge_with_dead_gep_between_regions(i32 %n, ptr noalias %src, ptr noalias %dst) optsize { 1039; CHECK-LABEL: LV: Checking a loop in 'merge_with_dead_gep_between_regions' 1040; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 1041; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 1042; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 1043; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count 1044; CHECK-NEXT: Live-in ir<%n> = original trip-count 1045; CHECK-EMPTY: 1046; CHECK-NEXT: ir-bb<entry>: 1047; CHECK-NEXT: Successor(s): vector.ph 1048; CHECK-EMPTY: 1049; CHECK-NEXT: vector.ph: 1050; CHECK-NEXT: vp<[[END:%.+]]> = DERIVED-IV ir<%n> + vp<[[VEC_TC]]> * ir<-1> 1051; CHECK-NEXT: Successor(s): vector loop 1052; CHECK-EMPTY: 1053; CHECK-NEXT: <x1> vector loop: { 1054; CHECK-NEXT: vector.body: 1055; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 1056; CHECK-NEXT: vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<%n> + vp<[[CAN_IV]]> * ir<-1> 1057; CHECK-NEXT: EMIT vp<[[WIDE_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]> 1058; CHECK-NEXT: EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDE_IV]]>, vp<[[BTC]]> 1059; CHECK-NEXT: Successor(s): pred.store 1060; CHECK-EMPTY: 1061; CHECK-NEXT: <xVFxUF> pred.store: { 1062; CHECK-NEXT: pred.store.entry: 1063; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]> 1064; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 1065; CHECK-EMPTY: 1066; CHECK-NEXT: pred.store.if: 1067; CHECK-NEXT: vp<[[SCALAR_STEPS:%.+]]> = SCALAR-STEPS vp<[[DERIVED_IV]]>, ir<-1> 1068; CHECK-NEXT: REPLICATE ir<%gep.src> = getelementptr inbounds ir<%src>, vp<[[SCALAR_STEPS]]> 1069; CHECK-NEXT: REPLICATE ir<%l> = load ir<%gep.src> 1070; CHECK-NEXT: REPLICATE ir<%gep.dst> = getelementptr inbounds ir<%dst>, vp<[[SCALAR_STEPS]]> 1071; CHECK-NEXT: REPLICATE store ir<%l>, ir<%gep.dst> 1072; CHECK-NEXT: Successor(s): pred.store.continue 1073; CHECK-EMPTY: 1074; CHECK-NEXT: pred.store.continue: 1075; CHECK-NEXT: No successors 1076; CHECK-NEXT: } 1077; CHECK-NEXT: Successor(s): loop.1 1078; CHECK-EMPTY: 1079; CHECK-NEXT: loop.1: 1080; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add vp<[[CAN_IV]]>, vp<[[VFxUF]]> 1081; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 1082; CHECK-NEXT: No successors 1083; CHECK-NEXT: } 1084; CHECK-NEXT: Successor(s): middle.block 1085; CHECK-EMPTY: 1086; CHECK-NEXT: middle.block: 1087; CHECK-NEXT: EMIT branch-on-cond ir<true> 1088; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph 1089; CHECK-EMPTY: 1090; CHECK-NEXT: scalar.ph 1091; CHECK-NEXT: EMIT vp<[[RESUME:%.+]]> = resume-phi vp<[[END]]>, ir<%n> 1092; CHECK-NEXT: Successor(s): ir-bb<loop> 1093; CHECK-EMPTY: 1094; CHECK-NEXT: ir-bb<loop>: 1095; CHECK-NEXT: IR %iv = phi i32 [ %n, %entry ], [ %iv.next, %loop ] (extra operand: vp<[[RESUME]]> from scalar.ph) 1096; CHECK-NEXT: IR %iv.next = add nsw i32 %iv, -1 1097; CHECK-NEXT: IR %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv 1098; CHECK-NEXT: IR %l = load i32, ptr %gep.src, align 16 1099; CHECK-NEXT: IR %dead_gep = getelementptr inbounds i32, ptr %dst, i64 1 1100; CHECK-NEXT: IR %gep.dst = getelementptr inbounds i32, ptr %dst, i32 %iv 1101; CHECK-NEXT: IR store i32 %l, ptr %gep.dst, align 16 1102; CHECK-NEXT: IR %ec = icmp eq i32 %iv.next, 0 1103; CHECK-NEXT: No successors 1104; CHECK-EMPTY: 1105; CHECK-NEXT: ir-bb<exit> 1106; CHECK-NEXT: No successors 1107; CHECK-NEXT: } 1108; 1109entry: 1110 br label %loop 1111 1112loop: 1113 %iv = phi i32[ %n, %entry ], [ %iv.next, %loop ] 1114 %iv.next = add nsw i32 %iv, -1 1115 %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv 1116 %l = load i32, ptr %gep.src, align 16 1117 %dead_gep = getelementptr inbounds i32, ptr %dst, i64 1 1118 %gep.dst = getelementptr inbounds i32, ptr %dst, i32 %iv 1119 store i32 %l, ptr %gep.dst, align 16 1120 %ec = icmp eq i32 %iv.next, 0 1121 br i1 %ec, label %exit, label %loop 1122 1123exit: 1124 ret void 1125} 1126 1127define void @ptr_induction_remove_dead_recipe(ptr %start, ptr %end) { 1128; CHECK-LABEL: LV: Checking a loop in 'ptr_induction_remove_dead_recipe' 1129; CHECK: VPlan 'Initial VPlan for VF={2},UF>=1' { 1130; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF 1131; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF 1132; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count 1133; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count 1134; CHECK-EMPTY: 1135; CHECK-NEXT: ir-bb<entry>: 1136; CHECK-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV ((-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %start to i64)) 1137; CHECK-NEXT: Successor(s): vector.ph 1138; CHECK-EMPTY: 1139; CHECK-NEXT: vector.ph: 1140; CHECK-NEXT: vp<[[END:%.+]]> = DERIVED-IV ir<%start> + vp<[[VEC_TC]]> * ir<-1> 1141; CHECK-NEXT: Successor(s): vector loop 1142; CHECK-EMPTY: 1143; CHECK-NEXT: <x1> vector loop: { 1144; CHECK-NEXT: vector.body: 1145; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION 1146; CHECK-NEXT: vp<[[DEV_IV:%.+]]> = DERIVED-IV ir<0> + vp<[[CAN_IV]]> * ir<-1> 1147; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DEV_IV]]>, ir<-1> 1148; CHECK-NEXT: EMIT vp<[[PTR_IV:%.+]]> = ptradd ir<%start>, vp<[[STEPS]]> 1149; CHECK-NEXT: CLONE ir<%ptr.iv.next> = getelementptr inbounds vp<[[PTR_IV]]>, ir<-1> 1150; CHECK-NEXT: vp<[[VEC_PTR:%.+]]> = reverse-vector-pointer inbounds ir<%ptr.iv.next>, vp<[[VF]]> 1151; CHECK-NEXT: WIDEN ir<%l> = load vp<[[VEC_PTR]]> 1152; CHECK-NEXT: WIDEN ir<%c.1> = icmp eq ir<%l>, ir<0> 1153; CHECK-NEXT: EMIT vp<[[NEG:%.+]]> = not ir<%c.1> 1154; CHECK-NEXT: Successor(s): pred.store 1155; CHECK-EMPTY: 1156; CHECK-NEXT: <xVFxUF> pred.store: { 1157; CHECK-NEXT: pred.store.entry: 1158; CHECK-NEXT: BRANCH-ON-MASK vp<[[NEG]]> 1159; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue 1160; CHECK-EMPTY: 1161; CHECK-NEXT: pred.store.if: 1162; CHECK-NEXT: REPLICATE ir<%ptr.iv.next>.1 = getelementptr inbounds vp<[[PTR_IV]]>, ir<-1> 1163; CHECK-NEXT: REPLICATE store ir<95>, ir<%ptr.iv.next>.1 1164; CHECK-NEXT: Successor(s): pred.store.continue 1165; CHECK-EMPTY: 1166; CHECK-NEXT: pred.store.continue: 1167; CHECK-NEXT: No successors 1168; CHECK-NEXT: } 1169; CHECK-NEXT: Successor(s): if.then.0 1170; CHECK-EMPTY: 1171; CHECK-NEXT: if.then.0: 1172; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]> 1173; CHECK-NEXT: EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]> 1174; CHECK-NEXT: No successors 1175; CHECK-NEXT: } 1176; CHECK-NEXT: Successor(s): middle.block 1177; CHECK-EMPTY: 1178; CHECK-NEXT: middle.block: 1179; CHECK-NEXT: EMIT vp<[[CMP:%.+]]> = icmp eq vp<[[TC]]>, vp<[[VEC_TC]]> 1180; CHECK-NEXT: EMIT branch-on-cond vp<[[CMP]]> 1181; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph 1182; CHECK-EMPTY: 1183; CHECK-NEXT: scalar.ph: 1184; CHECK-NEXT: EMIT vp<[[RESUME:%.+]]> = resume-phi vp<[[END]]>, ir<%start> 1185; CHECK-NEXT: Successor(s): ir-bb<loop.header> 1186; CHECK-EMPTY: 1187; CHECK-NEXT: ir-bb<loop.header>: 1188; CHECK-NEXT: IR %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ] (extra operand: vp<[[RESUME]]> from scalar.ph) 1189; CHECK-NEXT: IR %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 -1 1190; CHECK-NEXT: IR %l = load i8, ptr %ptr.iv.next, align 1 1191; CHECK-NEXT: IR %c.1 = icmp eq i8 %l, 0 1192; CHECK-NEXT: No successors 1193; CHECK-EMPTY: 1194; CHECK-NEXT: ir-bb<exit>: 1195; CHECK-NEXT: No successors 1196; CHECK-NEXT: } 1197; 1198entry: 1199 br label %loop.header 1200 1201loop.header: 1202 %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ] 1203 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 -1 1204 %l = load i8, ptr %ptr.iv.next, align 1 1205 %c.1 = icmp eq i8 %l, 0 1206 br i1 %c.1, label %loop.latch, label %if.then 1207 1208if.then: 1209 store i8 95, ptr %ptr.iv.next, align 1 1210 br label %loop.latch 1211 1212loop.latch: 1213 %c.2 = icmp eq ptr %ptr.iv.next, %end 1214 br i1 %c.2, label %exit, label %loop.header 1215 1216exit: 1217 ret void 1218} 1219