blob: 4e96d743722da736c4bac80eb2932be9b5f57bd5 [file]
; 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 -mattr=+neon,+dotprod -force-vector-interleave=1 -vplan-print-after="optimize$" \
; RUN: -force-vector-width=16 -disable-output 2>&1 < %s | FileCheck %s
target triple = "aarch64-none-unknown-elf"
define i32 @unsigned_absolute_difference(ptr noalias %x, ptr noalias %y) {
; CHECK-LABEL: VPlan for loop in 'unsigned_absolute_difference'
; CHECK: VPlan 'Initial VPlan for VF={16},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<8000> = 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: EMIT vp<[[VP3:%[0-9]+]]> = reduction-start-vector ir<0>, ir<0>, ir<4>
; CHECK-NEXT: Successor(s): vector loop
; CHECK-EMPTY:
; CHECK-NEXT: <x1> vector loop: {
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%sum.0> = phi (add) vp<[[VP3]]>, vp<[[VP13:%[0-9]+]]> (VF scaled by 1/4)
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%x.ptr> = getelementptr inbounds nuw ir<%x>, vp<[[VP5]]>
; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer inbounds nuw i8, ir<%x.ptr>, ir<1>
; CHECK-NEXT: WIDEN ir<%x.val> = load vp<[[VP6]]>
; CHECK-NEXT: CLONE ir<%y.ptr> = getelementptr inbounds nuw ir<%y>, vp<[[VP5]]>
; CHECK-NEXT: vp<[[VP7:%[0-9]+]]> = vector-pointer inbounds nuw i8, ir<%y.ptr>, ir<1>
; CHECK-NEXT: WIDEN ir<%y.val> = load vp<[[VP7]]>
; CHECK-NEXT: WIDEN vp<[[VP8:%[0-9]+]]> = freeze ir<%x.val>
; CHECK-NEXT: WIDEN vp<[[VP9:%[0-9]+]]> = freeze ir<%y.val>
; CHECK-NEXT: WIDEN-INTRINSIC vp<[[VP10:%[0-9]+]]> = call llvm.umax(vp<[[VP8]]>, vp<[[VP9]]>)
; CHECK-NEXT: WIDEN-INTRINSIC vp<[[VP11:%[0-9]+]]> = call llvm.umin(vp<[[VP8]]>, vp<[[VP9]]>)
; CHECK-NEXT: WIDEN vp<[[VP12:%[0-9]+]]> = sub vp<[[VP10]]>, vp<[[VP11]]>
; CHECK-NEXT: EXPRESSION vp<[[VP13]]> = ir<%sum.0> + partial.reduce.add (vp<[[VP12]]> zext to i32)
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, 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<[[VP15:%[0-9]+]]> = compute-reduction-result (add) vp<[[VP13]]>
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<8000>, 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: IR %sum.1.lcssa = phi i32 [ %sum.1, %for.body ] (extra operand: vp<[[VP15]]> from middle.block)
; CHECK-NEXT: No successors
; CHECK-EMPTY:
; CHECK-NEXT: scalar.ph:
;
entry:
br label %for.body
for.body:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
%sum.0 = phi i32 [ 0, %entry ], [ %sum.1, %for.body ]
%x.ptr = getelementptr inbounds nuw i8, ptr %x, i64 %iv
%x.val = load i8, ptr %x.ptr, align 1
%ext.x = zext i8 %x.val to i32
%y.ptr = getelementptr inbounds nuw i8, ptr %y, i64 %iv
%y.val = load i8, ptr %y.ptr, align 1
%ext.y = zext i8 %y.val to i32
%sub = sub nsw i32 %ext.x, %ext.y
%abs.diff = tail call i32 @llvm.abs.i32(i32 %sub, i1 true)
%sum.1 = add nuw nsw i32 %abs.diff, %sum.0
%iv.next = add nuw nsw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, 8000
br i1 %exitcond.not, label %exit, label %for.body
exit:
ret i32 %sum.1
}
define i32 @signed_absolute_difference(ptr noalias %x, ptr noalias %y) {
; CHECK-LABEL: VPlan for loop in 'signed_absolute_difference'
; CHECK: VPlan 'Initial VPlan for VF={16},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<8000> = 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: EMIT vp<[[VP3:%[0-9]+]]> = reduction-start-vector ir<0>, ir<0>, ir<4>
; CHECK-NEXT: Successor(s): vector loop
; CHECK-EMPTY:
; CHECK-NEXT: <x1> vector loop: {
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%sum.0> = phi (add) vp<[[VP3]]>, vp<[[VP13:%[0-9]+]]> (VF scaled by 1/4)
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%x.ptr> = getelementptr inbounds nuw ir<%x>, vp<[[VP5]]>
; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer inbounds nuw i8, ir<%x.ptr>, ir<1>
; CHECK-NEXT: WIDEN ir<%x.val> = load vp<[[VP6]]>
; CHECK-NEXT: CLONE ir<%y.ptr> = getelementptr inbounds nuw ir<%y>, vp<[[VP5]]>
; CHECK-NEXT: vp<[[VP7:%[0-9]+]]> = vector-pointer inbounds nuw i8, ir<%y.ptr>, ir<1>
; CHECK-NEXT: WIDEN ir<%y.val> = load vp<[[VP7]]>
; CHECK-NEXT: WIDEN vp<[[VP8:%[0-9]+]]> = freeze ir<%x.val>
; CHECK-NEXT: WIDEN vp<[[VP9:%[0-9]+]]> = freeze ir<%y.val>
; CHECK-NEXT: WIDEN-INTRINSIC vp<[[VP10:%[0-9]+]]> = call llvm.smax(vp<[[VP8]]>, vp<[[VP9]]>)
; CHECK-NEXT: WIDEN-INTRINSIC vp<[[VP11:%[0-9]+]]> = call llvm.smin(vp<[[VP8]]>, vp<[[VP9]]>)
; CHECK-NEXT: WIDEN vp<[[VP12:%[0-9]+]]> = sub vp<[[VP10]]>, vp<[[VP11]]>
; CHECK-NEXT: EXPRESSION vp<[[VP13]]> = ir<%sum.0> + partial.reduce.add (vp<[[VP12]]> zext to i32)
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, 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<[[VP15:%[0-9]+]]> = compute-reduction-result (add) vp<[[VP13]]>
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<8000>, 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: IR %sum.1.lcssa = phi i32 [ %sum.1, %for.body ] (extra operand: vp<[[VP15]]> from middle.block)
; CHECK-NEXT: No successors
; CHECK-EMPTY:
; CHECK-NEXT: scalar.ph:
;
entry:
br label %for.body
for.body:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
%sum.0 = phi i32 [ 0, %entry ], [ %sum.1, %for.body ]
%x.ptr = getelementptr inbounds nuw i8, ptr %x, i64 %iv
%x.val = load i8, ptr %x.ptr, align 1
%ext.x = sext i8 %x.val to i32
%y.ptr = getelementptr inbounds nuw i8, ptr %y, i64 %iv
%y.val = load i8, ptr %y.ptr, align 1
%ext.y = sext i8 %y.val to i32
%sub = sub nsw i32 %ext.x, %ext.y
%abs.diff = tail call i32 @llvm.abs.i32(i32 %sub, i1 true)
%sum.1 = add nuw nsw i32 %abs.diff, %sum.0
%iv.next = add nuw nsw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, 8000
br i1 %exitcond.not, label %exit, label %for.body
exit:
ret i32 %sum.1
}