The analysis passes output function name encapsulated in `'` braces, but LV uses `"`. Harmonizing this may help in creating an update script for the LV costmodel test checks. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D121105
190 lines
9.4 KiB
LLVM
190 lines
9.4 KiB
LLVM
; REQUIRES: asserts
|
|
; RUN: opt -loop-vectorize -mcpu=neoverse-v1 -disable-output %s -debug 2>&1 | FileCheck %s
|
|
|
|
target triple="aarch64--linux-gnu"
|
|
|
|
; CHECK: LV: Checking a loop in 'gather_nxv4i32_loaded_index'
|
|
; CHECK: LV: Found an estimated cost of 81 for VF vscale x 4 For instruction: %1 = load float, float* %arrayidx3, align 4
|
|
define void @gather_nxv4i32_loaded_index(float* noalias nocapture readonly %a, i64* noalias nocapture readonly %b, float* noalias nocapture %c, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i64, i64* %b, i64 %indvars.iv
|
|
%0 = load i64, i64* %arrayidx, align 8
|
|
%arrayidx3 = getelementptr inbounds float, float* %a, i64 %0
|
|
%1 = load float, float* %arrayidx3, align 4
|
|
%arrayidx5 = getelementptr inbounds float, float* %c, i64 %indvars.iv
|
|
store float %1, float* %arrayidx5, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
; CHECK: LV: Checking a loop in 'scatter_nxv4i32_loaded_index'
|
|
; CHECK: LV: Found an estimated cost of 81 for VF vscale x 4 For instruction: store float %1, float* %arrayidx5, align 4
|
|
define void @scatter_nxv4i32_loaded_index(float* noalias nocapture readonly %a, i64* noalias nocapture readonly %b, float* noalias nocapture %c, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i64, i64* %b, i64 %indvars.iv
|
|
%0 = load i64, i64* %arrayidx, align 8
|
|
%arrayidx3 = getelementptr inbounds float, float* %a, i64 %indvars.iv
|
|
%1 = load float, float* %arrayidx3, align 4
|
|
%arrayidx5 = getelementptr inbounds float, float* %c, i64 %0
|
|
store float %1, float* %arrayidx5, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
; NOTE: For runtime-determined strides the vectoriser versions the loop and adds SCEV checks
|
|
; to ensure the stride value is always 1. Therefore, it can assume a contiguous load and a cost of 1.
|
|
; CHECK: LV: Checking a loop in 'gather_nxv4i32_unknown_stride'
|
|
; CHECK: LV: Found an estimated cost of 1 for VF vscale x 4 For instruction: %0 = load float, float* %arrayidx, align 4
|
|
define void @gather_nxv4i32_unknown_stride(float* noalias nocapture readonly %a, float* noalias nocapture %b, i64 %stride, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%indvars.iv.stride2 = mul i64 %indvars.iv, %stride
|
|
%arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv.stride2
|
|
%0 = load float, float* %arrayidx, align 4
|
|
%arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
|
|
store float %0, float* %arrayidx2, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
; NOTE: For runtime-determined strides the vectoriser versions the loop and adds SCEV checks
|
|
; to ensure the stride value is always 1. Therefore, it can assume a contiguous load and cost is 1.
|
|
; CHECK: LV: Checking a loop in 'scatter_nxv4i32_unknown_stride'
|
|
; CHECK: LV: Found an estimated cost of 1 for VF vscale x 4 For instruction: store float %0, float* %arrayidx2, align 4
|
|
define void @scatter_nxv4i32_unknown_stride(float* noalias nocapture readonly %a, float* noalias nocapture %b, i64 %stride, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%indvars.iv.stride2 = mul i64 %indvars.iv, %stride
|
|
%arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
|
|
%0 = load float, float* %arrayidx, align 4
|
|
%arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv.stride2
|
|
store float %0, float* %arrayidx2, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
; CHECK: LV: Checking a loop in 'gather_nxv4i32_stride2'
|
|
; CHECK: LV: Found an estimated cost of 81 for VF vscale x 4 For instruction: %0 = load float, float* %arrayidx, align 4
|
|
define void @gather_nxv4i32_stride2(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%indvars.iv.stride2 = mul i64 %indvars.iv, 2
|
|
%arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv.stride2
|
|
%0 = load float, float* %arrayidx, align 4
|
|
%arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
|
|
store float %0, float* %arrayidx2, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
; CHECK: LV: Checking a loop in 'scatter_nxv4i32_stride2'
|
|
; CHECK: LV: Found an estimated cost of 81 for VF vscale x 4 For instruction: store float %0, float* %arrayidx2, align 4
|
|
define void @scatter_nxv4i32_stride2(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%indvars.iv.stride2 = mul i64 %indvars.iv, 2
|
|
%arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
|
|
%0 = load float, float* %arrayidx, align 4
|
|
%arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv.stride2
|
|
store float %0, float* %arrayidx2, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
|
|
; CHECK: LV: Checking a loop in 'gather_nxv4i32_stride64'
|
|
; CHECK: LV: Found an estimated cost of 81 for VF vscale x 4 For instruction: %0 = load float, float* %arrayidx, align 4
|
|
define void @gather_nxv4i32_stride64(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%indvars.iv.stride2 = mul i64 %indvars.iv, 64
|
|
%arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv.stride2
|
|
%0 = load float, float* %arrayidx, align 4
|
|
%arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
|
|
store float %0, float* %arrayidx2, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
; CHECK: LV: Checking a loop in 'scatter_nxv4i32_stride64'
|
|
; CHECK: LV: Found an estimated cost of 81 for VF vscale x 4 For instruction: store float %0, float* %arrayidx2, align 4
|
|
define void @scatter_nxv4i32_stride64(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.body
|
|
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
|
|
%indvars.iv.stride2 = mul i64 %indvars.iv, 64
|
|
%arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
|
|
%0 = load float, float* %arrayidx, align 4
|
|
%arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv.stride2
|
|
store float %0, float* %arrayidx2, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %n
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
|
|
ret void
|
|
}
|
|
|
|
|
|
attributes #0 = { vscale_range(1, 16) "target-features"="+sve" }
|
|
|
|
!0 = distinct !{!0, !1, !2, !3, !4, !5}
|
|
!1 = !{!"llvm.loop.mustprogress"}
|
|
!2 = !{!"llvm.loop.vectorize.width", i32 4}
|
|
!3 = !{!"llvm.loop.vectorize.scalable.enable", i1 true}
|
|
!4 = !{!"llvm.loop.interleave.count", i32 1}
|
|
!5 = !{!"llvm.loop.vectorize.enable", i1 true}
|