| ; 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 | |
| } |