[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / CodeGen / PowerPC / ppc64-P9-vabsd.ll
blob653b2121e40ab5d39896b22f036d36ea36c1af89
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 {
7 entry:
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)
10   ret <4 x i32> %0
11 ; CHECK-LABEL: simple_absv_32
12 ; CHECK-NOT:  vxor 
13 ; CHECK-NOT:  vabsduw
14 ; CHECK:      vnegw v[[REG:[0-9]+]], v2
15 ; CHECK-NEXT: vmaxsw v2, v2, v[[REG]]
16 ; CHECK-NEXT: blr
17 ; CHECK-PWR8-LABEL: simple_absv_32
18 ; CHECK-PWR8: xxlxor
19 ; CHECK-PWR8: vsubuwm
20 ; CHECK-PWR8: vmaxsw
21 ; CHECK-PWR8: blr
22 ; CHECK-PWR7-LABEL: simple_absv_32
23 ; CHECK-PWR7: xxlxor
24 ; CHECK-PWR7: vsubuwm
25 ; CHECK-PWR7: vmaxsw
26 ; CHECK-PWR7: blr
29 define <4 x i32> @simple_absv_32_swap(<4 x i32> %a) local_unnamed_addr {
30 entry:
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)
33   ret <4 x i32> %0
34 ; CHECK-LABEL: simple_absv_32_swap
35 ; CHECK-NOT:  vxor 
36 ; CHECK-NOT:  vabsduw
37 ; CHECK:      vnegw  v[[REG:[0-9]+]], v2
38 ; CHECK-NEXT: vmaxsw v2, v2, v[[REG]]
39 ; CHECK-NEXT: blr
40 ; CHECK-PWR8-LABEL: simple_absv_32_swap
41 ; CHECK-PWR8: xxlxor
42 ; CHECK-PWR8: vsubuwm
43 ; CHECK-PWR8: vmaxsw
44 ; CHECK-PWR8: blr
47 define <8 x i16> @simple_absv_16(<8 x i16> %a) local_unnamed_addr {
48 entry:
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)
51   ret <8 x i16> %0
52 ; CHECK-LABEL: simple_absv_16
53 ; CHECK-NOT:  mtvsrws
54 ; CHECK-NOT:  vabsduh
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]]
58 ; CHECK-NEXT: blr
59 ; CHECK-PWR8-LABEL: simple_absv_16
60 ; CHECK-PWR8: xxlxor
61 ; CHECK-PWR8: vsubuhm
62 ; CHECK-PWR8: vmaxsh
63 ; CHECK-PWR8: blr
64 ; CHECK-PWR7-LABEL: simple_absv_16
65 ; CHECK-PWR7: xxlxor
66 ; CHECK-PWR7: vsubuhm
67 ; CHECK-PWR7: vmaxsh
68 ; CHECK-PWR7: blr
71 define <16 x i8> @simple_absv_8(<16 x i8> %a) local_unnamed_addr {
72 entry:
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)
75   ret <16 x i8> %0
76 ; CHECK-LABEL: simple_absv_8
77 ; CHECK-NOT:  xxspltib
78 ; CHECK-NOT:  vabsdub
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]]
82 ; CHECK-NEXT: blr
83 ; CHECK-PWR8-LABEL: simple_absv_8
84 ; CHECK-PWR8: xxlxor
85 ; CHECK-PWR8: vsububm
86 ; CHECK-PWR8: vmaxsb
87 ; CHECK-PWR8: blr
88 ; CHECK-PWR7-LABEL: simple_absv_8
89 ; CHECK-PWR7: xxlxor
90 ; CHECK-PWR7: vsububm
91 ; CHECK-PWR7: vmaxsb
92 ; CHECK-PWR7: blr
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 {
97 entry:
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
102   ret <2 x i64> %3
103 ; CHECK-LABEL: sub_absv_64
104 ; CHECK: vsubudm
105 ; CHECK: vnegd
106 ; CHECK: vmaxsd
107 ; CHECK-NEXT: blr
108 ; CHECK-PWR8-LABEL: sub_absv_64
109 ; CHECK-PWR8-DAG: vsubudm
110 ; CHECK-PWR8-DAG: xxlxor
111 ; CHECK-PWR8: vmaxsd
112 ; CHECK-PWR8: blr
113 ; CHECK-PWR7-LABEL: sub_absv_64
114 ; CHECK-PWR7-NOT: vmaxsd
115 ; CHECK-PWR7: blr
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 {
120 entry:
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
125   ret <4 x i32> %3
126 ; CHECK-LABEL: sub_absv_32
127 ; CHECK-NOT:  vsubuwm
128 ; CHECK-NOT:  vnegw
129 ; CHECK-NOT:  vmaxsw
130 ; CHECK-DAG:  xvnegsp v2, v2
131 ; CHECK-DAG:  xvnegsp v3, v3
132 ; CHECK-NEXT: vabsduw v2, v{{[23]}}, v{{[23]}}
133 ; CHECK-NEXT: blr
134 ; CHECK-PWR8-LABEL: sub_absv_32
135 ; CHECK-PWR8-DAG: vsubuwm
136 ; CHECK-PWR8-DAG: xxlxor
137 ; CHECK-PWR8: vmaxsw
138 ; CHECK-PWR8: blr
139 ; CHECK-PWR7-LABEL: sub_absv_32
140 ; CHECK-PWR7-DAG: vsubuwm
141 ; CHECK-PWR7-DAG: xxlxor
142 ; CHECK-PWR7: vmaxsw
143 ; CHECK-PWR7: blr
146 define <8 x i16> @sub_absv_16(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr {
147 entry:
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
152   ret <8 x i16> %3
153 ; CHECK-LABEL: sub_absv_16
154 ; CHECK-NOT:  vabsduh
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]]
159 ; CHECK-NEXT: blr
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
169 ; CHECK-PWR7: vmaxsh
170 ; CHECK-PWR7-NEXT: blr
173 define <16 x i8> @sub_absv_8(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr {
174 entry:
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
179   ret <16 x i8> %3
180 ; CHECK-LABEL: sub_absv_8
181 ; CHECK-NOT:  vabsdub
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]]
186 ; CHECK-NEXT: blr
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
196 ; CHECK-PWR7: vmaxsb
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 {
206 entry:
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>
214   ret <8 x i16> %6
215 ; CHECK-LABEL: sub_absv_16_ext
216 ; CHECK-NOT: vabsduh
217 ; CHECK: vabsduw
218 ; CHECK-NOT: vnegw
219 ; CHECK-NOT: vabsduh
220 ; CHECK: vabsduw
221 ; CHECK-NOT: vnegw
222 ; CHECK-NOT: vabsduh
223 ; CHECK: blr
224 ; CHECK-PWR8-LABEL: sub_absv_16
225 ; CHECK-PWR8-DAG: vsubuwm
226 ; CHECK-PWR8-DAG: xxlxor
227 ; CHECK-PWR8: blr
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 {
234 entry:
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
397 ; CHECK-NOT: vabsdub
398 ; CHECK: subf
399 ; CHECK-NOT: vabsdub
400 ; CHECK: xor
401 ; CHECK-NOT: vabsdub
402 ; CHECK: blr
403 ; CHECK-PWR8-LABEL: sub_absv_8_ext
404 ; CHECK-PWR8: subf
405 ; CHECK-PWR8: xor
406 ; CHECK-PWR8: blr
409 define <4 x i32> @sub_absv_vec_32(<4 x i32> %a, <4 x i32> %b) local_unnamed_addr {
410 entry:
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)
414   ret <4 x i32> %0
415 ; CHECK-LABEL: sub_absv_vec_32
416 ; CHECK-NOT:  vsubuwm
417 ; CHECK-NOT:  vnegw
418 ; CHECK-NOT:  vmaxsw
419 ; CHECK-DAG:  xvnegsp v2, v2
420 ; CHECK-DAG:  xvnegsp v3, v3
421 ; CHECK-NEXT: vabsduw v2, v{{[23]}}, v{{[23]}}
422 ; CHECK-NEXT: blr
423 ; CHECK-PWR8-LABEL: sub_absv_vec_32
424 ; CHECK-PWR8-DAG: xxlxor
425 ; CHECK-PWR8-DAG: vsubuwm
426 ; CHECK-PWR8: vmaxsw
427 ; CHECK-PWR8: blr
430 define <8 x i16> @sub_absv_vec_16(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr {
431 entry:
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)
435   ret <8 x i16> %0
436 ; CHECK-LABEL: sub_absv_vec_16
437 ; CHECK-NOT:  mtvsrws
438 ; CHECK-NOT:  vabsduh
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]]
443 ; CHECK-NEXT: blr
444 ; CHECK-PWR8-LABEL: sub_absv_vec_16
445 ; CHECK-PWR8-DAG: xxlxor
446 ; CHECK-PWR8-DAG: vsubuhm
447 ; CHECK-PWR8: vmaxsh
448 ; CHECK-PWR8: blr
451 define <16 x i8> @sub_absv_vec_8(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr {
452 entry:
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)
456   ret <16 x i8> %0
457 ; CHECK-LABEL: sub_absv_vec_8
458 ; CHECK-NOT:  xxspltib
459 ; CHECK-NOT:  vabsdub
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]]
464 ; CHECK-NEXT: blr
465 ; CHECK-PWR8-LABEL: sub_absv_vec_8
466 ; CHECK-PWR8-DAG: xxlxor
467 ; CHECK-PWR8-DAG: vsububm
468 ; CHECK-PWR8: vmaxsb
469 ; CHECK-PWR8: blr
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)
478     ret <4 x i32> %7
479 ; CHECK-LABEL: zext_sub_absd32
480 ; CHECK-NOT: xvnegsp
481 ; CHECK:     vabsduw
482 ; CHECK:     blr
483 ; CHECK-PWR8-LABEL: zext_sub_absd32
484 ; CHECK-PWR8: vmaxsw
485 ; CHECK-PWR8: blr
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)
494     ret <8 x i16> %7
495 ; CHECK-LABEL: zext_sub_absd16
496 ; CHECK-NOT: vadduhm
497 ; CHECK:     vabsduh
498 ; CHECK:     blr
499 ; CHECK-PWR8-LABEL: zext_sub_absd16
500 ; CHECK-PWR8: vmaxsh
501 ; CHECK-PWR8: blr
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)
510     ret <16 x i8> %7
511 ; CHECK-LABEL: zext_sub_absd8
512 ; CHECK-NOT: vaddubm
513 ; CHECK:     vabsdub
514 ; CHECK:     blr
515 ; CHECK-PWR8-LABEL: zext_sub_absd8
516 ; CHECK-PWR8: vmaxsb
517 ; CHECK-PWR8: blr
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
527   ret <4 x i32> %6
528 ; CHECK-LABEL: absd_int32_ugt
529 ; CHECK-NOT: vcmpgtuw
530 ; CHECK-NOT: xxsel
531 ; CHECK: vabsduw v2, v2, v3
532 ; CHECK-NEXT: blr
533 ; CHECK-PWR8-LABEL: absd_int32_ugt
534 ; CHECK-PWR8: vcmpgtuw
535 ; CHECK-PWR8: xxsel
536 ; CHECK-PWR8: blr
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
544   ret <4 x i32> %6
545 ; CHECK-LABEL: absd_int32_uge
546 ; CHECK-NOT: vcmpgtuw
547 ; CHECK-NOT: xxsel
548 ; CHECK: vabsduw v2, v2, v3
549 ; CHECK-NEXT: blr
550 ; CHECK-PWR8-LABEL: absd_int32_uge
551 ; CHECK-PWR8: vcmpgtuw
552 ; CHECK-PWR8: xxsel
553 ; CHECK-PWR8: blr
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
561   ret <4 x i32> %6
562 ; CHECK-LABEL: absd_int32_ult
563 ; CHECK-NOT: vcmpgtuw
564 ; CHECK-NOT: xxsel
565 ; CHECK: vabsduw v2, v2, v3
566 ; CHECK-NEXT: blr
567 ; CHECK-PWR8-LABEL: absd_int32_ult
568 ; CHECK-PWR8: vcmpgtuw
569 ; CHECK-PWR8: xxsel
570 ; CHECK-PWR8: blr
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
578   ret <4 x i32> %6
579 ; CHECK-LABEL: absd_int32_ule
580 ; CHECK-NOT: vcmpgtuw
581 ; CHECK-NOT: xxsel
582 ; CHECK: vabsduw v2, v2, v3
583 ; CHECK-NEXT: blr
584 ; CHECK-PWR8-LABEL: absd_int32_ule
585 ; CHECK-PWR8: vcmpgtuw
586 ; CHECK-PWR8: xxsel
587 ; CHECK-PWR8: blr
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
595   ret <8 x i16> %6
596 ; CHECK-LABEL: absd_int16_ugt
597 ; CHECK-NOT: vcmpgtuh
598 ; CHECK-NOT: xxsel
599 ; CHECK: vabsduh v2, v2, v3
600 ; CHECK-NEXT: blr
601 ; CHECK-PWR8-LABEL: absd_int16_ugt
602 ; CHECK-PWR8: vcmpgtuh
603 ; CHECK-PWR8: xxsel
604 ; CHECK-PWR8: blr
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
612   ret <8 x i16> %6
613 ; CHECK-LABEL: absd_int16_uge
614 ; CHECK-NOT: vcmpgtuh
615 ; CHECK-NOT: xxsel
616 ; CHECK: vabsduh v2, v2, v3
617 ; CHECK-NEXT: blr
618 ; CHECK-PWR8-LABEL: absd_int16_uge
619 ; CHECK-PWR8: vcmpgtuh
620 ; CHECK-PWR8: xxsel
621 ; CHECK-PWR8: blr
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
629   ret <8 x i16> %6
630 ; CHECK-LABEL: absd_int16_ult
631 ; CHECK-NOT: vcmpgtuh
632 ; CHECK-NOT: xxsel
633 ; CHECK: vabsduh v2, v2, v3
634 ; CHECK-NEXT: blr
635 ; CHECK-PWR8-LABEL: absd_int16_ult
636 ; CHECK-PWR8: vcmpgtuh
637 ; CHECK-PWR8: xxsel
638 ; CHECK-PWR8: blr
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
646   ret <8 x i16> %6
647 ; CHECK-LABEL: absd_int16_ule
648 ; CHECK-NOT: vcmpgtuh
649 ; CHECK-NOT: xxsel
650 ; CHECK: vabsduh v2, v2, v3
651 ; CHECK-NEXT: blr
652 ; CHECK-PWR8-LABEL: absd_int16_ule
653 ; CHECK-PWR8: vcmpgtuh
654 ; CHECK-PWR8: xxsel
655 ; CHECK-PWR8: blr
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
663   ret <16 x i8> %6
664 ; CHECK-LABEL: absd_int8_ugt
665 ; CHECK-NOT: vcmpgtub
666 ; CHECK-NOT: xxsel
667 ; CHECK: vabsdub v2, v2, v3
668 ; CHECK-NEXT: blr
669 ; CHECK-PWR8-LABEL: absd_int8_ugt
670 ; CHECK-PWR8: vcmpgtub
671 ; CHECK-PWR8: xxsel
672 ; CHECK-PWR8: blr
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
680   ret <16 x i8> %6
681 ; CHECK-LABEL: absd_int8_uge
682 ; CHECK-NOT: vcmpgtub
683 ; CHECK-NOT: xxsel
684 ; CHECK: vabsdub v2, v2, v3
685 ; CHECK-NEXT: blr
686 ; CHECK-PWR8-LABEL: absd_int8_uge
687 ; CHECK-PWR8: vcmpgtub
688 ; CHECK-PWR8: xxsel
689 ; CHECK-PWR8: blr
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
697   ret <16 x i8> %6
698 ; CHECK-LABEL: absd_int8_ult
699 ; CHECK-NOT: vcmpgtub
700 ; CHECK-NOT: xxsel
701 ; CHECK: vabsdub v2, v2, v3
702 ; CHECK-NEXT: blr
703 ; CHECK-PWR8-LABEL: absd_int8_ult
704 ; CHECK-PWR8: vcmpgtub
705 ; CHECK-PWR8: xxsel
706 ; CHECK-PWR8: blr
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
714   ret <16 x i8> %6
715 ; CHECK-LABEL: absd_int8_ule
716 ; CHECK-NOT: vcmpgtub
717 ; CHECK-NOT: xxsel
718 ; CHECK: vabsdub v2, v2, v3
719 ; CHECK-NEXT: blr
720 ; CHECK-PWR8-LABEL: absd_int8_ule
721 ; CHECK-PWR8: vcmpgtub
722 ; CHECK-PWR8: xxsel
723 ; CHECK-PWR8: blr
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
733   ret <4 x i32> %6
734 ; CHECK-LABEL: absd_int32_ugt_opp
735 ; CHECK-NOT: vabsduw
736 ; CHECK: vcmpgtuw
737 ; CHECK: xxsel
738 ; CHECK: blr
739 ; CHECK-PWR8-LABEL: absd_int32_ugt_opp
740 ; CHECK-PWR8: vcmpgtuw
741 ; CHECK-PWR8: xxsel
742 ; CHECK-PWR8: blr
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
750   ret <2 x i64> %6
751 ; CHECK-LABEL: absd_int64_ugt
752 ; CHECK-NOT: vabsduw
753 ; CHECK: vcmpgtud
754 ; CHECK: xxsel
755 ; CHECK: blr
756 ; CHECK-PWR8-LABEL: absd_int64_ugt
757 ; CHECK-PWR8: vcmpgtud
758 ; CHECK-PWR8: xxsel
759 ; CHECK-PWR8: blr
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>)