Update VPlan to include the scalar loop header. This allows retiring VPLiveOut, as the remaining live-outs can now be handled by adding operands to the wrapped phis in the scalar loop header. Note that the current version only includes the scalar loop header, no other loop blocks and also does not wrap it in a region block. PR: https://github.com/llvm/llvm-project/pull/109975
95 lines
3.6 KiB
LLVM
95 lines
3.6 KiB
LLVM
; REQUIRES: asserts
|
|
|
|
; RUN: opt -passes=loop-vectorize -pass-remarks=loop-vectorize -enable-vplan-native-path -debug -disable-output %s 2>&1 | FileCheck %s
|
|
|
|
@arr2 = external global [8 x i64], align 16
|
|
@arr = external global [8 x [8 x i64]], align 16
|
|
|
|
define void @foo(i64 %n) {
|
|
; CHECK: VPlan 'HCFGBuilder: Plain CFG
|
|
; CHECK-NEXT: {
|
|
; CHECK-NEXT: Live-in vp<[[VTC:%.+]]> = vector-trip-count
|
|
; CHECK-NEXT: Live-in ir<8> = original trip-count
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.ph:
|
|
; CHECK-NEXT: Successor(s): vector loop
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: WIDEN-PHI ir<%outer.iv> = phi ir<0>, ir<%outer.iv.next>
|
|
; CHECK-NEXT: EMIT ir<%gep.1> = getelementptr ir<@arr2>, ir<0>, ir<%outer.iv>
|
|
; CHECK-NEXT: EMIT store ir<%outer.iv>, ir<%gep.1>
|
|
; CHECK-NEXT: EMIT ir<%add> = add ir<%outer.iv>, ir<%n>
|
|
; CHECK-NEXT: Successor(s): inner
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: <x1> inner: {
|
|
; CHECK-NEXT: inner:
|
|
; CHECK-NEXT: WIDEN-PHI ir<%inner.iv> = phi ir<0>, ir<%inner.iv.next>
|
|
; CHECK-NEXT: EMIT ir<%gep.2> = getelementptr ir<@arr>, ir<0>, ir<%inner.iv>, ir<%outer.iv>
|
|
; CHECK-NEXT: EMIT store ir<%add>, ir<%gep.2>
|
|
; CHECK-NEXT: EMIT ir<%inner.iv.next> = add ir<%inner.iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%inner.ec> = icmp ir<%inner.iv.next>, ir<8>
|
|
; CHECK-NEXT: EMIT branch-on-cond ir<%inner.ec>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): vector.latch
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.latch:
|
|
; CHECK-NEXT: EMIT ir<%outer.iv.next> = add ir<%outer.iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%outer.ec> = icmp ir<%outer.iv.next>, ir<8>
|
|
; CHECK-NEXT: EMIT branch-on-cond ir<%outer.ec>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: middle.block:
|
|
; CHECK-NEXT: EMIT vp<[[C:%.+]]> = icmp eq ir<8>, vp<[[VTC]]>
|
|
; CHECK-NEXT: EMIT branch-on-cond vp<[[C]]>
|
|
; 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:
|
|
; CHECK-NEXT: Successor(s): ir-bb<outer.header>
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: ir-bb<outer.header>:
|
|
; CHECK-NEXT: IR %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
|
|
; CHECK-NEXT: IR %gep.1 = getelementptr inbounds [8 x i64], ptr @arr2, i64 0, i64 %outer.iv
|
|
; CHECK-NEXT: IR store i64 %outer.iv, ptr %gep.1, align 4
|
|
; CHECK-NEXT: IR %add = add nsw i64 %outer.iv, %n
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
entry:
|
|
br label %outer.header
|
|
|
|
outer.header:
|
|
%outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
|
|
%gep.1 = getelementptr inbounds [8 x i64], ptr @arr2, i64 0, i64 %outer.iv
|
|
store i64 %outer.iv, ptr %gep.1, align 4
|
|
%add = add nsw i64 %outer.iv, %n
|
|
br label %inner
|
|
|
|
inner:
|
|
%inner.iv = phi i64 [ 0, %outer.header ], [ %inner.iv.next, %inner ]
|
|
%gep.2 = getelementptr inbounds [8 x [8 x i64]], ptr @arr, i64 0, i64 %inner.iv, i64 %outer.iv
|
|
store i64 %add, ptr %gep.2, align 4
|
|
%inner.iv.next = add nuw nsw i64 %inner.iv, 1
|
|
%inner.ec = icmp eq i64 %inner.iv.next, 8
|
|
br i1 %inner.ec, label %outer.latch, label %inner
|
|
|
|
outer.latch:
|
|
%outer.iv.next = add nuw nsw i64 %outer.iv, 1
|
|
%outer.ec = icmp eq i64 %outer.iv.next, 8
|
|
br i1 %outer.ec, label %exit, label %outer.header, !llvm.loop !1
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; CHECK: remark: <unknown>:0:0: vectorized outer loop (vectorization width: 4, interleaved count: 1)
|
|
|
|
!1 = distinct !{!1, !2, !3}
|
|
!2 = !{!"llvm.loop.vectorize.width", i32 4}
|
|
!3 = !{!"llvm.loop.vectorize.enable", i1 true}
|