| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "middle.block:" --version 6 |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=2 \ |
| ; RUN: -vplan-print-after=unrollByUF -disable-output %s 2>&1 \ |
| ; RUN: | FileCheck --strict-whitespace %s |
| |
| define void @cast_flags_mixed(ptr noalias %A, ptr noalias %B) { |
| ; CHECK-LABEL: VPlan for loop in 'cast_flags_mixed' |
| ; CHECK: VPlan 'Initial VPlan for VF={4},UF={2}' { |
| ; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF |
| ; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF |
| ; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count |
| ; CHECK-NEXT: Live-in vp<[[VP3:%[0-9]+]]> = backedge-taken count |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<entry>: |
| ; CHECK-NEXT: EMIT branch-on-cond ir<false> |
| ; CHECK-NEXT: Successor(s): scalar.ph, vector.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.ph: |
| ; CHECK-NEXT: CLONE ir<%gep.zext> = getelementptr ir<%A>, ir<3> |
| ; CHECK-NEXT: CLONE ir<%gep.trunc> = getelementptr ir<%B>, ir<3> |
| ; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = wide-iv-step vp<[[VP0]]>, ir<1> |
| ; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = wide-iv-step vp<[[VP0]]>, ir<1> |
| ; CHECK-NEXT: Successor(s): vector loop |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <x1> vector loop: { |
| ; CHECK-NEXT: vp<[[VP7:%[0-9]+]]> = CANONICAL-IV |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.body: |
| ; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nsw ir<0>, ir<1>, vp<[[VP0]]>, vp<[[VP5]]>, vp<%step.add> |
| ; CHECK-NEXT: vp<[[VP9:%[0-9]+]]> = WIDEN-INDUCTION nuw ir<0>, ir<1>, vp<[[VP0]]>, vp<[[VP6]]>, vp<%step.add>.1 |
| ; CHECK-NEXT: EMIT vp<%step.add> = add nsw ir<%iv>, vp<[[VP5]]> |
| ; CHECK-NEXT: EMIT vp<%step.add>.1 = add nuw vp<[[VP9]]>, vp<[[VP6]]> |
| ; CHECK-NEXT: EMIT vp<[[VP10:%[0-9]+]]> = icmp ule vp<[[VP9]]>, vp<[[VP3]]> |
| ; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = icmp ule vp<%step.add>.1, vp<[[VP3]]> |
| ; CHECK-NEXT: WIDEN-CAST ir<%sext.plain> = sext ir<%iv> to i64 |
| ; CHECK-NEXT: WIDEN-CAST ir<%sext.plain>.1 = sext vp<%step.add> to i64 |
| ; CHECK-NEXT: Successor(s): pred.store |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <xVFxUF> pred.store: { |
| ; CHECK-NEXT: pred.store.entry: |
| ; CHECK-NEXT: BRANCH-ON-MASK vp<[[VP10]]> |
| ; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.if: |
| ; CHECK-NEXT: REPLICATE ir<%gep.sext> = getelementptr ir<%A>, ir<%sext.plain> |
| ; CHECK-NEXT: REPLICATE store ir<%gep.sext>, ir<%gep.zext> |
| ; CHECK-NEXT: Successor(s): pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.continue: |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): pred.store |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <xVFxUF> pred.store: { |
| ; CHECK-NEXT: pred.store.entry: |
| ; CHECK-NEXT: BRANCH-ON-MASK vp<[[VP11]]> |
| ; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.if: |
| ; CHECK-NEXT: REPLICATE ir<%gep.sext>.1 = getelementptr ir<%A>, ir<%sext.plain>.1 |
| ; CHECK-NEXT: REPLICATE store ir<%gep.sext>.1, ir<%gep.zext> |
| ; CHECK-NEXT: Successor(s): pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.continue: |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): loop.0 |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: loop.0: |
| ; CHECK-NEXT: CLONE store ir<0>, ir<%gep.trunc> |
| ; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP7]]>, vp<[[VP1]]> |
| ; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]> |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): middle.block |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: middle.block: |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ] |
| %zext.nneg = zext nneg i16 3 to i64 |
| %gep.zext = getelementptr ptr, ptr %A, i64 %zext.nneg |
| %sext.plain = sext i16 %iv to i64 |
| %gep.sext = getelementptr [4 x ptr], ptr %A, i64 %sext.plain |
| %trunc.flags = trunc nuw nsw i16 3 to i8 |
| %gep.trunc = getelementptr [4 x i8], ptr %B, i8 %trunc.flags |
| store ptr %gep.sext, ptr %gep.zext |
| store i8 0, ptr %gep.trunc |
| %iv.next = add nsw i16 %iv, 1 |
| %ec = icmp slt i16 %iv.next, 4 |
| br i1 %ec, label %loop, label %exit |
| |
| exit: |
| ret void |
| } |
| |
| define void @cast_flags_single(ptr noalias %A, ptr noalias %B) { |
| ; CHECK-LABEL: VPlan for loop in 'cast_flags_single' |
| ; CHECK: VPlan 'Initial VPlan for VF={4},UF={2}' { |
| ; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF |
| ; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF |
| ; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count |
| ; CHECK-NEXT: Live-in vp<[[VP3:%[0-9]+]]> = backedge-taken count |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<entry>: |
| ; CHECK-NEXT: EMIT branch-on-cond ir<false> |
| ; CHECK-NEXT: Successor(s): scalar.ph, vector.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.ph: |
| ; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = wide-iv-step vp<[[VP0]]>, ir<1> |
| ; CHECK-NEXT: Successor(s): vector loop |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <x1> vector loop: { |
| ; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = CANONICAL-IV |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.body: |
| ; CHECK-NEXT: vp<[[VP8:%[0-9]+]]> = WIDEN-INDUCTION nuw ir<0>, ir<1>, vp<[[VP0]]>, vp<[[VP5]]>, vp<%step.add> |
| ; CHECK-NEXT: EMIT vp<%step.add> = add nuw vp<[[VP8]]>, vp<[[VP5]]> |
| ; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = icmp ule vp<[[VP8]]>, vp<[[VP3]]> |
| ; CHECK-NEXT: EMIT vp<[[VP10:%[0-9]+]]> = icmp ule vp<%step.add>, vp<[[VP3]]> |
| ; CHECK-NEXT: vp<[[VP11:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP6]]> * ir<1> |
| ; CHECK-NEXT: Successor(s): pred.store |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <xVFxUF> pred.store: { |
| ; CHECK-NEXT: pred.store.entry: |
| ; CHECK-NEXT: BRANCH-ON-MASK vp<[[VP9]]> |
| ; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.if: |
| ; CHECK-NEXT: vp<[[VP12:%[0-9]+]]> = SCALAR-STEPS vp<[[VP11]]>, ir<1>, vp<[[VP0]]> |
| ; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr ir<%A>, vp<[[VP12]]> |
| ; CHECK-NEXT: REPLICATE store ir<3>, ir<%gep.a> |
| ; CHECK-NEXT: REPLICATE store ir<3>, ir<%gep.a> |
| ; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<%B>, vp<[[VP12]]> |
| ; CHECK-NEXT: REPLICATE store ir<3>, ir<%gep.b> |
| ; CHECK-NEXT: Successor(s): pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.continue: |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): pred.store |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <xVFxUF> pred.store: { |
| ; CHECK-NEXT: pred.store.entry: |
| ; CHECK-NEXT: BRANCH-ON-MASK vp<[[VP10]]> |
| ; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.if: |
| ; CHECK-NEXT: EMIT-SCALAR vp<[[VP13:%[0-9]+]]> = trunc vp<[[VP0]]> to i16 |
| ; CHECK-NEXT: vp<[[VP14:%[0-9]+]]> = SCALAR-STEPS vp<[[VP11]]>, ir<1>, vp<[[VP0]]>, vp<[[VP13]]> |
| ; CHECK-NEXT: REPLICATE ir<%gep.a>.1 = getelementptr ir<%A>, vp<[[VP14]]> |
| ; CHECK-NEXT: REPLICATE store ir<3>, ir<%gep.a>.1 |
| ; CHECK-NEXT: REPLICATE store ir<3>, ir<%gep.a>.1 |
| ; CHECK-NEXT: REPLICATE ir<%gep.b>.1 = getelementptr ir<%B>, vp<[[VP14]]> |
| ; CHECK-NEXT: REPLICATE store ir<3>, ir<%gep.b>.1 |
| ; CHECK-NEXT: Successor(s): pred.store.continue |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: pred.store.continue: |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): loop.2 |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: loop.2: |
| ; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP6]]>, vp<[[VP1]]> |
| ; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]> |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): middle.block |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: middle.block: |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ] |
| %trunc.nuw.only = trunc nuw i16 3 to i8 |
| %trunc.nsw.only = trunc nsw i16 3 to i8 |
| %zext.plain = zext i16 3 to i64 |
| %gep.a = getelementptr i8, ptr %A, i16 %iv |
| %gep.b = getelementptr i64, ptr %B, i16 %iv |
| store i8 %trunc.nuw.only, ptr %gep.a |
| store i8 %trunc.nsw.only, ptr %gep.a |
| store i64 %zext.plain, ptr %gep.b |
| %iv.next = add nsw i16 %iv, 1 |
| %ec = icmp slt i16 %iv.next, 4 |
| br i1 %ec, label %loop, label %exit |
| |
| exit: |
| ret void |
| } |
| |
| define void @fpiv_wideivstep_flags(float %init, ptr %p, i64 %n) { |
| ; CHECK-LABEL: VPlan for loop in 'fpiv_wideivstep_flags' |
| ; CHECK: VPlan 'Initial VPlan for VF={4},UF={2}' { |
| ; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF |
| ; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF |
| ; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count |
| ; CHECK-NEXT: Live-in ir<%n> = original trip-count |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<entry>: |
| ; CHECK-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%n>, ir<8> |
| ; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check> |
| ; CHECK-NEXT: Successor(s): scalar.ph, vector.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.ph: |
| ; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%init> + vp<[[VP2]]> * ir<1.000000e+00> |
| ; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = wide-iv-step fast vp<[[VP0]]>, ir<1.000000e+00> |
| ; CHECK-NEXT: Successor(s): vector loop |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <x1> vector loop: { |
| ; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = CANONICAL-IV |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.body: |
| ; CHECK-NEXT: ir<%x> = WIDEN-INDUCTION fast ir<%init>, ir<1.000000e+00>, vp<[[VP0]]>, vp<[[VP5]]>, vp<%step.add> |
| ; CHECK-NEXT: EMIT vp<%step.add> = fadd fast ir<%x>, vp<[[VP5]]> |
| ; CHECK-NEXT: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<1>, vp<[[VP0]]> |
| ; CHECK-NEXT: CLONE ir<%arrayidx> = getelementptr inbounds ir<%p>, vp<[[VP7]]> |
| ; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = mul nuw nsw vp<[[VP0]]>, ir<1> |
| ; CHECK-NEXT: vp<[[VP9:%[0-9]+]]> = vector-pointer inbounds float, ir<%arrayidx>, ir<1> |
| ; CHECK-NEXT: vp<[[VP10:%[0-9]+]]> = vector-pointer inbounds float, ir<%arrayidx>, ir<1>, vp<[[VP8]]> |
| ; CHECK-NEXT: WIDEN store vp<[[VP9]]>, ir<%x> |
| ; CHECK-NEXT: WIDEN store vp<[[VP10]]>, vp<%step.add> |
| ; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP6]]>, vp<[[VP1]]> |
| ; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]> |
| ; CHECK-NEXT: No successors |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: Successor(s): middle.block |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: middle.block: |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %x = phi float [ %init, %entry ], [ %add, %loop ] |
| %arrayidx = getelementptr inbounds float, ptr %p, i64 %iv |
| store float %x, ptr %arrayidx, align 4 |
| %add = fadd fast float %x, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |