[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / test / Transforms / LoopVectorize / SystemZ / mem-interleaving-costs-02.ll
blob4c992cedd884a483ef0db263314907ef85ad38a5
1 ; REQUIRES: asserts
2 ; RUN: opt -mtriple=s390x-unknown-linux -mcpu=z13 -loop-vectorize \
3 ; RUN:   -debug-only=loop-vectorize,vectorutils -max-interleave-group-factor=64\
4 ; RUN:   -disable-output < %s 2>&1 | FileCheck %s
6 ; Check that some cost estimations for interleave groups make sense.
8 ; This loop is loading four i16 values at indices [0, 1, 2, 3], with a stride
9 ; of 4. At VF=4, memory interleaving means loading 4 * 4 * 16 bits = 2 vector
10 ; registers. Each of the 4 vector values must then be constructed from the
11 ; two vector registers using one vperm each, which gives a cost of 2 + 4 = 6.
13 ; CHECK: LV: Checking a loop in "fun0"
14 ; CHECK: LV: Found an estimated cost of 6 for VF 4 For instruction:   %ld0 = load i16
15 ; CHECK: LV: Found an estimated cost of 0 for VF 4 For instruction:   %ld1 = load i16
16 ; CHECK: LV: Found an estimated cost of 0 for VF 4 For instruction:   %ld2 = load i16
17 ; CHECK: LV: Found an estimated cost of 0 for VF 4 For instruction:   %ld3 = load i16
18 define void @fun0(i16 *%ptr, i16 *%dst) {
19 entry:
20   br label %for.body
22 for.body:
23   %ivptr = phi i16* [ %ptr.next, %for.body ], [ %ptr, %entry ]
24   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
25   %inc = add i64 %iv, 4
26   %ptr0 = getelementptr inbounds i16, i16* %ivptr, i64 0
27   %ld0 = load i16, i16* %ptr0
28   %ptr1 = getelementptr inbounds i16, i16* %ivptr, i64 1
29   %ld1 = load i16, i16* %ptr1
30   %ptr2 = getelementptr inbounds i16, i16* %ivptr, i64 2
31   %ld2 = load i16, i16* %ptr2
32   %ptr3 = getelementptr inbounds i16, i16* %ivptr, i64 3
33   %ld3 = load i16, i16* %ptr3
34   %a1 = add i16 %ld0, %ld1
35   %a2 = add i16 %a1, %ld2
36   %a3 = add i16 %a2, %ld3
37   %dstptr = getelementptr inbounds i16, i16* %dst, i64 %iv
38   store i16 %a3, i16* %dstptr
39   %ptr.next = getelementptr inbounds i16, i16* %ivptr, i64 4
40   %cmp = icmp eq i64 %inc, 100
41   br i1 %cmp, label %for.end, label %for.body
43 for.end:
44   ret void
47 ; This loop loads one i8 value in a stride of 3. At VF=16, this means loading
48 ; 3 vector registers, and then constructing the vector value with two vperms,
49 ; which gives a cost of 5.
51 ; CHECK: LV: Checking a loop in "fun1"
52 ; CHECK: LV: Found an estimated cost of 5 for VF 16 For instruction:   %ld0 = load i8
53 define void @fun1(i8 *%ptr, i8 *%dst) {
54 entry:
55   br label %for.body
57 for.body:
58   %ivptr = phi i8* [ %ptr.next, %for.body ], [ %ptr, %entry ]
59   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
60   %inc = add i64 %iv, 4
61   %ptr0 = getelementptr inbounds i8, i8* %ivptr, i64 0
62   %ld0 = load i8, i8* %ptr0
63   %dstptr = getelementptr inbounds i8, i8* %dst, i64 %iv
64   store i8 %ld0, i8* %dstptr
65   %ptr.next = getelementptr inbounds i8, i8* %ivptr, i64 3
66   %cmp = icmp eq i64 %inc, 100
67   br i1 %cmp, label %for.end, label %for.body
69 for.end:
70   ret void
73 ; This loop is loading 4 i8 values at indexes [0, 1, 2, 3], with a stride of
74 ; 32. At VF=2, this means loading 2 vector registers, and using 4 vperms to
75 ; produce the vector values, which gives a cost of 6.
77 ; CHECK: LV: Checking a loop in "fun2"
78 ; CHECK: LV: Found an estimated cost of 6 for VF 2 For instruction:   %ld0 = load i8
79 ; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction:   %ld1 = load i8
80 ; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction:   %ld2 = load i8
81 ; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction:   %ld3 = load i8
82 define void @fun2(i8 *%ptr, i8 *%dst) {
83 entry:
84   br label %for.body
86 for.body:
87   %ivptr = phi i8* [ %ptr.next, %for.body ], [ %ptr, %entry ]
88   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
89   %inc = add i64 %iv, 4
90   %ptr0 = getelementptr inbounds i8, i8* %ivptr, i64 0
91   %ld0 = load i8, i8* %ptr0
92   %ptr1 = getelementptr inbounds i8, i8* %ivptr, i64 1
93   %ld1 = load i8, i8* %ptr1
94   %ptr2 = getelementptr inbounds i8, i8* %ivptr, i64 2
95   %ld2 = load i8, i8* %ptr2
96   %ptr3 = getelementptr inbounds i8, i8* %ivptr, i64 3
97   %ld3 = load i8, i8* %ptr3
98   %a1 = add i8 %ld0, %ld1
99   %a2 = add i8 %a1, %ld2
100   %a3 = add i8 %a2, %ld3
101   %dstptr = getelementptr inbounds i8, i8* %dst, i64 %iv
102   store i8 %a3, i8* %dstptr
103   %ptr.next = getelementptr inbounds i8, i8* %ivptr, i64 32
104   %cmp = icmp eq i64 %inc, 100
105   br i1 %cmp, label %for.end, label %for.body
107 for.end:
108   ret void
111 ; This loop is loading 4 i8 values at indexes [0, 1, 2, 3], with a stride of
112 ; 30. At VF=2, this means loading 3 vector registers, and using 4 vperms to
113 ; produce the vector values, which gives a cost of 7. This is the same loop
114 ; as in fun2, except the stride makes the second iterations values overlap a
115 ; vector register boundary.
117 ; CHECK: LV: Checking a loop in "fun3"
118 ; CHECK: LV: Found an estimated cost of 7 for VF 2 For instruction:   %ld0 = load i8
119 ; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction:   %ld1 = load i8
120 ; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction:   %ld2 = load i8
121 ; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction:   %ld3 = load i8
122 define void @fun3(i8 *%ptr, i8 *%dst) {
123 entry:
124   br label %for.body
126 for.body:
127   %ivptr = phi i8* [ %ptr.next, %for.body ], [ %ptr, %entry ]
128   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
129   %inc = add i64 %iv, 4
130   %ptr0 = getelementptr inbounds i8, i8* %ivptr, i64 0
131   %ld0 = load i8, i8* %ptr0
132   %ptr1 = getelementptr inbounds i8, i8* %ivptr, i64 1
133   %ld1 = load i8, i8* %ptr1
134   %ptr2 = getelementptr inbounds i8, i8* %ivptr, i64 2
135   %ld2 = load i8, i8* %ptr2
136   %ptr3 = getelementptr inbounds i8, i8* %ivptr, i64 3
137   %ld3 = load i8, i8* %ptr3
138   %a1 = add i8 %ld0, %ld1
139   %a2 = add i8 %a1, %ld2
140   %a3 = add i8 %a2, %ld3
141   %dstptr = getelementptr inbounds i8, i8* %dst, i64 %iv
142   store i8 %a3, i8* %dstptr
143   %ptr.next = getelementptr inbounds i8, i8* %ivptr, i64 30
144   %cmp = icmp eq i64 %inc, 100
145   br i1 %cmp, label %for.end, label %for.body
147 for.end:
148   ret void