1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -slp-vectorizer -slp-vectorize-hor -slp-vectorize-hor-store -S < %s -mtriple=x86_64-apple-macosx -mcpu=corei7-avx -mattr=+avx2 | FileCheck %s
4 ;void Distance(float *p1, int p2, unsigned long p3[], float p4[]) {
13 ; p4[0] += p1[p3[0] & a];
16 define void @_Z8DistanceIlLi5EEvPfiPmS0_(float* %p1, i32 %p2, i64* %p3, float* %p4) {
17 ; CHECK-LABEL: @_Z8DistanceIlLi5EEvPfiPmS0_(
19 ; CHECK-NEXT: store i64 5, i64* [[P3:%.*]], align 8
20 ; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[P2:%.*]] to i64
21 ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[P1:%.*]], i64 [[IDX_EXT]]
22 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[ADD_PTR]], i64 5
23 ; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[ARRAYIDX1]], align 4
24 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[P4:%.*]], i64 3
25 ; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[ARRAYIDX2]], align 4
26 ; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP0]], [[TMP1]]
27 ; CHECK-NEXT: store float [[ADD]], float* [[ARRAYIDX2]], align 4
28 ; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 1
29 ; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 2
30 ; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 3
31 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[P3]] to <4 x i64>*
32 ; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 8
33 ; CHECK-NEXT: [[TMP4:%.*]] = lshr <4 x i64> [[TMP3]], <i64 5, i64 5, i64 5, i64 5>
34 ; CHECK-NEXT: [[TMP5:%.*]] = bitcast i64* [[P3]] to <4 x i64>*
35 ; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[TMP5]], align 8
36 ; CHECK-NEXT: [[ADD_PTR11:%.*]] = getelementptr inbounds float, float* [[ADD_PTR]], i64 [[IDX_EXT]]
37 ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x i64> [[TMP4]], i32 0
38 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP6]], 5
39 ; CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds float, float* [[ADD_PTR11]], i64 [[AND]]
40 ; CHECK-NEXT: [[TMP7:%.*]] = load float, float* [[ARRAYIDX13]], align 4
41 ; CHECK-NEXT: [[TMP8:%.*]] = load float, float* [[P4]], align 4
42 ; CHECK-NEXT: [[ADD15:%.*]] = fadd float [[TMP7]], [[TMP8]]
43 ; CHECK-NEXT: store float [[ADD15]], float* [[P4]], align 4
44 ; CHECK-NEXT: ret void
47 store i64 5, i64* %p3, align 8
48 %idx.ext = sext i32 %p2 to i64
49 %add.ptr = getelementptr inbounds float, float* %p1, i64 %idx.ext
50 %arrayidx1 = getelementptr inbounds float, float* %add.ptr, i64 5
51 %0 = load float, float* %arrayidx1, align 4
52 %arrayidx2 = getelementptr inbounds float, float* %p4, i64 3
53 %1 = load float, float* %arrayidx2, align 4
54 %add = fadd float %0, %1
55 store float %add, float* %arrayidx2, align 4
56 %2 = load i64, i64* %p3, align 8
58 store i64 %shr, i64* %p3, align 8
59 %arrayidx4 = getelementptr inbounds i64, i64* %p3, i64 1
60 %3 = load i64, i64* %arrayidx4, align 8
61 %shr5 = lshr i64 %3, 5
62 store i64 %shr5, i64* %arrayidx4, align 8
63 %arrayidx6 = getelementptr inbounds i64, i64* %p3, i64 2
64 %4 = load i64, i64* %arrayidx6, align 8
65 %shr7 = lshr i64 %4, 5
66 store i64 %shr7, i64* %arrayidx6, align 8
67 %arrayidx8 = getelementptr inbounds i64, i64* %p3, i64 3
68 %5 = load i64, i64* %arrayidx8, align 8
69 %shr9 = lshr i64 %5, 5
70 store i64 %shr9, i64* %arrayidx8, align 8
71 %add.ptr11 = getelementptr inbounds float, float* %add.ptr, i64 %idx.ext
72 %and = and i64 %shr, 5
73 %arrayidx13 = getelementptr inbounds float, float* %add.ptr11, i64 %and
74 %6 = load float, float* %arrayidx13, align 4
75 %7 = load float, float* %p4, align 4
76 %add15 = fadd float %6, %7
77 store float %add15, float* %p4, align 4
81 define void @store_reverse(i64* %p3) {
82 ; CHECK-LABEL: @store_reverse(
84 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, i64* [[P3:%.*]], i64 8
85 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 7
86 ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 1
87 ; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 9
88 ; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 6
89 ; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 2
90 ; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 10
91 ; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 5
92 ; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 3
93 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[P3]] to <4 x i64>*
94 ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i64>, <4 x i64>* [[TMP0]], align 8
95 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i64> [[TMP1]], <4 x i64> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
96 ; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 11
97 ; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64* [[ARRAYIDX1]] to <4 x i64>*
98 ; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP3]], align 8
99 ; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x i64> [[TMP4]], <4 x i64> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
100 ; CHECK-NEXT: [[TMP6:%.*]] = shl <4 x i64> [[TMP2]], [[TMP5]]
101 ; CHECK-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 4
102 ; CHECK-NEXT: [[TMP7:%.*]] = bitcast i64* [[ARRAYIDX14]] to <4 x i64>*
103 ; CHECK-NEXT: store <4 x i64> [[TMP6]], <4 x i64>* [[TMP7]], align 8
104 ; CHECK-NEXT: ret void
107 %0 = load i64, i64* %p3, align 8
108 %arrayidx1 = getelementptr inbounds i64, i64* %p3, i64 8
109 %1 = load i64, i64* %arrayidx1, align 8
110 %shl = shl i64 %0, %1
111 %arrayidx2 = getelementptr inbounds i64, i64* %p3, i64 7
112 store i64 %shl, i64* %arrayidx2, align 8
113 %arrayidx3 = getelementptr inbounds i64, i64* %p3, i64 1
114 %2 = load i64, i64* %arrayidx3, align 8
115 %arrayidx4 = getelementptr inbounds i64, i64* %p3, i64 9
116 %3 = load i64, i64* %arrayidx4, align 8
117 %shl5 = shl i64 %2, %3
118 %arrayidx6 = getelementptr inbounds i64, i64* %p3, i64 6
119 store i64 %shl5, i64* %arrayidx6, align 8
120 %arrayidx7 = getelementptr inbounds i64, i64* %p3, i64 2
121 %4 = load i64, i64* %arrayidx7, align 8
122 %arrayidx8 = getelementptr inbounds i64, i64* %p3, i64 10
123 %5 = load i64, i64* %arrayidx8, align 8
124 %shl9 = shl i64 %4, %5
125 %arrayidx10 = getelementptr inbounds i64, i64* %p3, i64 5
126 store i64 %shl9, i64* %arrayidx10, align 8
127 %arrayidx11 = getelementptr inbounds i64, i64* %p3, i64 3
128 %6 = load i64, i64* %arrayidx11, align 8
129 %arrayidx12 = getelementptr inbounds i64, i64* %p3, i64 11
130 %7 = load i64, i64* %arrayidx12, align 8
131 %shl13 = shl i64 %6, %7
132 %arrayidx14 = getelementptr inbounds i64, i64* %p3, i64 4
133 store i64 %shl13, i64* %arrayidx14, align 8
137 define void @store15(float* %p1, i32 %p2, i64* %p3, float* %p4) {
138 ; CHECK-LABEL: @store15(
140 ; CHECK-NEXT: store i64 5, i64* [[P3:%.*]], align 8
141 ; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[P2:%.*]] to i64
142 ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[P1:%.*]], i64 [[IDX_EXT]]
143 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[ADD_PTR]], i64 5
144 ; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[ARRAYIDX1]], align 4
145 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[P4:%.*]], i64 3
146 ; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[ARRAYIDX2]], align 4
147 ; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP0]], [[TMP1]]
148 ; CHECK-NEXT: store float [[ADD]], float* [[ARRAYIDX2]], align 4
149 ; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 1
150 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[P3]] to <2 x i64>*
151 ; CHECK-NEXT: [[TMP3:%.*]] = load <2 x i64>, <2 x i64>* [[TMP2]], align 8
152 ; CHECK-NEXT: [[TMP4:%.*]] = lshr <2 x i64> [[TMP3]], <i64 5, i64 5>
153 ; CHECK-NEXT: [[TMP5:%.*]] = bitcast i64* [[P3]] to <2 x i64>*
154 ; CHECK-NEXT: store <2 x i64> [[TMP4]], <2 x i64>* [[TMP5]], align 8
155 ; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 2
156 ; CHECK-NEXT: [[TMP6:%.*]] = load i64, i64* [[ARRAYIDX6]], align 8
157 ; CHECK-NEXT: [[SHR7:%.*]] = lshr i64 [[TMP6]], 5
158 ; CHECK-NEXT: store i64 [[SHR7]], i64* [[ARRAYIDX6]], align 8
159 ; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 3
160 ; CHECK-NEXT: [[TMP7:%.*]] = load i64, i64* [[ARRAYIDX8]], align 8
161 ; CHECK-NEXT: [[SHR9:%.*]] = lshr i64 [[TMP7]], 5
162 ; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 5
163 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
164 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
165 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
166 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
167 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
168 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
169 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
170 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
171 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
172 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
173 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
174 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
175 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
176 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
177 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
178 ; CHECK-NEXT: store i64 [[SHR9]], i64* [[ARRAYIDX8]], align 8
179 ; CHECK-NEXT: ret void
182 store i64 5, i64* %p3, align 8
183 %idx.ext = sext i32 %p2 to i64
184 %add.ptr = getelementptr inbounds float, float* %p1, i64 %idx.ext
185 %arrayidx1 = getelementptr inbounds float, float* %add.ptr, i64 5
186 %0 = load float, float* %arrayidx1, align 4
187 %arrayidx2 = getelementptr inbounds float, float* %p4, i64 3
188 %1 = load float, float* %arrayidx2, align 4
189 %add = fadd float %0, %1
190 store float %add, float* %arrayidx2, align 4
191 %2 = load i64, i64* %p3, align 8
192 %shr = lshr i64 %2, 5
193 store i64 %shr, i64* %p3, align 8
194 %arrayidx4 = getelementptr inbounds i64, i64* %p3, i64 1
195 %3 = load i64, i64* %arrayidx4, align 8
196 %shr5 = lshr i64 %3, 5
197 store i64 %shr5, i64* %arrayidx4, align 8
198 %arrayidx6 = getelementptr inbounds i64, i64* %p3, i64 2
199 %4 = load i64, i64* %arrayidx6, align 8
200 %shr7 = lshr i64 %4, 5
201 store i64 %shr7, i64* %arrayidx6, align 8
202 %arrayidx8 = getelementptr inbounds i64, i64* %p3, i64 3
203 %5 = load i64, i64* %arrayidx8, align 8
204 %shr9 = lshr i64 %5, 5
205 %arrayidx9 = getelementptr inbounds i64, i64* %p3, i64 5
206 store i64 5, i64* %arrayidx9, align 8
207 store i64 5, i64* %arrayidx9, align 8
208 store i64 5, i64* %arrayidx9, align 8
209 store i64 5, i64* %arrayidx9, align 8
210 store i64 5, i64* %arrayidx9, align 8
211 store i64 5, i64* %arrayidx9, align 8
212 store i64 5, i64* %arrayidx9, align 8
213 store i64 5, i64* %arrayidx9, align 8
214 store i64 5, i64* %arrayidx9, align 8
215 store i64 5, i64* %arrayidx9, align 8
216 store i64 5, i64* %arrayidx9, align 8
217 store i64 5, i64* %arrayidx9, align 8
218 store i64 5, i64* %arrayidx9, align 8
219 store i64 5, i64* %arrayidx9, align 8
220 store i64 5, i64* %arrayidx9, align 8
221 store i64 %shr9, i64* %arrayidx8, align 8
225 define void @store16(float* %p1, i32 %p2, i64* %p3, float* %p4) {
226 ; CHECK-LABEL: @store16(
228 ; CHECK-NEXT: store i64 5, i64* [[P3:%.*]], align 8
229 ; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[P2:%.*]] to i64
230 ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[P1:%.*]], i64 [[IDX_EXT]]
231 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[ADD_PTR]], i64 5
232 ; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[ARRAYIDX1]], align 4
233 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[P4:%.*]], i64 3
234 ; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[ARRAYIDX2]], align 4
235 ; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP0]], [[TMP1]]
236 ; CHECK-NEXT: store float [[ADD]], float* [[ARRAYIDX2]], align 4
237 ; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 1
238 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[P3]] to <2 x i64>*
239 ; CHECK-NEXT: [[TMP3:%.*]] = load <2 x i64>, <2 x i64>* [[TMP2]], align 8
240 ; CHECK-NEXT: [[TMP4:%.*]] = lshr <2 x i64> [[TMP3]], <i64 5, i64 5>
241 ; CHECK-NEXT: [[TMP5:%.*]] = bitcast i64* [[P3]] to <2 x i64>*
242 ; CHECK-NEXT: store <2 x i64> [[TMP4]], <2 x i64>* [[TMP5]], align 8
243 ; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 2
244 ; CHECK-NEXT: [[TMP6:%.*]] = load i64, i64* [[ARRAYIDX6]], align 8
245 ; CHECK-NEXT: [[SHR7:%.*]] = lshr i64 [[TMP6]], 5
246 ; CHECK-NEXT: store i64 [[SHR7]], i64* [[ARRAYIDX6]], align 8
247 ; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 3
248 ; CHECK-NEXT: [[TMP7:%.*]] = load i64, i64* [[ARRAYIDX8]], align 8
249 ; CHECK-NEXT: [[SHR9:%.*]] = lshr i64 [[TMP7]], 5
250 ; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i64, i64* [[P3]], i64 5
251 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
252 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
253 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
254 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
255 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
256 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
257 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
258 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
259 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
260 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
261 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
262 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
263 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
264 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
265 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
266 ; CHECK-NEXT: store i64 5, i64* [[ARRAYIDX9]], align 8
267 ; CHECK-NEXT: store i64 [[SHR9]], i64* [[ARRAYIDX8]], align 8
268 ; CHECK-NEXT: ret void
271 store i64 5, i64* %p3, align 8
272 %idx.ext = sext i32 %p2 to i64
273 %add.ptr = getelementptr inbounds float, float* %p1, i64 %idx.ext
274 %arrayidx1 = getelementptr inbounds float, float* %add.ptr, i64 5
275 %0 = load float, float* %arrayidx1, align 4
276 %arrayidx2 = getelementptr inbounds float, float* %p4, i64 3
277 %1 = load float, float* %arrayidx2, align 4
278 %add = fadd float %0, %1
279 store float %add, float* %arrayidx2, align 4
280 %2 = load i64, i64* %p3, align 8
281 %shr = lshr i64 %2, 5
282 store i64 %shr, i64* %p3, align 8
283 %arrayidx4 = getelementptr inbounds i64, i64* %p3, i64 1
284 %3 = load i64, i64* %arrayidx4, align 8
285 %shr5 = lshr i64 %3, 5
286 store i64 %shr5, i64* %arrayidx4, align 8
287 %arrayidx6 = getelementptr inbounds i64, i64* %p3, i64 2
288 %4 = load i64, i64* %arrayidx6, align 8
289 %shr7 = lshr i64 %4, 5
290 store i64 %shr7, i64* %arrayidx6, align 8
291 %arrayidx8 = getelementptr inbounds i64, i64* %p3, i64 3
292 %5 = load i64, i64* %arrayidx8, align 8
293 %shr9 = lshr i64 %5, 5
294 %arrayidx9 = getelementptr inbounds i64, i64* %p3, i64 5
295 store i64 5, i64* %arrayidx9, align 8
296 store i64 5, i64* %arrayidx9, align 8
297 store i64 5, i64* %arrayidx9, align 8
298 store i64 5, i64* %arrayidx9, align 8
299 store i64 5, i64* %arrayidx9, align 8
300 store i64 5, i64* %arrayidx9, align 8
301 store i64 5, i64* %arrayidx9, align 8
302 store i64 5, i64* %arrayidx9, align 8
303 store i64 5, i64* %arrayidx9, align 8
304 store i64 5, i64* %arrayidx9, align 8
305 store i64 5, i64* %arrayidx9, align 8
306 store i64 5, i64* %arrayidx9, align 8
307 store i64 5, i64* %arrayidx9, align 8
308 store i64 5, i64* %arrayidx9, align 8
309 store i64 5, i64* %arrayidx9, align 8
310 store i64 5, i64* %arrayidx9, align 8
311 store i64 %shr9, i64* %arrayidx8, align 8