[RISCV] Change func to funct in RISCVInstrInfoXqci.td. NFC (#119669)
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / SystemZ / mem-interleaving-costs-02.ll
bloba0c45962021c8bbdae8cd04f4f9e928eb4c1d938
1 ; REQUIRES: asserts
2 ; RUN: opt -mtriple=s390x-unknown-linux -mcpu=z13 -passes=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: Cost of 6 for VF 4: INTERLEAVE-GROUP with factor 4 at %ld0, vp<%next.gep>
15 ; CHECK:   ir<%ld0> = load from index 0
16 ; CHECK:   ir<%ld1> = load from index 1
17 ; CHECK:   ir<%ld2> = load from index 2
18 ; CHECK:   ir<%ld3> = load from index 3
20 define void @fun0(ptr %ptr, ptr %dst) {
21 entry:
22   br label %for.body
24 for.body:
25   %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]
26   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
27   %inc = add i64 %iv, 4
28   %ld0 = load i16, ptr %ivptr
29   %ptr1 = getelementptr inbounds i16, ptr %ivptr, i64 1
30   %ld1 = load i16, ptr %ptr1
31   %ptr2 = getelementptr inbounds i16, ptr %ivptr, i64 2
32   %ld2 = load i16, ptr %ptr2
33   %ptr3 = getelementptr inbounds i16, ptr %ivptr, i64 3
34   %ld3 = load i16, ptr %ptr3
35   %a1 = add i16 %ld0, %ld1
36   %a2 = add i16 %a1, %ld2
37   %a3 = add i16 %a2, %ld3
38   %dstptr = getelementptr inbounds i16, ptr %dst, i64 %iv
39   store i16 %a3, ptr %dstptr
40   %ptr.next = getelementptr inbounds i16, ptr %ivptr, i64 4
41   %cmp = icmp eq i64 %inc, 100
42   br i1 %cmp, label %for.end, label %for.body
44 for.end:
45   ret void
48 ; This loop loads one i8 value in a stride of 3. At VF=16, this means loading
49 ; 3 vector registers, and then constructing the vector value with two vperms,
50 ; which gives a cost of 5.
52 ; CHECK: LV: Checking a loop in 'fun1'
53 ; CHECK: Cost of 5 for VF 16: INTERLEAVE-GROUP with factor 3 at %ld0, vp<%next.gep>
54 ; CHECK:   ir<%ld0> = load from index 0
55 define void @fun1(ptr %ptr, ptr %dst) {
56 entry:
57   br label %for.body
59 for.body:
60   %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]
61   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
62   %inc = add i64 %iv, 4
63   %ld0 = load i8, ptr %ivptr
64   %dstptr = getelementptr inbounds i8, ptr %dst, i64 %iv
65   store i8 %ld0, ptr %dstptr
66   %ptr.next = getelementptr inbounds i8, ptr %ivptr, i64 3
67   %cmp = icmp eq i64 %inc, 100
68   br i1 %cmp, label %for.end, label %for.body
70 for.end:
71   ret void
74 ; This loop is loading 4 i8 values at indexes [0, 1, 2, 3], with a stride of
75 ; 32. At VF=2, this means loading 2 vector registers, and using 4 vperms to
76 ; produce the vector values, which gives a cost of 6.
78 ; CHECK: LV: Checking a loop in 'fun2'
79 ; CHECK: Cost of 6 for VF 2: INTERLEAVE-GROUP with factor 32 at %ld0, vp<%next.gep>
80 ; CHECK:   ir<%ld0> = load from index 0
81 ; CHECK:   ir<%ld1> = load from index 1
82 ; CHECK:   ir<%ld2> = load from index 2
83 ; CHECK:   ir<%ld3> = load from index 3
84 define void @fun2(ptr %ptr, ptr %dst) {
85 entry:
86   br label %for.body
88 for.body:
89   %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]
90   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
91   %inc = add i64 %iv, 4
92   %ld0 = load i8, ptr %ivptr
93   %ptr1 = getelementptr inbounds i8, ptr %ivptr, i64 1
94   %ld1 = load i8, ptr %ptr1
95   %ptr2 = getelementptr inbounds i8, ptr %ivptr, i64 2
96   %ld2 = load i8, ptr %ptr2
97   %ptr3 = getelementptr inbounds i8, ptr %ivptr, i64 3
98   %ld3 = load i8, ptr %ptr3
99   %a1 = add i8 %ld0, %ld1
100   %a2 = add i8 %a1, %ld2
101   %a3 = add i8 %a2, %ld3
102   %dstptr = getelementptr inbounds i8, ptr %dst, i64 %iv
103   store i8 %a3, ptr %dstptr
104   %ptr.next = getelementptr inbounds i8, ptr %ivptr, i64 32
105   %cmp = icmp eq i64 %inc, 100
106   br i1 %cmp, label %for.end, label %for.body
108 for.end:
109   ret void
112 ; This loop is loading 4 i8 values at indexes [0, 1, 2, 3], with a stride of
113 ; 30. At VF=2, this means loading 3 vector registers, and using 4 vperms to
114 ; produce the vector values, which gives a cost of 7. This is the same loop
115 ; as in fun2, except the stride makes the second iterations values overlap a
116 ; vector register boundary.
118 ; CHECK: LV: Checking a loop in 'fun3'
119 ; CHECK: Cost of 7 for VF 2: INTERLEAVE-GROUP with factor 30 at %ld0, vp<%next.gep>
120 ; CHECK:   ir<%ld0> = load from index 0
121 ; CHECK:   ir<%ld1> = load from index 1
122 ; CHECK:   ir<%ld2> = load from index 2
123 ; CHECK:   ir<%ld3> = load from index 3
124 define void @fun3(ptr %ptr, ptr %dst) {
125 entry:
126   br label %for.body
128 for.body:
129   %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]
130   %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
131   %inc = add i64 %iv, 4
132   %ld0 = load i8, ptr %ivptr
133   %ptr1 = getelementptr inbounds i8, ptr %ivptr, i64 1
134   %ld1 = load i8, ptr %ptr1
135   %ptr2 = getelementptr inbounds i8, ptr %ivptr, i64 2
136   %ld2 = load i8, ptr %ptr2
137   %ptr3 = getelementptr inbounds i8, ptr %ivptr, i64 3
138   %ld3 = load i8, ptr %ptr3
139   %a1 = add i8 %ld0, %ld1
140   %a2 = add i8 %a1, %ld2
141   %a3 = add i8 %a2, %ld3
142   %dstptr = getelementptr inbounds i8, ptr %dst, i64 %iv
143   store i8 %a3, ptr %dstptr
144   %ptr.next = getelementptr inbounds i8, ptr %ivptr, i64 30
145   %cmp = icmp eq i64 %inc, 100
146   br i1 %cmp, label %for.end, label %for.body
148 for.end:
149   ret void