blob: 673c8f9e561425f5fdb7e08d9e5da59673fd30ea [file]
; 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
}