xref: /llvm-project/llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll (revision a105877646d68e48cdeeeadd9d1e075dc3c5d68d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4define 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]]
10;
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
15}
16
17define 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]]
23;
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
28}
29
30define 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]]
36;
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
41}
42
43define 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]]
49;
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
54}
55
56define 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]]
62;
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
67}
68
69define 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]]
75;
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
80}
81
82define 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]]
88;
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
93}
94
95define 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]]
99;
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
104}
105
106define <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]]
112;
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
117}
118
119; Negative test
120define 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]]
126;
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
131}
132
133; Negative test
134define 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]]
140;
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
145}
146
147declare half @foo()
148
149define 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]]
157;
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
164}
165
166define 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]]
174;
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
181}
182
183define 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]]
189;
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
194}
195
196define 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]]
202;
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
207}
208
209define 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]]
215;
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
220}
221
222define 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]]
228;
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
233}
234
235define 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]]
241;
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
246}
247
248define 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]]
254;
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
259}
260
261; Can ignore fabs and fneg
262define 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]]
269;
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
275}
276
277define 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]]
283;
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
289}
290
291define 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]]
300;
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
308}
309
310define 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]]
319;
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
327}
328
329define <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]]
336;
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
342}
343
344define 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]]
351;
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
357}
358
359define 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]]
366;
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
372}
373
374define 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]]
380;
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
386}
387
388define 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]]
395;
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
401}
402
403define 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]]
411;
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
418}
419
420define 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]]
427;
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
433}
434
435define 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]]
442;
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
448}
449
450define 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]]
457;
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
463}
464
465define 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]]
472;
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
479}
480
481define 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]]
489;
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
496}
497
498
499declare half @llvm.fabs.f16(half)
500declare <2 x half> @llvm.fabs.v2f16(<2 x half>)
501declare half @llvm.copysign.f16(half, half)
502declare <2 x half> @llvm.copysign.v2f16(<2 x half>, <2 x half>)
503