| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 |
| |
| ; RUN: opt -passes=loop-vectorize -force-vector-interleave=2 -force-vector-width=1 -vplan-print-after="VPlanTransforms::replicateByVF$" -disable-output %s 2>&1 | FileCheck --check-prefix=SCALAR %s |
| ; RUN: opt -passes=loop-vectorize -force-vector-interleave=2 -force-vector-width=2 -vplan-print-after="VPlanTransforms::replicateByVF$" -disable-output %s 2>&1 | FileCheck --check-prefix=VECTOR %s |
| |
| define void @predicated_load(i1 %c, ptr %ptr, ptr %dst) { |
| ; SCALAR-LABEL: VPlan for loop in 'predicated_load' |
| ; SCALAR: VPlan 'Initial VPlan for VF={1},UF={2}' { |
| ; SCALAR-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF |
| ; SCALAR-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF |
| ; SCALAR-NEXT: Live-in ir<1024> = vector-trip-count |
| ; SCALAR-NEXT: Live-in ir<1024> = original trip-count |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: ir-bb<entry>: |
| ; SCALAR-NEXT: EMIT branch-on-cond ir<false> |
| ; SCALAR-NEXT: Successor(s): scalar.ph, vector.ph |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: vector.ph: |
| ; SCALAR-NEXT: Successor(s): vector loop |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: <x1> vector loop: { |
| ; SCALAR-NEXT: vector.body: |
| ; SCALAR-NEXT: EMIT vp<[[VP3:%[0-9]+]]> = CANONICAL-INDUCTION ir<0>, vp<%index.next> |
| ; SCALAR-NEXT: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3]]>, ir<1>, vp<[[VP0]]> |
| ; SCALAR-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3]]>, ir<1>, vp<[[VP0]]>, vp<[[VP0]]> |
| ; SCALAR-NEXT: EMIT branch-on-cond ir<%c> |
| ; SCALAR-NEXT: Successor(s): pred.load.if, pred.load.continue |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: pred.load.if: |
| ; SCALAR-NEXT: CLONE ir<%gep> = getelementptr ir<%ptr>, vp<[[VP4]]> |
| ; SCALAR-NEXT: CLONE ir<%lv> = load ir<%gep> |
| ; SCALAR-NEXT: Successor(s): pred.load.continue |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: pred.load.continue: |
| ; SCALAR-NEXT: EMIT-SCALAR vp<[[VP7:%[0-9]+]]> = phi [ ir<poison>, vector.body ], [ ir<%lv>, pred.load.if ] |
| ; SCALAR-NEXT: EMIT branch-on-cond ir<%c> |
| ; SCALAR-NEXT: Successor(s): pred.load.if, pred.load.continue |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: pred.load.if: |
| ; SCALAR-NEXT: CLONE ir<%gep>.1 = getelementptr ir<%ptr>, vp<[[VP5]]> |
| ; SCALAR-NEXT: CLONE ir<%lv>.1 = load ir<%gep>.1 |
| ; SCALAR-NEXT: Successor(s): pred.load.continue |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: pred.load.continue: |
| ; SCALAR-NEXT: EMIT-SCALAR vp<[[VP9:%[0-9]+]]> = phi [ ir<poison>, pred.load.continue ], [ ir<%lv>.1, pred.load.if ] |
| ; SCALAR-NEXT: BLEND ir<%pred.val> = ir<0> vp<%7>/ir<%c> |
| ; SCALAR-NEXT: BLEND ir<%pred.val>.1 = ir<0> vp<%9>/ir<%c> |
| ; SCALAR-NEXT: CLONE ir<%gep.dst> = getelementptr ir<%dst>, vp<[[VP4]]> |
| ; SCALAR-NEXT: CLONE ir<%gep.dst>.1 = getelementptr ir<%dst>, vp<[[VP5]]> |
| ; SCALAR-NEXT: CLONE store ir<%pred.val>, ir<%gep.dst> |
| ; SCALAR-NEXT: CLONE store ir<%pred.val>.1, ir<%gep.dst>.1 |
| ; SCALAR-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]> |
| ; SCALAR-NEXT: EMIT branch-on-count vp<%index.next>, ir<1024> |
| ; SCALAR-NEXT: No successors |
| ; SCALAR-NEXT: } |
| ; SCALAR-NEXT: Successor(s): middle.block |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: middle.block: |
| ; SCALAR-NEXT: EMIT vp<%cmp.n> = icmp eq ir<1024>, ir<1024> |
| ; SCALAR-NEXT: EMIT branch-on-cond vp<%cmp.n> |
| ; SCALAR-NEXT: Successor(s): ir-bb<exit>, scalar.ph |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: ir-bb<exit>: |
| ; SCALAR-NEXT: No successors |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: scalar.ph: |
| ; SCALAR-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ ir<1024>, middle.block ], [ ir<0>, ir-bb<entry> ] |
| ; SCALAR-NEXT: Successor(s): ir-bb<loop.header> |
| ; SCALAR-EMPTY: |
| ; SCALAR-NEXT: ir-bb<loop.header>: |
| ; SCALAR-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] (extra operand: vp<%bc.resume.val> from scalar.ph) |
| ; SCALAR-NEXT: IR %gep = getelementptr i8, ptr %ptr, i64 %iv |
| ; SCALAR-NEXT: No successors |
| ; SCALAR-NEXT: } |
| ; |
| ; VECTOR-LABEL: VPlan for loop in 'predicated_load' |
| ; VECTOR: VPlan 'Initial VPlan for VF={2},UF={2}' { |
| ; VECTOR-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF |
| ; VECTOR-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF |
| ; VECTOR-NEXT: Live-in ir<1024> = vector-trip-count |
| ; VECTOR-NEXT: Live-in ir<1024> = original trip-count |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: ir-bb<entry>: |
| ; VECTOR-NEXT: EMIT branch-on-cond ir<false> |
| ; VECTOR-NEXT: Successor(s): scalar.ph, vector.ph |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: vector.ph: |
| ; VECTOR-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = broadcast ir<%c> |
| ; VECTOR-NEXT: Successor(s): vector loop |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: <x1> vector loop: { |
| ; VECTOR-NEXT: vector.body: |
| ; VECTOR-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = CANONICAL-INDUCTION ir<0>, vp<%index.next> |
| ; VECTOR-NEXT: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1>, vp<[[VP0]]> |
| ; VECTOR-NEXT: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1>, vp<[[VP0]]>, ir<1> |
| ; VECTOR-NEXT: Successor(s): pred.load |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: <xVFxUF> pred.load: { |
| ; VECTOR-NEXT: pred.load.entry: |
| ; VECTOR-NEXT: BRANCH-ON-MASK ir<%c> |
| ; VECTOR-NEXT: Successor(s): pred.load.if, pred.load.continue |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: pred.load.if: |
| ; VECTOR-NEXT: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1>, vp<[[VP0]]> |
| ; VECTOR-NEXT: REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[VP8]]> |
| ; VECTOR-NEXT: REPLICATE ir<%lv> = load ir<%gep> (S->V) |
| ; VECTOR-NEXT: Successor(s): pred.load.continue |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: pred.load.continue: |
| ; VECTOR-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[VP9:%[0-9]+]]> = ir<%lv> |
| ; VECTOR-NEXT: No successors |
| ; VECTOR-NEXT: } |
| ; VECTOR-NEXT: Successor(s): pred.load |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: <xVFxUF> pred.load: { |
| ; VECTOR-NEXT: pred.load.entry: |
| ; VECTOR-NEXT: BRANCH-ON-MASK ir<%c> |
| ; VECTOR-NEXT: Successor(s): pred.load.if, pred.load.continue |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: pred.load.if: |
| ; VECTOR-NEXT: vp<[[VP10:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1>, vp<[[VP0]]>, vp<[[VP0]]> |
| ; VECTOR-NEXT: REPLICATE ir<%gep>.1 = getelementptr ir<%ptr>, vp<[[VP10]]> |
| ; VECTOR-NEXT: REPLICATE ir<%lv>.1 = load ir<%gep>.1 (S->V) |
| ; VECTOR-NEXT: Successor(s): pred.load.continue |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: pred.load.continue: |
| ; VECTOR-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[VP11:%[0-9]+]]> = ir<%lv>.1 |
| ; VECTOR-NEXT: No successors |
| ; VECTOR-NEXT: } |
| ; VECTOR-NEXT: Successor(s): if.then.0 |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: if.then.0: |
| ; VECTOR-NEXT: BLEND ir<%pred.val> = ir<0> vp<%9>/vp<[[VP4]]> |
| ; VECTOR-NEXT: BLEND ir<%pred.val>.1 = ir<0> vp<%11>/vp<[[VP4]]> |
| ; VECTOR-NEXT: CLONE ir<%gep.dst> = getelementptr ir<%dst>, vp<[[VP6]]> |
| ; VECTOR-NEXT: EMIT vp<[[VP12:%[0-9]+]]> = mul nuw nsw vp<[[VP0]]>, ir<1> |
| ; VECTOR-NEXT: vp<[[VP13:%[0-9]+]]> = vector-pointer ir<%gep.dst> |
| ; VECTOR-NEXT: vp<[[VP14:%[0-9]+]]> = vector-pointer ir<%gep.dst>, vp<[[VP12]]> |
| ; VECTOR-NEXT: WIDEN store vp<[[VP13]]>, ir<%pred.val> |
| ; VECTOR-NEXT: WIDEN store vp<[[VP14]]>, ir<%pred.val>.1 |
| ; VECTOR-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP5]]>, vp<[[VP1]]> |
| ; VECTOR-NEXT: EMIT branch-on-count vp<%index.next>, ir<1024> |
| ; VECTOR-NEXT: No successors |
| ; VECTOR-NEXT: } |
| ; VECTOR-NEXT: Successor(s): middle.block |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: middle.block: |
| ; VECTOR-NEXT: EMIT vp<%cmp.n> = icmp eq ir<1024>, ir<1024> |
| ; VECTOR-NEXT: EMIT branch-on-cond vp<%cmp.n> |
| ; VECTOR-NEXT: Successor(s): ir-bb<exit>, scalar.ph |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: ir-bb<exit>: |
| ; VECTOR-NEXT: No successors |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: scalar.ph: |
| ; VECTOR-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ ir<1024>, middle.block ], [ ir<0>, ir-bb<entry> ] |
| ; VECTOR-NEXT: Successor(s): ir-bb<loop.header> |
| ; VECTOR-EMPTY: |
| ; VECTOR-NEXT: ir-bb<loop.header>: |
| ; VECTOR-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] (extra operand: vp<%bc.resume.val> from scalar.ph) |
| ; VECTOR-NEXT: IR %gep = getelementptr i8, ptr %ptr, i64 %iv |
| ; VECTOR-NEXT: No successors |
| ; VECTOR-NEXT: } |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] |
| %gep = getelementptr i8, ptr %ptr, i64 %iv |
| br i1 %c, label %if.then, label %loop.latch |
| |
| if.then: |
| %lv = load i8, ptr %gep, align 1 |
| br label %loop.latch |
| |
| loop.latch: |
| %pred.val = phi i8 [ 0, %loop.header ], [ %lv, %if.then ] |
| %gep.dst = getelementptr i8, ptr %dst, i64 %iv |
| store i8 %pred.val, ptr %gep.dst, align 1 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %cmp = icmp eq i64 %iv.next, 1024 |
| br i1 %cmp, label %exit, label %loop.header |
| |
| exit: |
| ret void |
| } |