[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / unordered-compare-and-ordered.ll
blobec015e8ad2aaa01d41f891e401c018778a80eb38
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 define i1 @fcmp_ord_and_uno(half %x, half %y) {
5 ; CHECK-LABEL: @fcmp_ord_and_uno(
6 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
7 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno half [[X]], [[Y:%.*]]
8 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UNO]]
9 ; CHECK-NEXT:    ret i1 [[AND]]
11   %ord = fcmp ord half %x, 0.0
12   %uno = fcmp uno half %x, %y
13   %and = and i1 %ord, %uno
14   ret i1 %and
17 define i1 @fcmp_ord_and_ueq(half %x, half %y) {
18 ; CHECK-LABEL: @fcmp_ord_and_ueq(
19 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
20 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
21 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
22 ; CHECK-NEXT:    ret i1 [[AND]]
24   %ord = fcmp ord half %x, 0.0
25   %ueq = fcmp ueq half %x, %y
26   %and = and i1 %ord, %ueq
27   ret i1 %and
30 define i1 @fcmp_ord_and_ugt(half %x, half %y) {
31 ; CHECK-LABEL: @fcmp_ord_and_ugt(
32 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
33 ; CHECK-NEXT:    [[UGT:%.*]] = fcmp ugt half [[X]], [[Y:%.*]]
34 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UGT]]
35 ; CHECK-NEXT:    ret i1 [[AND]]
37   %ord = fcmp ord half %x, 0.0
38   %ugt = fcmp ugt half %x, %y
39   %and = and i1 %ord, %ugt
40   ret i1 %and
43 define i1 @fcmp_ord_and_uge(half %x, half %y) {
44 ; CHECK-LABEL: @fcmp_ord_and_uge(
45 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
46 ; CHECK-NEXT:    [[UGE:%.*]] = fcmp uge half [[X]], [[Y:%.*]]
47 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UGE]]
48 ; CHECK-NEXT:    ret i1 [[AND]]
50   %ord = fcmp ord half %x, 0.0
51   %uge = fcmp uge half %x, %y
52   %and = and i1 %ord, %uge
53   ret i1 %and
56 define i1 @fcmp_ord_and_ult(half %x, half %y) {
57 ; CHECK-LABEL: @fcmp_ord_and_ult(
58 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
59 ; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]]
60 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[ULT]]
61 ; CHECK-NEXT:    ret i1 [[AND]]
63   %ord = fcmp ord half %x, 0.0
64   %ult = fcmp ult half %x, %y
65   %and = and i1 %ord, %ult
66   ret i1 %and
69 define i1 @fcmp_ord_and_ule(half %x, half %y) {
70 ; CHECK-LABEL: @fcmp_ord_and_ule(
71 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
72 ; CHECK-NEXT:    [[ULE:%.*]] = fcmp ule half [[X]], [[Y:%.*]]
73 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[ULE]]
74 ; CHECK-NEXT:    ret i1 [[AND]]
76   %ord = fcmp ord half %x, 0.0
77   %ule = fcmp ule half %x, %y
78   %and = and i1 %ord, %ule
79   ret i1 %and
82 define i1 @fcmp_ord_and_une(half %x, half %y) {
83 ; CHECK-LABEL: @fcmp_ord_and_une(
84 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
85 ; CHECK-NEXT:    [[UNE:%.*]] = fcmp une half [[X]], [[Y:%.*]]
86 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UNE]]
87 ; CHECK-NEXT:    ret i1 [[AND]]
89   %ord = fcmp ord half %x, 0.0
90   %une = fcmp une half %x, %y
91   %and = and i1 %ord, %une
92   ret i1 %and
95 define i1 @fcmp_ord_and_true(half %x, half %y) {
96 ; CHECK-LABEL: @fcmp_ord_and_true(
97 ; CHECK-NEXT:    [[UNE:%.*]] = fcmp une half [[X:%.*]], [[Y:%.*]]
98 ; CHECK-NEXT:    ret i1 [[UNE]]
100   %ord = fcmp true half %x, 0.0
101   %une = fcmp une half %x, %y
102   %and = and i1 %ord, %une
103   ret i1 %and
106 define <2 x i1> @fcmp_ord_and_ueq_vector(<2 x half> %x, <2 x half> %y) {
107 ; CHECK-LABEL: @fcmp_ord_and_ueq_vector(
108 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord <2 x half> [[X:%.*]], zeroinitializer
109 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq <2 x half> [[X]], [[Y:%.*]]
110 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]]
111 ; CHECK-NEXT:    ret <2 x i1> [[AND]]
113   %ord = fcmp ord <2 x half> %x, zeroinitializer
114   %ueq = fcmp ueq <2 x half> %x, %y
115   %and = and <2 x i1> %ord, %ueq
116   ret <2 x i1> %and
119 ; Negative test
120 define i1 @fcmp_ord_and_ueq_different_value0(half %x, half %y, half %z) {
121 ; CHECK-LABEL: @fcmp_ord_and_ueq_different_value0(
122 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
123 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Z:%.*]], [[Y:%.*]]
124 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
125 ; CHECK-NEXT:    ret i1 [[AND]]
127   %ord = fcmp ord half %x, 0.0
128   %ueq = fcmp ueq half %z, %y
129   %and = and i1 %ord, %ueq
130   ret i1 %and
133 ; Negative test
134 define i1 @fcmp_ord_and_ueq_different_value1(half %x, half %y, half %z) {
135 ; CHECK-LABEL: @fcmp_ord_and_ueq_different_value1(
136 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
137 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[Z:%.*]]
138 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
139 ; CHECK-NEXT:    ret i1 [[AND]]
141   %ord = fcmp ord half %x, 0.0
142   %ueq = fcmp ueq half %y, %z
143   %and = and i1 %ord, %ueq
144   ret i1 %and
147 declare half @foo()
149 define i1 @fcmp_ord_and_ueq_commute0() {
150 ; CHECK-LABEL: @fcmp_ord_and_ueq_commute0(
151 ; CHECK-NEXT:    [[X:%.*]] = call half @foo()
152 ; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
153 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
154 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]]
155 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[UEQ]], [[ORD]]
156 ; CHECK-NEXT:    ret i1 [[AND]]
158   %x = call half @foo()
159   %y = call half @foo()
160   %ord = fcmp ord half %x, 0.0
161   %ueq = fcmp ueq half %x, %y
162   %and = and i1 %ueq, %ord
163   ret i1 %and
166 define i1 @fcmp_ord_and_ueq_commute1() {
167 ; CHECK-LABEL: @fcmp_ord_and_ueq_commute1(
168 ; CHECK-NEXT:    [[X:%.*]] = call half @foo()
169 ; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
170 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
171 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]]
172 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
173 ; CHECK-NEXT:    ret i1 [[AND]]
175   %x = call half @foo()
176   %y = call half @foo()
177   %ord = fcmp ord half %x, 0.0
178   %ueq = fcmp ueq half %x, %y
179   %and = and i1 %ord, %ueq
180   ret i1 %and
183 define i1 @fcmp_oeq_x_x_and_ult(half %x, half %y) {
184 ; CHECK-LABEL: @fcmp_oeq_x_x_and_ult(
185 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
186 ; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]]
187 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[ULT]]
188 ; CHECK-NEXT:    ret i1 [[AND]]
190   %ord = fcmp oeq half %x, %x ; noncanonical ordered
191   %ult = fcmp ult half %x, %y
192   %and = and i1 %ord, %ult
193   ret i1 %and
196 define i1 @fcmp_ord_and_ueq_preserve_flags(half %x, half %y) {
197 ; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_flags(
198 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000
199 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]]
200 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
201 ; CHECK-NEXT:    ret i1 [[AND]]
203   %ord = fcmp nsz ord half %x, 0.0
204   %ueq = fcmp nsz ueq half %x, %y
205   %and = and i1 %ord, %ueq
206   ret i1 %and
209 define i1 @fcmp_ord_and_ueq_preserve_subset_flags0(half %x, half %y) {
210 ; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags0(
211 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000
212 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ninf nsz ueq half [[X]], [[Y:%.*]]
213 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
214 ; CHECK-NEXT:    ret i1 [[AND]]
216   %ord = fcmp nsz ord half %x, 0.0
217   %ueq = fcmp ninf nsz ueq half %x, %y
218   %and = and i1 %ord, %ueq
219   ret i1 %and
222 define i1 @fcmp_ord_and_ueq_preserve_subset_flags1(half %x, half %y) {
223 ; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags1(
224 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ninf nsz ord half [[X:%.*]], 0xH0000
225 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]]
226 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
227 ; CHECK-NEXT:    ret i1 [[AND]]
229   %ord = fcmp ninf nsz ord half %x, 0.0
230   %ueq = fcmp nsz ueq half %x, %y
231   %and = and i1 %ord, %ueq
232   ret i1 %and
235 define i1 @fcmp_ord_and_ueq_flags_lhs(half %x, half %y) {
236 ; CHECK-LABEL: @fcmp_ord_and_ueq_flags_lhs(
237 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000
238 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
239 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
240 ; CHECK-NEXT:    ret i1 [[AND]]
242   %ord = fcmp nsz ord half %x, 0.0
243   %ueq = fcmp ueq half %x, %y
244   %and = and i1 %ord, %ueq
245   ret i1 %and
248 define i1 @fcmp_ord_and_ueq_flags_rhs(half %x, half %y) {
249 ; CHECK-LABEL: @fcmp_ord_and_ueq_flags_rhs(
250 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
251 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]]
252 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
253 ; CHECK-NEXT:    ret i1 [[AND]]
255   %ord = fcmp ord half %x, 0.0
256   %ueq = fcmp nsz ueq half %x, %y
257   %and = and i1 %ord, %ueq
258   ret i1 %and
261 ; Can ignore fabs and fneg
262 define i1 @fcmp_ord_and_fabs_ueq(half %x, half %y) {
263 ; CHECK-LABEL: @fcmp_ord_and_fabs_ueq(
264 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
265 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
266 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]]
267 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
268 ; CHECK-NEXT:    ret i1 [[AND]]
270   %fabs.x = call half @llvm.fabs.f16(half %x)
271   %ord = fcmp ord half %x, 0.0
272   %ueq = fcmp ueq half %fabs.x, %y
273   %and = and i1 %ord, %ueq
274   ret i1 %and
277 define i1 @fcmp_ord_fabs_and_ueq(half %x, half %y) {
278 ; CHECK-LABEL: @fcmp_ord_fabs_and_ueq(
279 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
280 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
281 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
282 ; CHECK-NEXT:    ret i1 [[AND]]
284   %fabs.x = call half @llvm.fabs.f16(half %x)
285   %ord = fcmp ord half %fabs.x, 0.0
286   %ueq = fcmp ueq half %x, %y
287   %and = and i1 %ord, %ueq
288   ret i1 %and
291 define i1 @fcmp_ord_and_fabs_ueq_commute0() {
292 ; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_commute0(
293 ; CHECK-NEXT:    [[X:%.*]] = call half @foo()
294 ; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
295 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X]])
296 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
297 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y]], [[FABS_X]]
298 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
299 ; CHECK-NEXT:    ret i1 [[AND]]
301   %x = call half @foo()
302   %y = call half @foo()
303   %fabs.x = call half @llvm.fabs.f16(half %x)
304   %ord = fcmp ord half %x, 0.0
305   %ueq = fcmp ueq half %y, %fabs.x
306   %and = and i1 %ord, %ueq
307   ret i1 %and
310 define i1 @fcmp_ord_and_fabs_ueq_commute1() {
311 ; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_commute1(
312 ; CHECK-NEXT:    [[X:%.*]] = call half @foo()
313 ; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
314 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X]])
315 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
316 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y]], [[FABS_X]]
317 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[UEQ]], [[ORD]]
318 ; CHECK-NEXT:    ret i1 [[AND]]
320   %x = call half @foo()
321   %y = call half @foo()
322   %fabs.x = call half @llvm.fabs.f16(half %x)
323   %ord = fcmp ord half %x, 0.0
324   %ueq = fcmp ueq half %y, %fabs.x
325   %and = and i1 %ueq, %ord
326   ret i1 %and
329 define <2 x i1> @fcmp_ord_and_fabs_ueq_vector(<2 x half> %x, <2 x half> %y) {
330 ; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_vector(
331 ; CHECK-NEXT:    [[FABS_X:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
332 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord <2 x half> [[X]], zeroinitializer
333 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq <2 x half> [[FABS_X]], [[Y:%.*]]
334 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]]
335 ; CHECK-NEXT:    ret <2 x i1> [[AND]]
337   %fabs.x = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
338   %ord = fcmp ord <2 x half> %x, zeroinitializer
339   %ueq = fcmp ueq <2 x half> %fabs.x, %y
340   %and = and <2 x i1> %ord, %ueq
341   ret <2 x i1> %and
344 define i1 @fcmp_ord_fabs_and_fabs_ueq(half %x, half %y) {
345 ; CHECK-LABEL: @fcmp_ord_fabs_and_fabs_ueq(
346 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
347 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
348 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]]
349 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
350 ; CHECK-NEXT:    ret i1 [[AND]]
352   %fabs.x = call half @llvm.fabs.f16(half %x)
353   %ord = fcmp ord half %fabs.x, 0.0
354   %ueq = fcmp ueq half %fabs.x, %y
355   %and = and i1 %ord, %ueq
356   ret i1 %and
359 define i1 @fcmp_ord_and_fneg_ueq(half %x, half %y) {
360 ; CHECK-LABEL: @fcmp_ord_and_fneg_ueq(
361 ; CHECK-NEXT:    [[FNEG_X:%.*]] = fneg half [[X:%.*]]
362 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
363 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[FNEG_X]]
364 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
365 ; CHECK-NEXT:    ret i1 [[AND]]
367   %fneg.x = fneg half %x
368   %ord = fcmp ord half %x, 0.0
369   %ueq = fcmp ueq half %fneg.x, %y
370   %and = and i1 %ord, %ueq
371   ret i1 %and
374 define i1 @fcmp_ord_fneg_and_ueq(half %x, half %y) {
375 ; CHECK-LABEL: @fcmp_ord_fneg_and_ueq(
376 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
377 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
378 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
379 ; CHECK-NEXT:    ret i1 [[AND]]
381   %fneg.x = fneg half %x
382   %ord = fcmp ord half %fneg.x, 0.0
383   %ueq = fcmp ueq half %x, %y
384   %and = and i1 %ord, %ueq
385   ret i1 %and
388 define i1 @fcmp_ord_fneg_and_fneg_ueq(half %x, half %y) {
389 ; CHECK-LABEL: @fcmp_ord_fneg_and_fneg_ueq(
390 ; CHECK-NEXT:    [[FNEG_X:%.*]] = fneg half [[X:%.*]]
391 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
392 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[FNEG_X]]
393 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
394 ; CHECK-NEXT:    ret i1 [[AND]]
396   %fneg.x = fneg half %x
397   %ord = fcmp ord half %fneg.x, 0.0
398   %ueq = fcmp ueq half %fneg.x, %y
399   %and = and i1 %ord, %ueq
400   ret i1 %and
403 define i1 @fcmp_ord_and_fneg_fabs_ueq(half %x, half %y) {
404 ; CHECK-LABEL: @fcmp_ord_and_fneg_fabs_ueq(
405 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
406 ; CHECK-NEXT:    [[FNEG_FABS_X:%.*]] = fneg half [[FABS_X]]
407 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
408 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[FNEG_FABS_X]]
409 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
410 ; CHECK-NEXT:    ret i1 [[AND]]
412   %fabs.x = call half @llvm.fabs.f16(half %x)
413   %fneg.fabs.x = fneg half %fabs.x
414   %ord = fcmp ord half %x, 0.0
415   %ueq = fcmp ueq half %fneg.fabs.x, %y
416   %and = and i1 %ord, %ueq
417   ret i1 %and
420 define i1 @fcmp_ord_and_copysign_ueq(half %x, half %y, half %z) {
421 ; CHECK-LABEL: @fcmp_ord_and_copysign_ueq(
422 ; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
423 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
424 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]]
425 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
426 ; CHECK-NEXT:    ret i1 [[AND]]
428   %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
429   %ord = fcmp ord half %x, 0.0
430   %ueq = fcmp ueq half %copysign.x.y, %y
431   %and = and i1 %ord, %ueq
432   ret i1 %and
435 define i1 @fcmp_copysign_ord_and_ueq(half %x, half %y, half %z) {
436 ; CHECK-LABEL: @fcmp_copysign_ord_and_ueq(
437 ; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
438 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[COPYSIGN_X_Y]], 0xH0000
439 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
440 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
441 ; CHECK-NEXT:    ret i1 [[AND]]
443   %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
444   %ord = fcmp ord half %copysign.x.y, 0.0
445   %ueq = fcmp ueq half %x, %y
446   %and = and i1 %ord, %ueq
447   ret i1 %and
450 define i1 @fcmp_ord_and_copysign_ueq_commute(half %x, half %y, half %z) {
451 ; CHECK-LABEL: @fcmp_ord_and_copysign_ueq_commute(
452 ; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
453 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
454 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[COPYSIGN_X_Y]]
455 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
456 ; CHECK-NEXT:    ret i1 [[AND]]
458   %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
459   %ord = fcmp ord half %x, 0.0
460   %ueq = fcmp ueq half %y, %copysign.x.y
461   %and = and i1 %ord, %ueq
462   ret i1 %and
465 define i1 @fcmp_ord_and_copysign_fneg_ueq(half %x, half %y, half %z) {
466 ; CHECK-LABEL: @fcmp_ord_and_copysign_fneg_ueq(
467 ; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
468 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
469 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]]
470 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
471 ; CHECK-NEXT:    ret i1 [[AND]]
473   %x.fneg = fneg half %x
474   %copysign.x.y = call half @llvm.copysign.f16(half %x.fneg, half %z)
475   %ord = fcmp ord half %x, 0.0
476   %ueq = fcmp ueq half %copysign.x.y, %y
477   %and = and i1 %ord, %ueq
478   ret i1 %and
481 define i1 @fcmp_ord_and_fneg_copysign_ueq(half %x, half %y, half %z) {
482 ; CHECK-LABEL: @fcmp_ord_and_fneg_copysign_ueq(
483 ; CHECK-NEXT:    [[TMP1:%.*]] = fneg half [[Z:%.*]]
484 ; CHECK-NEXT:    [[FNEG_COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[TMP1]])
485 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
486 ; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FNEG_COPYSIGN]], [[Y:%.*]]
487 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
488 ; CHECK-NEXT:    ret i1 [[AND]]
490   %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
491   %fneg.copysign = fneg half %copysign.x.y
492   %ord = fcmp ord half %x, 0.0
493   %ueq = fcmp ueq half %fneg.copysign, %y
494   %and = and i1 %ord, %ueq
495   ret i1 %and
499 declare half @llvm.fabs.f16(half)
500 declare <2 x half> @llvm.fabs.v2f16(<2 x half>)
501 declare half @llvm.copysign.f16(half, half)
502 declare <2 x half> @llvm.copysign.v2f16(<2 x half>, <2 x half>)