xref: /llvm-project/llvm/test/Transforms/LoopVectorize/PowerPC/vplan-force-tail-with-evl.ll (revision 43045051d4114f2490bf0e6b01a7969d5c27ee04)
1; REQUIRES: asserts
2
3; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize \
4; RUN: -force-tail-folding-style=data-with-evl \
5; RUN: -prefer-predicate-over-epilogue=predicate-dont-vectorize \
6; RUN: -mtriple=powerpc64le-unknown-linux-gnu \
7; RUN: -mcpu=pwr10 -disable-output < %s 2>&1 | FileCheck %s
8
9define void @foo(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) {
10; CHECK-LABEL: VPlan 'Initial VPlan for VF={2,4},UF>=1' {
11; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
12; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
13; CHECK-NEXT: Live-in vp<[[VTC:%.+]]> = vector-trip-count
14; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
15; CHECK-NEXT: Live-in ir<%N> = original trip-count
16; CHECK-EMPTY:
17; CHECK-NEXT: ir-bb<entry>:
18; CHECK-NEXT: Successor(s): vector.ph
19; CHECK-EMPTY:
20; CHECK-NEXT: vector.ph:
21; CHECK-NEXT: Successor(s): vector loop
22; CHECK-EMPTY:
23; CHECK-NEXT: <x1> vector loop: {
24; CHECK-NEXT:   vector.body:
25; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION ir<0>, vp<[[CAN_INC:%.*]]>
26; CHECK-NEXT:     ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
27; CHECK-NEXT:     EMIT vp<[[CMP:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
28; CHECK-NEXT:   Successor(s): pred.store
29; CHECK-EMPTY:
30; CHECK-NEXT:  <xVFxUF> pred.store: {
31; CHECK-NEXT:    pred.store.entry:
32; CHECK-NEXT:      BRANCH-ON-MASK vp<[[CMP]]>
33; CHECK-NEXT:    Successor(s): pred.store.if, pred.store.continue
34; CHECK-EMPTY:
35; CHECK-NEXT:    pred.store.if:
36; CHECK-NEXT:      vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
37; CHECK-NEXT:      REPLICATE ir<%arrayidx> = getelementptr inbounds ir<%b>, vp<[[STEPS]]>
38; CHECK-NEXT:      REPLICATE ir<%0> = load ir<%arrayidx>
39; CHECK-NEXT:      REPLICATE ir<%arrayidx2> = getelementptr inbounds ir<%c>, vp<[[STEPS]]>
40; CHECK-NEXT:      REPLICATE ir<%1> = load ir<%arrayidx2>
41; CHECK-NEXT:      REPLICATE ir<%arrayidx4> = getelementptr inbounds ir<%a>, vp<[[STEPS]]>
42; CHECK-NEXT:      REPLICATE ir<%add> = add nsw ir<%1>, ir<%0>
43; CHECK-NEXT:      REPLICATE store ir<%add>, ir<%arrayidx4>
44; CHECK-NEXT:    Successor(s): pred.store.continue
45; CHECK-EMPTY:
46; CHECK-NEXT:    pred.store.continue:
47; CHECK-NEXT:    No successors
48; CHECK-NEXT:  }
49; CHECK-NEXT:  Successor(s): for.body.2
50; CHECK-EMPTY:
51; CHECK-NEXT:  for.body.2:
52; CHECK-NEXT:     EMIT vp<[[CAN_INC:%.+]]> = add vp<[[CAN_IV]]>, vp<[[VFxUF]]>
53; CHECK-NEXT:     EMIT branch-on-count vp<[[CAN_INC]]>, vp<[[VTC]]>
54; CHECK-NEXT:   No successors
55; CHECK-NEXT: }
56;
57entry:
58  br label %for.body
59
60for.body:
61  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
62  %arrayidx = getelementptr inbounds i32, ptr %b, i64 %iv
63  %0 = load i32, ptr %arrayidx, align 4
64  %arrayidx2 = getelementptr inbounds i32, ptr %c, i64 %iv
65  %1 = load i32, ptr %arrayidx2, align 4
66  %add = add nsw i32 %1, %0
67  %arrayidx4 = getelementptr inbounds i32, ptr %a, i64 %iv
68  store i32 %add, ptr %arrayidx4, align 4
69  %iv.next = add nuw nsw i64 %iv, 1
70  %exitcond.not = icmp eq i64 %iv.next, %N
71  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
72
73for.cond.cleanup:
74  ret void
75}
76
77define void @safe_dep(ptr %p) {
78; CHECK-LABEL: VPlan 'Initial VPlan for VF={2},UF>=1' {
79; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
80; CHECK-NEXT: Live-in vp<[[VTC:%.+]]> = vector-trip-count
81; CHECK-NEXT: Live-in ir<512> = original trip-count
82; CHECK-EMPTY:
83; CHECK-NEXT: ir-bb<entry>:
84; CHECK-NEXT: Successor(s): vector.ph
85; CHECK-EMPTY:
86; CHECK-NEXT: vector.ph:
87; CHECK-NEXT: Successor(s): vector loop
88; CHECK-EMPTY:
89; CHECK-NEXT: <x1> vector loop: {
90; CHECK-NEXT:   vector.body:
91; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION ir<0>, vp<[[CAN_INC:%.+]]>
92; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
93; CHECK-NEXT:     CLONE ir<%a1> = getelementptr ir<%p>, vp<[[STEPS]]>
94; CHECK-NEXT:     vp<[[VPTR1:%.+]]> = vector-pointer ir<%a1>
95; CHECK-NEXT:     WIDEN ir<%v> = load vp<[[VPTR1]]>
96; CHECK-NEXT:     CLONE ir<%offset> = add vp<[[STEPS]]>, ir<100>
97; CHECK-NEXT:     CLONE ir<%a2> = getelementptr ir<%p>, ir<%offset>
98; CHECK-NEXT:     vp<[[VPTR2:%.+]]> = vector-pointer ir<%a2>
99; CHECK-NEXT:     WIDEN store vp<[[VPTR2]]>, ir<%v>
100; CHECK-NEXT:     EMIT vp<[[CAN_INC]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
101; CHECK-NEXT:     EMIT branch-on-count vp<[[CAN_INC]]>, vp<[[VTC]]>
102; CHECK-NEXT:   No successors
103; CHECK-NEXT: }
104;
105entry:
106  br label %loop
107
108loop:
109  %iv = phi i64 [0, %entry], [%iv.next, %loop]
110  %a1 = getelementptr i64, ptr %p, i64 %iv
111  %v = load i64, ptr %a1, align 32
112  %offset = add i64 %iv, 100
113  %a2 = getelementptr i64, ptr %p, i64 %offset
114  store i64 %v, ptr %a2, align 32
115  %iv.next = add i64 %iv, 1
116  %cmp = icmp ne i64 %iv, 511
117  br i1 %cmp, label %loop, label %exit
118
119exit:
120  ret void
121}
122
123