When pragma of loop transformations are encoded in LLVM IR, follow-up metadata is used if multiple transformations are specified. They are used to explicitly express the order of the transformations. However, they are not properly processed on each transformation pass, so now only the first one is attempted to be applied. This is a pre-commit to add a test that causes the problem. ref: https://github.com/llvm/llvm-project/pull/127474#issuecomment-2717790398
88 lines
4.2 KiB
LLVM
88 lines
4.2 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -passes='loop-vectorize,loop-unroll' -force-vector-width=4 -S < %s | FileCheck %s
|
|
|
|
; Test if the follow-up metadata for loops works fine. The original code is
|
|
; something like below. In this case, unrolling should be applied after
|
|
; vectorization.
|
|
;
|
|
; void f(float *a, float x) {
|
|
; #pragma clang loop vectorize(enable) unroll_count(8)
|
|
; for (int i = 0; i < 1024; i++) {
|
|
; a[i] *= x;
|
|
; }
|
|
; }
|
|
;
|
|
; FIXME: Currently unrolling is not applied. This is because the new Loop ID
|
|
; created after vectorization does not directly contain unroll metadata.
|
|
; Unexpected nests have been created.
|
|
define void @f(ptr noundef captures(none) %a, float noundef %x) {
|
|
; CHECK-LABEL: define void @f(
|
|
; CHECK-SAME: ptr noundef captures(none) [[A:%.*]], float noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*]]:
|
|
; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[X]], i64 0
|
|
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: [[INDEX_NEXT_6:%.*]] = add i64 [[INDEX]], 0
|
|
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw float, ptr [[A]], i64 [[INDEX_NEXT_6]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i32 0
|
|
; CHECK-NEXT: [[WIDE_LOAD_7:%.*]] = load <4 x float>, ptr [[TMP2]], align 4
|
|
; CHECK-NEXT: [[TMP15:%.*]] = fmul <4 x float> [[BROADCAST_SPLAT]], [[WIDE_LOAD_7]]
|
|
; CHECK-NEXT: store <4 x float> [[TMP15]], ptr [[TMP2]], align 4
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
|
|
; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
|
|
; CHECK: [[SCALAR_PH]]:
|
|
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
|
|
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
|
|
; CHECK: [[FOR_BODY]]:
|
|
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[A]], i64 [[IV]]
|
|
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[ARRAYIDX]], align 4
|
|
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[LOAD]]
|
|
; CHECK-NEXT: store float [[MUL]], ptr [[ARRAYIDX]], align 4
|
|
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
|
|
; CHECK-NEXT: [[COMP:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
|
|
; CHECK-NEXT: br i1 [[COMP]], label %[[EXIT_LOOPEXIT:.*]], label %[[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
|
|
; CHECK: [[EXIT_LOOPEXIT]]:
|
|
; CHECK-NEXT: br label %[[EXIT]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
|
|
%arrayidx = getelementptr inbounds nuw float, ptr %a, i64 %iv
|
|
%load = load float, ptr %arrayidx, align 4
|
|
%mul = fmul float %x, %load
|
|
store float %mul, ptr %arrayidx, align 4
|
|
%iv.next = add nuw nsw i64 %iv, 1
|
|
%comp = icmp eq i64 %iv.next, 1024
|
|
br i1 %comp, label %exit, label %for.body, !llvm.loop !0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
!0 = distinct !{!0, !1, !2}
|
|
!1 = !{!"llvm.loop.vectorize.enable", i1 true}
|
|
!2 = !{!"llvm.loop.vectorize.followup_all", !3}
|
|
!3 = distinct !{!3, !4, !5}
|
|
!4 = !{!"llvm.loop.isvectorized"}
|
|
!5 = !{!"llvm.loop.unroll.count", i32 8}
|
|
;.
|
|
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META4:![0-9]+]]}
|
|
; CHECK: [[META1]] = distinct !{[[META1]], [[META2:![0-9]+]], [[META3:![0-9]+]]}
|
|
; CHECK: [[META2]] = !{!"llvm.loop.isvectorized"}
|
|
; CHECK: [[META3]] = !{!"llvm.loop.unroll.count", i32 8}
|
|
; CHECK: [[META4]] = !{!"llvm.loop.unroll.runtime.disable"}
|
|
; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]]}
|
|
;.
|