| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "scalar.ph:" --version 6 |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -disable-output -vplan-print-after=makeCallWideningDecisions %s 2>&1 | FileCheck --strict-whitespace %s |
| |
| target triple = "arm64-apple-macosx" |
| |
| declare double @acos(double) |
| declare <2 x double> @vec_acos(<2 x double>) |
| |
| define void @wide_call_attrs(ptr noalias %in.ptr, ptr noalias %out.ptr) { |
| ; CHECK-LABEL: VPlan for loop in 'wide_call_attrs' |
| ; CHECK: VPlan ' for UF>=1' { |
| ; 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<1000> = original trip-count |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<entry>: |
| ; CHECK-NEXT: Successor(s): scalar.ph, vector.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.ph: |
| ; CHECK-NEXT: Successor(s): vector loop |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <x1> vector loop: { |
| ; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.body: |
| ; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0]]> |
| ; CHECK-NEXT: CLONE ir<%in.gep> = getelementptr inbounds ir<%in.ptr>, ir<%iv> |
| ; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = vector-pointer inbounds double, ir<%in.gep>, ir<1> |
| ; CHECK-NEXT: WIDEN ir<%in> = load vp<[[VP4]]> |
| ; CHECK-NEXT: WIDEN-CALL ir<%call> = call @acos(ir<%in>) (using library function: vec_acos) |
| ; CHECK-NEXT: CLONE ir<%out.gep> = getelementptr inbounds ir<%out.ptr>, ir<%iv> |
| ; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds double, ir<%out.gep>, ir<1> |
| ; CHECK-NEXT: WIDEN store vp<[[VP5]]>, ir<%call> |
| ; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1> |
| ; CHECK-NEXT: CLONE ir<%exitcond> = icmp eq ir<%iv.next>, ir<1000> |
| ; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, 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: |
| ; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = exiting-iv-value ir<%iv> |
| ; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<1000>, vp<[[VP2]]> |
| ; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n> |
| ; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<exit>: |
| ; CHECK-NEXT: No successors |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: scalar.ph: |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %in.gep = getelementptr inbounds double, ptr %in.ptr, i64 %iv |
| %in = load double, ptr %in.gep, align 8 |
| %call = tail call nofpclass(nan) double @acos(double nofpclass(inf) %in) #0 |
| %out.gep = getelementptr inbounds double, ptr %out.ptr, i64 %iv |
| store double %call, ptr %out.gep, align 8 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %exitcond = icmp eq i64 %iv.next, 1000 |
| br i1 %exitcond, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| define void @test_intrinsic_with_arg_and_ret_attrs(ptr noalias %A, ptr noalias %B, i32 %n) { |
| ; CHECK-LABEL: VPlan for loop in 'test_intrinsic_with_arg_and_ret_attrs' |
| ; CHECK: VPlan ' for UF>=1' { |
| ; 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: Successor(s): scalar.ph, vector.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.ph: |
| ; CHECK-NEXT: Successor(s): vector loop |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: <x1> vector loop: { |
| ; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.body: |
| ; CHECK-NEXT: ir<%i> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0]]> |
| ; CHECK-NEXT: CLONE ir<%gep.A> = getelementptr inbounds ir<%A>, ir<%i> |
| ; CHECK-NEXT: CLONE ir<%gep.B> = getelementptr inbounds ir<%B>, ir<%i> |
| ; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = vector-pointer inbounds float, ir<%gep.A>, ir<1> |
| ; CHECK-NEXT: WIDEN ir<%a> = load vp<[[VP4]]> |
| ; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds float, ir<%gep.B>, ir<1> |
| ; CHECK-NEXT: WIDEN ir<%b> = load vp<[[VP5]]> |
| ; CHECK-NEXT: WIDEN-INTRINSIC ir<%m> = call llvm.minnum(ir<%a>, ir<%b>) |
| ; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer inbounds float, ir<%gep.A>, ir<1> |
| ; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%m> |
| ; CHECK-NEXT: EMIT ir<%i.next> = add ir<%i>, ir<1> |
| ; CHECK-NEXT: CLONE ir<%cond> = icmp eq ir<%i.next>, ir<%n> |
| ; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, 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: |
| ; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = exiting-iv-value ir<%i> |
| ; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%n>, vp<[[VP2]]> |
| ; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n> |
| ; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<exit>: |
| ; CHECK-NEXT: No successors |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: scalar.ph: |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] |
| %gep.A = getelementptr inbounds float, ptr %A, i32 %i |
| %gep.B = getelementptr inbounds float, ptr %B, i32 %i |
| %a = load float, ptr %gep.A |
| %b = load float, ptr %gep.B |
| %m = call nofpclass(nan) float @llvm.minnum.f32(float nofpclass(nan) %a, float nofpclass(nan) %b) |
| store float %m, ptr %gep.A |
| %i.next = add i32 %i, 1 |
| %cond = icmp eq i32 %i.next, %n |
| br i1 %cond, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| attributes #0 = { "vector-function-abi-variant"="_ZGVnN2v_acos(vec_acos)" } |