1 ; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s
2 ; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr9 -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s
3 ; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-PWR8 -implicit-check-not vabsdu
4 ; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-PWR7 -implicit-check-not vmaxsd
6 define <4 x i32> @simple_absv_32(<4 x i32> %a) local_unnamed_addr {
8 %sub.i = sub <4 x i32> zeroinitializer, %a
9 %0 = tail call <4 x i32> @llvm.ppc.altivec.vmaxsw(<4 x i32> %a, <4 x i32> %sub.i)
11 ; CHECK-LABEL: simple_absv_32
14 ; CHECK: vnegw v[[REG:[0-9]+]], v2
15 ; CHECK-NEXT: vmaxsw v2, v2, v[[REG]]
17 ; CHECK-PWR8-LABEL: simple_absv_32
22 ; CHECK-PWR7-LABEL: simple_absv_32
29 define <4 x i32> @simple_absv_32_swap(<4 x i32> %a) local_unnamed_addr {
31 %sub.i = sub <4 x i32> zeroinitializer, %a
32 %0 = tail call <4 x i32> @llvm.ppc.altivec.vmaxsw(<4 x i32> %sub.i, <4 x i32> %a)
34 ; CHECK-LABEL: simple_absv_32_swap
37 ; CHECK: vnegw v[[REG:[0-9]+]], v2
38 ; CHECK-NEXT: vmaxsw v2, v2, v[[REG]]
40 ; CHECK-PWR8-LABEL: simple_absv_32_swap
47 define <8 x i16> @simple_absv_16(<8 x i16> %a) local_unnamed_addr {
49 %sub.i = sub <8 x i16> zeroinitializer, %a
50 %0 = tail call <8 x i16> @llvm.ppc.altivec.vmaxsh(<8 x i16> %a, <8 x i16> %sub.i)
52 ; CHECK-LABEL: simple_absv_16
55 ; CHECK: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
56 ; CHECK-NEXT: vsubuhm v[[REG:[0-9]+]], v[[ZERO]], v2
57 ; CHECK-NEXT: vmaxsh v2, v2, v[[REG]]
59 ; CHECK-PWR8-LABEL: simple_absv_16
64 ; CHECK-PWR7-LABEL: simple_absv_16
71 define <16 x i8> @simple_absv_8(<16 x i8> %a) local_unnamed_addr {
73 %sub.i = sub <16 x i8> zeroinitializer, %a
74 %0 = tail call <16 x i8> @llvm.ppc.altivec.vmaxsb(<16 x i8> %a, <16 x i8> %sub.i)
76 ; CHECK-LABEL: simple_absv_8
79 ; CHECK: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
80 ; CHECK-NEXT: vsububm v[[REG:[0-9]+]], v[[ZERO]], v2
81 ; CHECK-NEXT: vmaxsb v2, v2, v[[REG]]
83 ; CHECK-PWR8-LABEL: simple_absv_8
88 ; CHECK-PWR7-LABEL: simple_absv_8
95 ; v2i64 vmax isn't avaiable on pwr7
96 define <2 x i64> @sub_absv_64(<2 x i64> %a, <2 x i64> %b) local_unnamed_addr {
98 %0 = sub nsw <2 x i64> %a, %b
99 %1 = icmp sgt <2 x i64> %0, <i64 -1, i64 -1>
100 %2 = sub <2 x i64> zeroinitializer, %0
101 %3 = select <2 x i1> %1, <2 x i64> %0, <2 x i64> %2
103 ; CHECK-LABEL: sub_absv_64
108 ; CHECK-PWR8-LABEL: sub_absv_64
109 ; CHECK-PWR8-DAG: vsubudm
110 ; CHECK-PWR8-DAG: xxlxor
113 ; CHECK-PWR7-LABEL: sub_absv_64
114 ; CHECK-PWR7-NOT: vmaxsd
118 ; The select pattern can only be detected for v4i32.
119 define <4 x i32> @sub_absv_32(<4 x i32> %a, <4 x i32> %b) local_unnamed_addr {
121 %0 = sub nsw <4 x i32> %a, %b
122 %1 = icmp sgt <4 x i32> %0, <i32 -1, i32 -1, i32 -1, i32 -1>
123 %2 = sub <4 x i32> zeroinitializer, %0
124 %3 = select <4 x i1> %1, <4 x i32> %0, <4 x i32> %2
126 ; CHECK-LABEL: sub_absv_32
130 ; CHECK-DAG: xvnegsp v2, v2
131 ; CHECK-DAG: xvnegsp v3, v3
132 ; CHECK-NEXT: vabsduw v2, v{{[23]}}, v{{[23]}}
134 ; CHECK-PWR8-LABEL: sub_absv_32
135 ; CHECK-PWR8-DAG: vsubuwm
136 ; CHECK-PWR8-DAG: xxlxor
139 ; CHECK-PWR7-LABEL: sub_absv_32
140 ; CHECK-PWR7-DAG: vsubuwm
141 ; CHECK-PWR7-DAG: xxlxor
146 define <8 x i16> @sub_absv_16(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr {
148 %0 = sub nsw <8 x i16> %a, %b
149 %1 = icmp sgt <8 x i16> %0, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
150 %2 = sub <8 x i16> zeroinitializer, %0
151 %3 = select <8 x i1> %1, <8 x i16> %0, <8 x i16> %2
153 ; CHECK-LABEL: sub_absv_16
155 ; CHECK-DAG: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
156 ; CHECK-DAG: vsubuhm v[[SUB:[0-9]+]], v2, v3
157 ; CHECK: vsubuhm v[[SUB1:[0-9]+]], v[[ZERO]], v[[SUB]]
158 ; CHECK-NEXT: vmaxsh v2, v[[SUB]], v[[SUB1]]
160 ; CHECK-PWR8-LABEL: sub_absv_16
161 ; CHECK-PWR8-DAG: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
162 ; CHECK-PWR8-DAG: vsubuhm v[[SUB:[0-9]+]], v2, v3
163 ; CHECK-PWR8: vsubuhm v[[SUB1:[0-9]+]], v[[ZERO]], v[[SUB]]
164 ; CHECK-PWR8-NEXT: vmaxsh v2, v[[SUB]], v[[SUB1]]
165 ; CHECK-PWR8-NEXT: blr
166 ; CHECK-PWR7-LABEL: sub_absv_16
167 ; CHECK-PWR7-DAG: vsubuhm
168 ; CHECK-PWR7-DAG: xxlxor
170 ; CHECK-PWR7-NEXT: blr
173 define <16 x i8> @sub_absv_8(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr {
175 %0 = sub nsw <16 x i8> %a, %b
176 %1 = icmp sgt <16 x i8> %0, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
177 %2 = sub <16 x i8> zeroinitializer, %0
178 %3 = select <16 x i1> %1, <16 x i8> %0, <16 x i8> %2
180 ; CHECK-LABEL: sub_absv_8
182 ; CHECK-DAG: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
183 ; CHECK-DAG: vsububm v[[SUB:[0-9]+]], v2, v3
184 ; CHECK: vsububm v[[SUB1:[0-9]+]], v[[ZERO]], v[[SUB]]
185 ; CHECK-NEXT: vmaxsb v2, v[[SUB]], v[[SUB1]]
187 ; CHECK-PWR8-LABEL: sub_absv_8
188 ; CHECK-PWR8-DAG: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
189 ; CHECK-PWR8-DAG: vsububm v[[SUB:[0-9]+]], v2, v3
190 ; CHECK-PWR8: vsububm v[[SUB1:[0-9]+]], v[[ZERO]], v[[SUB]]
191 ; CHECK-PWR8-NEXT: vmaxsb v2, v[[SUB]], v[[SUB1]]
192 ; CHECK-PWR8-NEXT: blr
193 ; CHECK-PWR7-LABEL: sub_absv_8
194 ; CHECK-PWR7-DAG: xxlxor
195 ; CHECK-PWR7-DAG: vsububm
197 ; CHECK-PWR7-NEXT: blr
200 ; FIXME: This does not produce the ISD::ABS that we are looking for.
201 ; We should fix the missing canonicalization.
202 ; We do manage to find the word version of ABS but not the halfword.
203 ; Threfore, we end up doing more work than is required with a pair of abs for word
204 ; instead of just one for the halfword.
205 define <8 x i16> @sub_absv_16_ext(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr {
207 %0 = sext <8 x i16> %a to <8 x i32>
208 %1 = sext <8 x i16> %b to <8 x i32>
209 %2 = sub nsw <8 x i32> %0, %1
210 %3 = icmp sgt <8 x i32> %2, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
211 %4 = sub nsw <8 x i32> zeroinitializer, %2
212 %5 = select <8 x i1> %3, <8 x i32> %2, <8 x i32> %4
213 %6 = trunc <8 x i32> %5 to <8 x i16>
215 ; CHECK-LABEL: sub_absv_16_ext
224 ; CHECK-PWR8-LABEL: sub_absv_16
225 ; CHECK-PWR8-DAG: vsubuwm
226 ; CHECK-PWR8-DAG: xxlxor
230 ; FIXME: This does not produce ISD::ABS. This does not even vectorize correctly!
231 ; This function should look like sub_absv_32 and sub_absv_16 except that the type is v16i8.
232 ; Function Attrs: norecurse nounwind readnone
233 define <16 x i8> @sub_absv_8_ext(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr {
235 %vecext = extractelement <16 x i8> %a, i32 0
236 %conv = zext i8 %vecext to i32
237 %vecext1 = extractelement <16 x i8> %b, i32 0
238 %conv2 = zext i8 %vecext1 to i32
239 %sub = sub nsw i32 %conv, %conv2
240 %ispos = icmp sgt i32 %sub, -1
241 %neg = sub nsw i32 0, %sub
242 %0 = select i1 %ispos, i32 %sub, i32 %neg
243 %conv3 = trunc i32 %0 to i8
244 %vecins = insertelement <16 x i8> <i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, i8 %conv3, i32 0
245 %vecext4 = extractelement <16 x i8> %a, i32 1
246 %conv5 = zext i8 %vecext4 to i32
247 %vecext6 = extractelement <16 x i8> %b, i32 1
248 %conv7 = zext i8 %vecext6 to i32
249 %sub8 = sub nsw i32 %conv5, %conv7
250 %ispos171 = icmp sgt i32 %sub8, -1
251 %neg172 = sub nsw i32 0, %sub8
252 %1 = select i1 %ispos171, i32 %sub8, i32 %neg172
253 %conv10 = trunc i32 %1 to i8
254 %vecins11 = insertelement <16 x i8> %vecins, i8 %conv10, i32 1
255 %vecext12 = extractelement <16 x i8> %a, i32 2
256 %conv13 = zext i8 %vecext12 to i32
257 %vecext14 = extractelement <16 x i8> %b, i32 2
258 %conv15 = zext i8 %vecext14 to i32
259 %sub16 = sub nsw i32 %conv13, %conv15
260 %ispos173 = icmp sgt i32 %sub16, -1
261 %neg174 = sub nsw i32 0, %sub16
262 %2 = select i1 %ispos173, i32 %sub16, i32 %neg174
263 %conv18 = trunc i32 %2 to i8
264 %vecins19 = insertelement <16 x i8> %vecins11, i8 %conv18, i32 2
265 %vecext20 = extractelement <16 x i8> %a, i32 3
266 %conv21 = zext i8 %vecext20 to i32
267 %vecext22 = extractelement <16 x i8> %b, i32 3
268 %conv23 = zext i8 %vecext22 to i32
269 %sub24 = sub nsw i32 %conv21, %conv23
270 %ispos175 = icmp sgt i32 %sub24, -1
271 %neg176 = sub nsw i32 0, %sub24
272 %3 = select i1 %ispos175, i32 %sub24, i32 %neg176
273 %conv26 = trunc i32 %3 to i8
274 %vecins27 = insertelement <16 x i8> %vecins19, i8 %conv26, i32 3
275 %vecext28 = extractelement <16 x i8> %a, i32 4
276 %conv29 = zext i8 %vecext28 to i32
277 %vecext30 = extractelement <16 x i8> %b, i32 4
278 %conv31 = zext i8 %vecext30 to i32
279 %sub32 = sub nsw i32 %conv29, %conv31
280 %ispos177 = icmp sgt i32 %sub32, -1
281 %neg178 = sub nsw i32 0, %sub32
282 %4 = select i1 %ispos177, i32 %sub32, i32 %neg178
283 %conv34 = trunc i32 %4 to i8
284 %vecins35 = insertelement <16 x i8> %vecins27, i8 %conv34, i32 4
285 %vecext36 = extractelement <16 x i8> %a, i32 5
286 %conv37 = zext i8 %vecext36 to i32
287 %vecext38 = extractelement <16 x i8> %b, i32 5
288 %conv39 = zext i8 %vecext38 to i32
289 %sub40 = sub nsw i32 %conv37, %conv39
290 %ispos179 = icmp sgt i32 %sub40, -1
291 %neg180 = sub nsw i32 0, %sub40
292 %5 = select i1 %ispos179, i32 %sub40, i32 %neg180
293 %conv42 = trunc i32 %5 to i8
294 %vecins43 = insertelement <16 x i8> %vecins35, i8 %conv42, i32 5
295 %vecext44 = extractelement <16 x i8> %a, i32 6
296 %conv45 = zext i8 %vecext44 to i32
297 %vecext46 = extractelement <16 x i8> %b, i32 6
298 %conv47 = zext i8 %vecext46 to i32
299 %sub48 = sub nsw i32 %conv45, %conv47
300 %ispos181 = icmp sgt i32 %sub48, -1
301 %neg182 = sub nsw i32 0, %sub48
302 %6 = select i1 %ispos181, i32 %sub48, i32 %neg182
303 %conv50 = trunc i32 %6 to i8
304 %vecins51 = insertelement <16 x i8> %vecins43, i8 %conv50, i32 6
305 %vecext52 = extractelement <16 x i8> %a, i32 7
306 %conv53 = zext i8 %vecext52 to i32
307 %vecext54 = extractelement <16 x i8> %b, i32 7
308 %conv55 = zext i8 %vecext54 to i32
309 %sub56 = sub nsw i32 %conv53, %conv55
310 %ispos183 = icmp sgt i32 %sub56, -1
311 %neg184 = sub nsw i32 0, %sub56
312 %7 = select i1 %ispos183, i32 %sub56, i32 %neg184
313 %conv58 = trunc i32 %7 to i8
314 %vecins59 = insertelement <16 x i8> %vecins51, i8 %conv58, i32 7
315 %vecext60 = extractelement <16 x i8> %a, i32 8
316 %conv61 = zext i8 %vecext60 to i32
317 %vecext62 = extractelement <16 x i8> %b, i32 8
318 %conv63 = zext i8 %vecext62 to i32
319 %sub64 = sub nsw i32 %conv61, %conv63
320 %ispos185 = icmp sgt i32 %sub64, -1
321 %neg186 = sub nsw i32 0, %sub64
322 %8 = select i1 %ispos185, i32 %sub64, i32 %neg186
323 %conv66 = trunc i32 %8 to i8
324 %vecins67 = insertelement <16 x i8> %vecins59, i8 %conv66, i32 8
325 %vecext68 = extractelement <16 x i8> %a, i32 9
326 %conv69 = zext i8 %vecext68 to i32
327 %vecext70 = extractelement <16 x i8> %b, i32 9
328 %conv71 = zext i8 %vecext70 to i32
329 %sub72 = sub nsw i32 %conv69, %conv71
330 %ispos187 = icmp sgt i32 %sub72, -1
331 %neg188 = sub nsw i32 0, %sub72
332 %9 = select i1 %ispos187, i32 %sub72, i32 %neg188
333 %conv74 = trunc i32 %9 to i8
334 %vecins75 = insertelement <16 x i8> %vecins67, i8 %conv74, i32 9
335 %vecext76 = extractelement <16 x i8> %a, i32 10
336 %conv77 = zext i8 %vecext76 to i32
337 %vecext78 = extractelement <16 x i8> %b, i32 10
338 %conv79 = zext i8 %vecext78 to i32
339 %sub80 = sub nsw i32 %conv77, %conv79
340 %ispos189 = icmp sgt i32 %sub80, -1
341 %neg190 = sub nsw i32 0, %sub80
342 %10 = select i1 %ispos189, i32 %sub80, i32 %neg190
343 %conv82 = trunc i32 %10 to i8
344 %vecins83 = insertelement <16 x i8> %vecins75, i8 %conv82, i32 10
345 %vecext84 = extractelement <16 x i8> %a, i32 11
346 %conv85 = zext i8 %vecext84 to i32
347 %vecext86 = extractelement <16 x i8> %b, i32 11
348 %conv87 = zext i8 %vecext86 to i32
349 %sub88 = sub nsw i32 %conv85, %conv87
350 %ispos191 = icmp sgt i32 %sub88, -1
351 %neg192 = sub nsw i32 0, %sub88
352 %11 = select i1 %ispos191, i32 %sub88, i32 %neg192
353 %conv90 = trunc i32 %11 to i8
354 %vecins91 = insertelement <16 x i8> %vecins83, i8 %conv90, i32 11
355 %vecext92 = extractelement <16 x i8> %a, i32 12
356 %conv93 = zext i8 %vecext92 to i32
357 %vecext94 = extractelement <16 x i8> %b, i32 12
358 %conv95 = zext i8 %vecext94 to i32
359 %sub96 = sub nsw i32 %conv93, %conv95
360 %ispos193 = icmp sgt i32 %sub96, -1
361 %neg194 = sub nsw i32 0, %sub96
362 %12 = select i1 %ispos193, i32 %sub96, i32 %neg194
363 %conv98 = trunc i32 %12 to i8
364 %vecins99 = insertelement <16 x i8> %vecins91, i8 %conv98, i32 12
365 %vecext100 = extractelement <16 x i8> %a, i32 13
366 %conv101 = zext i8 %vecext100 to i32
367 %vecext102 = extractelement <16 x i8> %b, i32 13
368 %conv103 = zext i8 %vecext102 to i32
369 %sub104 = sub nsw i32 %conv101, %conv103
370 %ispos195 = icmp sgt i32 %sub104, -1
371 %neg196 = sub nsw i32 0, %sub104
372 %13 = select i1 %ispos195, i32 %sub104, i32 %neg196
373 %conv106 = trunc i32 %13 to i8
374 %vecins107 = insertelement <16 x i8> %vecins99, i8 %conv106, i32 13
375 %vecext108 = extractelement <16 x i8> %a, i32 14
376 %conv109 = zext i8 %vecext108 to i32
377 %vecext110 = extractelement <16 x i8> %b, i32 14
378 %conv111 = zext i8 %vecext110 to i32
379 %sub112 = sub nsw i32 %conv109, %conv111
380 %ispos197 = icmp sgt i32 %sub112, -1
381 %neg198 = sub nsw i32 0, %sub112
382 %14 = select i1 %ispos197, i32 %sub112, i32 %neg198
383 %conv114 = trunc i32 %14 to i8
384 %vecins115 = insertelement <16 x i8> %vecins107, i8 %conv114, i32 14
385 %vecext116 = extractelement <16 x i8> %a, i32 15
386 %conv117 = zext i8 %vecext116 to i32
387 %vecext118 = extractelement <16 x i8> %b, i32 15
388 %conv119 = zext i8 %vecext118 to i32
389 %sub120 = sub nsw i32 %conv117, %conv119
390 %ispos199 = icmp sgt i32 %sub120, -1
391 %neg200 = sub nsw i32 0, %sub120
392 %15 = select i1 %ispos199, i32 %sub120, i32 %neg200
393 %conv122 = trunc i32 %15 to i8
394 %vecins123 = insertelement <16 x i8> %vecins115, i8 %conv122, i32 15
395 ret <16 x i8> %vecins123
396 ; CHECK-LABEL: sub_absv_8_ext
403 ; CHECK-PWR8-LABEL: sub_absv_8_ext
409 define <4 x i32> @sub_absv_vec_32(<4 x i32> %a, <4 x i32> %b) local_unnamed_addr {
411 %sub = sub <4 x i32> %a, %b
412 %sub.i = sub <4 x i32> zeroinitializer, %sub
413 %0 = tail call <4 x i32> @llvm.ppc.altivec.vmaxsw(<4 x i32> %sub, <4 x i32> %sub.i)
415 ; CHECK-LABEL: sub_absv_vec_32
419 ; CHECK-DAG: xvnegsp v2, v2
420 ; CHECK-DAG: xvnegsp v3, v3
421 ; CHECK-NEXT: vabsduw v2, v{{[23]}}, v{{[23]}}
423 ; CHECK-PWR8-LABEL: sub_absv_vec_32
424 ; CHECK-PWR8-DAG: xxlxor
425 ; CHECK-PWR8-DAG: vsubuwm
430 define <8 x i16> @sub_absv_vec_16(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr {
432 %sub = sub <8 x i16> %a, %b
433 %sub.i = sub <8 x i16> zeroinitializer, %sub
434 %0 = tail call <8 x i16> @llvm.ppc.altivec.vmaxsh(<8 x i16> %sub, <8 x i16> %sub.i)
436 ; CHECK-LABEL: sub_absv_vec_16
439 ; CHECK-DAG: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
440 ; CHECK-DAG: vsubuhm v[[SUB:[0-9]+]], v2, v3
441 ; CHECK: vsubuhm v[[SUB1:[0-9]+]], v[[ZERO]], v[[SUB]]
442 ; CHECK-NEXT: vmaxsh v2, v[[SUB]], v[[SUB1]]
444 ; CHECK-PWR8-LABEL: sub_absv_vec_16
445 ; CHECK-PWR8-DAG: xxlxor
446 ; CHECK-PWR8-DAG: vsubuhm
451 define <16 x i8> @sub_absv_vec_8(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr {
453 %sub = sub <16 x i8> %a, %b
454 %sub.i = sub <16 x i8> zeroinitializer, %sub
455 %0 = tail call <16 x i8> @llvm.ppc.altivec.vmaxsb(<16 x i8> %sub, <16 x i8> %sub.i)
457 ; CHECK-LABEL: sub_absv_vec_8
458 ; CHECK-NOT: xxspltib
460 ; CHECK-DAG: xxlxor v[[ZERO:[0-9]+]], v[[ZERO]], v[[ZERO]]
461 ; CHECK-DAG: vsububm v[[SUB:[0-9]+]], v2, v3
462 ; CHECK: vsububm v[[SUB1:[0-9]+]], v[[ZERO]], v[[SUB]]
463 ; CHECK-NEXT: vmaxsb v2, v[[SUB]], v[[SUB1]]
465 ; CHECK-PWR8-LABEL: sub_absv_vec_8
466 ; CHECK-PWR8-DAG: xxlxor
467 ; CHECK-PWR8-DAG: vsububm
472 define <4 x i32> @zext_sub_absd32(<4 x i16>, <4 x i16>) local_unnamed_addr {
473 %3 = zext <4 x i16> %0 to <4 x i32>
474 %4 = zext <4 x i16> %1 to <4 x i32>
475 %5 = sub <4 x i32> %3, %4
476 %6 = sub <4 x i32> zeroinitializer, %5
477 %7 = tail call <4 x i32> @llvm.ppc.altivec.vmaxsw(<4 x i32> %5, <4 x i32> %6)
479 ; CHECK-LABEL: zext_sub_absd32
483 ; CHECK-PWR8-LABEL: zext_sub_absd32
488 define <8 x i16> @zext_sub_absd16(<8 x i8>, <8 x i8>) local_unnamed_addr {
489 %3 = zext <8 x i8> %0 to <8 x i16>
490 %4 = zext <8 x i8> %1 to <8 x i16>
491 %5 = sub <8 x i16> %3, %4
492 %6 = sub <8 x i16> zeroinitializer, %5
493 %7 = tail call <8 x i16> @llvm.ppc.altivec.vmaxsh(<8 x i16> %5, <8 x i16> %6)
495 ; CHECK-LABEL: zext_sub_absd16
499 ; CHECK-PWR8-LABEL: zext_sub_absd16
504 define <16 x i8> @zext_sub_absd8(<16 x i4>, <16 x i4>) local_unnamed_addr {
505 %3 = zext <16 x i4> %0 to <16 x i8>
506 %4 = zext <16 x i4> %1 to <16 x i8>
507 %5 = sub <16 x i8> %3, %4
508 %6 = sub <16 x i8> zeroinitializer, %5
509 %7 = tail call <16 x i8> @llvm.ppc.altivec.vmaxsb(<16 x i8> %5, <16 x i8> %6)
511 ; CHECK-LABEL: zext_sub_absd8
515 ; CHECK-PWR8-LABEL: zext_sub_absd8
520 ; To verify vabsdu* exploitation for ucmp + sub + select sequence
522 define <4 x i32> @absd_int32_ugt(<4 x i32>, <4 x i32>) {
523 %3 = icmp ugt <4 x i32> %0, %1
524 %4 = sub <4 x i32> %0, %1
525 %5 = sub <4 x i32> %1, %0
526 %6 = select <4 x i1> %3, <4 x i32> %4, <4 x i32> %5
528 ; CHECK-LABEL: absd_int32_ugt
529 ; CHECK-NOT: vcmpgtuw
531 ; CHECK: vabsduw v2, v2, v3
533 ; CHECK-PWR8-LABEL: absd_int32_ugt
534 ; CHECK-PWR8: vcmpgtuw
539 define <4 x i32> @absd_int32_uge(<4 x i32>, <4 x i32>) {
540 %3 = icmp uge <4 x i32> %0, %1
541 %4 = sub <4 x i32> %0, %1
542 %5 = sub <4 x i32> %1, %0
543 %6 = select <4 x i1> %3, <4 x i32> %4, <4 x i32> %5
545 ; CHECK-LABEL: absd_int32_uge
546 ; CHECK-NOT: vcmpgtuw
548 ; CHECK: vabsduw v2, v2, v3
550 ; CHECK-PWR8-LABEL: absd_int32_uge
551 ; CHECK-PWR8: vcmpgtuw
556 define <4 x i32> @absd_int32_ult(<4 x i32>, <4 x i32>) {
557 %3 = icmp ult <4 x i32> %0, %1
558 %4 = sub <4 x i32> %0, %1
559 %5 = sub <4 x i32> %1, %0
560 %6 = select <4 x i1> %3, <4 x i32> %5, <4 x i32> %4
562 ; CHECK-LABEL: absd_int32_ult
563 ; CHECK-NOT: vcmpgtuw
565 ; CHECK: vabsduw v2, v2, v3
567 ; CHECK-PWR8-LABEL: absd_int32_ult
568 ; CHECK-PWR8: vcmpgtuw
573 define <4 x i32> @absd_int32_ule(<4 x i32>, <4 x i32>) {
574 %3 = icmp ule <4 x i32> %0, %1
575 %4 = sub <4 x i32> %0, %1
576 %5 = sub <4 x i32> %1, %0
577 %6 = select <4 x i1> %3, <4 x i32> %5, <4 x i32> %4
579 ; CHECK-LABEL: absd_int32_ule
580 ; CHECK-NOT: vcmpgtuw
582 ; CHECK: vabsduw v2, v2, v3
584 ; CHECK-PWR8-LABEL: absd_int32_ule
585 ; CHECK-PWR8: vcmpgtuw
590 define <8 x i16> @absd_int16_ugt(<8 x i16>, <8 x i16>) {
591 %3 = icmp ugt <8 x i16> %0, %1
592 %4 = sub <8 x i16> %0, %1
593 %5 = sub <8 x i16> %1, %0
594 %6 = select <8 x i1> %3, <8 x i16> %4, <8 x i16> %5
596 ; CHECK-LABEL: absd_int16_ugt
597 ; CHECK-NOT: vcmpgtuh
599 ; CHECK: vabsduh v2, v2, v3
601 ; CHECK-PWR8-LABEL: absd_int16_ugt
602 ; CHECK-PWR8: vcmpgtuh
607 define <8 x i16> @absd_int16_uge(<8 x i16>, <8 x i16>) {
608 %3 = icmp uge <8 x i16> %0, %1
609 %4 = sub <8 x i16> %0, %1
610 %5 = sub <8 x i16> %1, %0
611 %6 = select <8 x i1> %3, <8 x i16> %4, <8 x i16> %5
613 ; CHECK-LABEL: absd_int16_uge
614 ; CHECK-NOT: vcmpgtuh
616 ; CHECK: vabsduh v2, v2, v3
618 ; CHECK-PWR8-LABEL: absd_int16_uge
619 ; CHECK-PWR8: vcmpgtuh
624 define <8 x i16> @absd_int16_ult(<8 x i16>, <8 x i16>) {
625 %3 = icmp ult <8 x i16> %0, %1
626 %4 = sub <8 x i16> %0, %1
627 %5 = sub <8 x i16> %1, %0
628 %6 = select <8 x i1> %3, <8 x i16> %5, <8 x i16> %4
630 ; CHECK-LABEL: absd_int16_ult
631 ; CHECK-NOT: vcmpgtuh
633 ; CHECK: vabsduh v2, v2, v3
635 ; CHECK-PWR8-LABEL: absd_int16_ult
636 ; CHECK-PWR8: vcmpgtuh
641 define <8 x i16> @absd_int16_ule(<8 x i16>, <8 x i16>) {
642 %3 = icmp ule <8 x i16> %0, %1
643 %4 = sub <8 x i16> %0, %1
644 %5 = sub <8 x i16> %1, %0
645 %6 = select <8 x i1> %3, <8 x i16> %5, <8 x i16> %4
647 ; CHECK-LABEL: absd_int16_ule
648 ; CHECK-NOT: vcmpgtuh
650 ; CHECK: vabsduh v2, v2, v3
652 ; CHECK-PWR8-LABEL: absd_int16_ule
653 ; CHECK-PWR8: vcmpgtuh
658 define <16 x i8> @absd_int8_ugt(<16 x i8>, <16 x i8>) {
659 %3 = icmp ugt <16 x i8> %0, %1
660 %4 = sub <16 x i8> %0, %1
661 %5 = sub <16 x i8> %1, %0
662 %6 = select <16 x i1> %3, <16 x i8> %4, <16 x i8> %5
664 ; CHECK-LABEL: absd_int8_ugt
665 ; CHECK-NOT: vcmpgtub
667 ; CHECK: vabsdub v2, v2, v3
669 ; CHECK-PWR8-LABEL: absd_int8_ugt
670 ; CHECK-PWR8: vcmpgtub
675 define <16 x i8> @absd_int8_uge(<16 x i8>, <16 x i8>) {
676 %3 = icmp uge <16 x i8> %0, %1
677 %4 = sub <16 x i8> %0, %1
678 %5 = sub <16 x i8> %1, %0
679 %6 = select <16 x i1> %3, <16 x i8> %4, <16 x i8> %5
681 ; CHECK-LABEL: absd_int8_uge
682 ; CHECK-NOT: vcmpgtub
684 ; CHECK: vabsdub v2, v2, v3
686 ; CHECK-PWR8-LABEL: absd_int8_uge
687 ; CHECK-PWR8: vcmpgtub
692 define <16 x i8> @absd_int8_ult(<16 x i8>, <16 x i8>) {
693 %3 = icmp ult <16 x i8> %0, %1
694 %4 = sub <16 x i8> %0, %1
695 %5 = sub <16 x i8> %1, %0
696 %6 = select <16 x i1> %3, <16 x i8> %5, <16 x i8> %4
698 ; CHECK-LABEL: absd_int8_ult
699 ; CHECK-NOT: vcmpgtub
701 ; CHECK: vabsdub v2, v2, v3
703 ; CHECK-PWR8-LABEL: absd_int8_ult
704 ; CHECK-PWR8: vcmpgtub
709 define <16 x i8> @absd_int8_ule(<16 x i8>, <16 x i8>) {
710 %3 = icmp ule <16 x i8> %0, %1
711 %4 = sub <16 x i8> %0, %1
712 %5 = sub <16 x i8> %1, %0
713 %6 = select <16 x i1> %3, <16 x i8> %5, <16 x i8> %4
715 ; CHECK-LABEL: absd_int8_ule
716 ; CHECK-NOT: vcmpgtub
718 ; CHECK: vabsdub v2, v2, v3
720 ; CHECK-PWR8-LABEL: absd_int8_ule
721 ; CHECK-PWR8: vcmpgtub
726 ; some cases we are unable to optimize
727 ; check whether goes beyond the scope
728 define <4 x i32> @absd_int32_ugt_opp(<4 x i32>, <4 x i32>) {
729 %3 = icmp ugt <4 x i32> %0, %1
730 %4 = sub <4 x i32> %0, %1
731 %5 = sub <4 x i32> %1, %0
732 %6 = select <4 x i1> %3, <4 x i32> %5, <4 x i32> %4
734 ; CHECK-LABEL: absd_int32_ugt_opp
739 ; CHECK-PWR8-LABEL: absd_int32_ugt_opp
740 ; CHECK-PWR8: vcmpgtuw
745 define <2 x i64> @absd_int64_ugt(<2 x i64>, <2 x i64>) {
746 %3 = icmp ugt <2 x i64> %0, %1
747 %4 = sub <2 x i64> %0, %1
748 %5 = sub <2 x i64> %1, %0
749 %6 = select <2 x i1> %3, <2 x i64> %4, <2 x i64> %5
751 ; CHECK-LABEL: absd_int64_ugt
756 ; CHECK-PWR8-LABEL: absd_int64_ugt
757 ; CHECK-PWR8: vcmpgtud
762 declare <4 x i32> @llvm.ppc.altivec.vmaxsw(<4 x i32>, <4 x i32>)
764 declare <8 x i16> @llvm.ppc.altivec.vmaxsh(<8 x i16>, <8 x i16>)
766 declare <16 x i8> @llvm.ppc.altivec.vmaxsb(<16 x i8>, <16 x i8>)