xref: /llvm-project/llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4define i1 @f32_fcnan_fcinf(float %a) {
5; CHECK-LABEL: define i1 @f32_fcnan_fcinf(
6; CHECK-SAME: float [[A:%.*]]) {
7; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])
8; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[TMP1]], 0x7FF0000000000000
9; CHECK-NEXT:    ret i1 [[CMP]]
10;
11  %i32 = bitcast float %a to i32
12  %and = and i32 %i32, 2139095040
13  %cmp = icmp eq i32 %and, 2139095040
14  ret i1 %cmp
15}
16
17define i1 @f32_fcnan_fcinf_strictfp(float %a) strictfp {
18; CHECK-LABEL: define i1 @f32_fcnan_fcinf_strictfp(
19; CHECK-SAME: float [[A:%.*]]) #[[ATTR0:[0-9]+]] {
20; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 519)
21; CHECK-NEXT:    ret i1 [[CMP]]
22;
23  %i32 = bitcast float %a to i32
24  %and = and i32 %i32, 2139095040
25  %cmp = icmp eq i32 %and, 2139095040
26  ret i1 %cmp
27}
28
29define i1 @f32_not_fcnan_fcinf(float %a) {
30; CHECK-LABEL: define i1 @f32_not_fcnan_fcinf(
31; CHECK-SAME: float [[A:%.*]]) {
32; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])
33; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[TMP1]], 0x7FF0000000000000
34; CHECK-NEXT:    ret i1 [[CMP]]
35;
36  %i32 = bitcast float %a to i32
37  %and = and i32 %i32, 2139095040
38  %cmp = icmp ne i32 %and, 2139095040
39  ret i1 %cmp
40}
41
42define i1 @f32_not_fcnan_fcinf_strictfp(float %a) strictfp {
43; CHECK-LABEL: define i1 @f32_not_fcnan_fcinf_strictfp(
44; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
45; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 504)
46; CHECK-NEXT:    ret i1 [[CMP]]
47;
48  %i32 = bitcast float %a to i32
49  %and = and i32 %i32, 2139095040
50  %cmp = icmp ne i32 %and, 2139095040
51  ret i1 %cmp
52}
53
54define i1 @f64_fcnan_fcinf(double %a) {
55; CHECK-LABEL: define i1 @f64_fcnan_fcinf(
56; CHECK-SAME: double [[A:%.*]]) {
57; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[A]])
58; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[TMP1]], 0x7FF0000000000000
59; CHECK-NEXT:    ret i1 [[CMP]]
60;
61  %i64 = bitcast double %a to i64
62  %and = and i64 %i64, 9218868437227405312
63  %cmp = icmp eq i64 %and, 9218868437227405312
64  ret i1 %cmp
65}
66
67define i1 @f64_fcnan_fcinf_strictfp(double %a) strictfp {
68; CHECK-LABEL: define i1 @f64_fcnan_fcinf_strictfp(
69; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] {
70; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f64(double [[A]], i32 519)
71; CHECK-NEXT:    ret i1 [[CMP]]
72;
73  %i64 = bitcast double %a to i64
74  %and = and i64 %i64, 9218868437227405312
75  %cmp = icmp eq i64 %and, 9218868437227405312
76  ret i1 %cmp
77}
78
79define i1 @f32_fcinf(float %a) {
80; CHECK-LABEL: define i1 @f32_fcinf(
81; CHECK-SAME: float [[A:%.*]]) {
82; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])
83; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[TMP1]], 0x7FF0000000000000
84; CHECK-NEXT:    ret i1 [[CMP]]
85;
86  %i32 = bitcast float %a to i32
87  %and = and i32 %i32, 2147483647
88  %cmp = icmp eq i32 %and, 2139095040
89  ret i1 %cmp
90}
91
92define i1 @f32_fcinf_strictfp(float %a) strictfp {
93; CHECK-LABEL: define i1 @f32_fcinf_strictfp(
94; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
95; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 516)
96; CHECK-NEXT:    ret i1 [[CMP]]
97;
98  %i32 = bitcast float %a to i32
99  %and = and i32 %i32, 2147483647
100  %cmp = icmp eq i32 %and, 2139095040
101  ret i1 %cmp
102}
103
104define i1 @f32_fcposinf(float %a) {
105; CHECK-LABEL: define i1 @f32_fcposinf(
106; CHECK-SAME: float [[A:%.*]]) {
107; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A]], 0x7FF0000000000000
108; CHECK-NEXT:    ret i1 [[CMP]]
109;
110  %i32 = bitcast float %a to i32
111  %cmp = icmp eq i32 %i32, 2139095040
112  ret i1 %cmp
113}
114
115define i1 @f32_fcposinf_strictfp(float %a) strictfp {
116; CHECK-LABEL: define i1 @f32_fcposinf_strictfp(
117; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
118; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 512)
119; CHECK-NEXT:    ret i1 [[CMP]]
120;
121  %i32 = bitcast float %a to i32
122  %cmp = icmp eq i32 %i32, 2139095040
123  ret i1 %cmp
124}
125
126define i1 @f32_fcneginf(float %a) {
127; CHECK-LABEL: define i1 @f32_fcneginf(
128; CHECK-SAME: float [[A:%.*]]) {
129; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A]], 0xFFF0000000000000
130; CHECK-NEXT:    ret i1 [[CMP]]
131;
132  %i32 = bitcast float %a to i32
133  %cmp = icmp eq i32 %i32, 4286578688
134  ret i1 %cmp
135}
136
137define i1 @f32_fcneginf_strictfp(float %a) strictfp {
138; CHECK-LABEL: define i1 @f32_fcneginf_strictfp(
139; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
140; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 4)
141; CHECK-NEXT:    ret i1 [[CMP]]
142;
143  %i32 = bitcast float %a to i32
144  %cmp = icmp eq i32 %i32, 4286578688
145  ret i1 %cmp
146}
147
148define i1 @f32_fcposzero(float %a) {
149; CHECK-LABEL: define i1 @f32_fcposzero(
150; CHECK-SAME: float [[A:%.*]]) {
151; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)
152; CHECK-NEXT:    ret i1 [[CMP]]
153;
154  %i32 = bitcast float %a to i32
155  %cmp = icmp eq i32 %i32, 0
156  ret i1 %cmp
157}
158
159define i1 @f32_fcposzero_strictfp(float %a) strictfp {
160; CHECK-LABEL: define i1 @f32_fcposzero_strictfp(
161; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
162; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)
163; CHECK-NEXT:    ret i1 [[CMP]]
164;
165  %i32 = bitcast float %a to i32
166  %cmp = icmp eq i32 %i32, 0
167  ret i1 %cmp
168}
169
170define i1 @f32_fcnegzero(float %a) {
171; CHECK-LABEL: define i1 @f32_fcnegzero(
172; CHECK-SAME: float [[A:%.*]]) {
173; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)
174; CHECK-NEXT:    ret i1 [[CMP]]
175;
176  %i32 = bitcast float %a to i32
177  %cmp = icmp eq i32 %i32, 2147483648
178  ret i1 %cmp
179}
180
181define i1 @f32_fcnegzero_strictfp(float %a) strictfp {
182; CHECK-LABEL: define i1 @f32_fcnegzero_strictfp(
183; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
184; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)
185; CHECK-NEXT:    ret i1 [[CMP]]
186;
187  %i32 = bitcast float %a to i32
188  %cmp = icmp eq i32 %i32, 2147483648
189  ret i1 %cmp
190}
191
192define i1 @f32_fczero(float %a) {
193; CHECK-LABEL: define i1 @f32_fczero(
194; CHECK-SAME: float [[A:%.*]]) {
195; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00
196; CHECK-NEXT:    ret i1 [[CMP]]
197;
198  %i32 = bitcast float %a to i32
199  %and = and i32 %i32, 2147483647
200  %cmp = icmp eq i32 %and, 0
201  ret i1 %cmp
202}
203
204define i1 @f32_fczero_strictfp(float %a) strictfp {
205; CHECK-LABEL: define i1 @f32_fczero_strictfp(
206; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
207; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 96)
208; CHECK-NEXT:    ret i1 [[CMP]]
209;
210  %i32 = bitcast float %a to i32
211  %and = and i32 %i32, 2147483647
212  %cmp = icmp eq i32 %and, 0
213  ret i1 %cmp
214}
215
216; TODO: handle more fpclass check idioms
217define i1 @f32_fcnan(float %a) {
218; CHECK-LABEL: define i1 @f32_fcnan(
219; CHECK-SAME: float [[A:%.*]]) {
220; CHECK-NEXT:    [[RES:%.*]] = fcmp uno float [[A]], 0.000000e+00
221; CHECK-NEXT:    ret i1 [[RES]]
222;
223  %i32 = bitcast float %a to i32
224  %and1 = and i32 %i32, 2139095040
225  %cmp1 = icmp eq i32 %and1, 2139095040
226  %and2 = and i32 %i32, 8388607
227  %cmp2 = icmp ne i32 %and2, 0
228  %res = and i1 %cmp1, %cmp2
229  ret i1 %res
230}
231
232define i1 @f32_fcnan_strictfp(float %a) strictfp {
233; CHECK-LABEL: define i1 @f32_fcnan_strictfp(
234; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
235; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
236; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[I32]], 2139095040
237; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND1]], 2139095040
238; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[I32]], 8388607
239; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[AND2]], 0
240; CHECK-NEXT:    [[RES:%.*]] = and i1 [[CMP1]], [[CMP2]]
241; CHECK-NEXT:    ret i1 [[RES]]
242;
243  %i32 = bitcast float %a to i32
244  %and1 = and i32 %i32, 2139095040
245  %cmp1 = icmp eq i32 %and1, 2139095040
246  %and2 = and i32 %i32, 8388607
247  %cmp2 = icmp ne i32 %and2, 0
248  %res = and i1 %cmp1, %cmp2
249  ret i1 %res
250}
251
252define <2 x i1> @f32_fcnan_fcinf_vec(<2 x float> %a) {
253; CHECK-LABEL: define <2 x i1> @f32_fcnan_fcinf_vec(
254; CHECK-SAME: <2 x float> [[A:%.*]]) {
255; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[A]])
256; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq <2 x float> [[TMP1]], splat (float 0x7FF0000000000000)
257; CHECK-NEXT:    ret <2 x i1> [[CMP]]
258;
259  %i32 = bitcast <2 x float> %a to <2 x i32>
260  %and = and <2 x i32> %i32, <i32 2139095040, i32 2139095040>
261  %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>
262  ret <2 x i1> %cmp
263}
264
265define <2 x i1> @f32_fcnan_fcinf_vec_strictfp(<2 x float> %a) strictfp {
266; CHECK-LABEL: define <2 x i1> @f32_fcnan_fcinf_vec_strictfp(
267; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {
268; CHECK-NEXT:    [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 519)
269; CHECK-NEXT:    ret <2 x i1> [[CMP]]
270;
271  %i32 = bitcast <2 x float> %a to <2 x i32>
272  %and = and <2 x i32> %i32, <i32 2139095040, i32 2139095040>
273  %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>
274  ret <2 x i1> %cmp
275}
276
277define <2 x i1> @f32_fcinf_vec(<2 x float> %a) {
278; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec(
279; CHECK-SAME: <2 x float> [[A:%.*]]) {
280; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[A]])
281; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq <2 x float> [[TMP1]], splat (float 0x7FF0000000000000)
282; CHECK-NEXT:    ret <2 x i1> [[CMP]]
283;
284  %i32 = bitcast <2 x float> %a to <2 x i32>
285  %and = and <2 x i32> %i32, <i32 2147483647, i32 2147483647>
286  %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>
287  ret <2 x i1> %cmp
288}
289
290define <2 x i1> @f32_fcinf_vec_strictfp(<2 x float> %a) strictfp {
291; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec_strictfp(
292; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {
293; CHECK-NEXT:    [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 516)
294; CHECK-NEXT:    ret <2 x i1> [[CMP]]
295;
296  %i32 = bitcast <2 x float> %a to <2 x i32>
297  %and = and <2 x i32> %i32, <i32 2147483647, i32 2147483647>
298  %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>
299  ret <2 x i1> %cmp
300}
301
302; Negative tests
303
304define i1 @f32_fcnan_fcinf_wrong_mask1(float %a) {
305; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask1(
306; CHECK-SAME: float [[A:%.*]]) {
307; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
308; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I32]], 2139095041
309; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040
310; CHECK-NEXT:    ret i1 [[CMP]]
311;
312  %i32 = bitcast float %a to i32
313  %and = and i32 %i32, 2139095041
314  %cmp = icmp eq i32 %and, 2139095040
315  ret i1 %cmp
316}
317
318define i1 @f32_fcnan_fcinf_wrong_mask1_strictfp(float %a) strictfp {
319; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask1_strictfp(
320; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
321; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
322; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I32]], 2139095041
323; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040
324; CHECK-NEXT:    ret i1 [[CMP]]
325;
326  %i32 = bitcast float %a to i32
327  %and = and i32 %i32, 2139095041
328  %cmp = icmp eq i32 %and, 2139095040
329  ret i1 %cmp
330}
331
332define i1 @f32_fcnan_fcinf_wrong_mask2(float %a) {
333; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask2(
334; CHECK-SAME: float [[A:%.*]]) {
335; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
336; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I32]], 2139095040
337; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432
338; CHECK-NEXT:    ret i1 [[CMP]]
339;
340  %i32 = bitcast float %a to i32
341  %and = and i32 %i32, 2139095040
342  %cmp = icmp eq i32 %and, 2130706432
343  ret i1 %cmp
344}
345
346define i1 @f32_fcnan_fcinf_wrong_mask2_strictfp(float %a) strictfp {
347; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask2_strictfp(
348; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
349; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
350; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I32]], 2139095040
351; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432
352; CHECK-NEXT:    ret i1 [[CMP]]
353;
354  %i32 = bitcast float %a to i32
355  %and = and i32 %i32, 2139095040
356  %cmp = icmp eq i32 %and, 2130706432
357  ret i1 %cmp
358}
359
360define i1 @f64_fcnan_fcinf_wrong_mask3(double %a) {
361; CHECK-LABEL: define i1 @f64_fcnan_fcinf_wrong_mask3(
362; CHECK-SAME: double [[A:%.*]]) {
363; CHECK-NEXT:    [[I64:%.*]] = bitcast double [[A]] to i64
364; CHECK-NEXT:    [[AND:%.*]] = and i64 [[I64]], 2139095040
365; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040
366; CHECK-NEXT:    ret i1 [[CMP]]
367;
368  %i64 = bitcast double %a to i64
369  %and = and i64 %i64, 2139095040
370  %cmp = icmp eq i64 %and, 2139095040
371  ret i1 %cmp
372}
373
374define i1 @f64_fcnan_fcinf_wrong_mask3_strictfp(double %a) strictfp {
375; CHECK-LABEL: define i1 @f64_fcnan_fcinf_wrong_mask3_strictfp(
376; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] {
377; CHECK-NEXT:    [[I64:%.*]] = bitcast double [[A]] to i64
378; CHECK-NEXT:    [[AND:%.*]] = and i64 [[I64]], 2139095040
379; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040
380; CHECK-NEXT:    ret i1 [[CMP]]
381;
382  %i64 = bitcast double %a to i64
383  %and = and i64 %i64, 2139095040
384  %cmp = icmp eq i64 %and, 2139095040
385  ret i1 %cmp
386}
387
388define i1 @f32_fcnan_fcinf_wrong_pred(float %a) {
389; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_pred(
390; CHECK-SAME: float [[A:%.*]]) {
391; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])
392; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[TMP1]], 0x7FF0000000000000
393; CHECK-NEXT:    ret i1 [[CMP]]
394;
395  %i32 = bitcast float %a to i32
396  %and = and i32 %i32, 2139095040
397  %cmp = icmp slt i32 %and, 2139095040
398  ret i1 %cmp
399}
400
401define i1 @f32_fcnan_fcinf_wrong_pred_strictfp(float %a) strictfp {
402; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_pred_strictfp(
403; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
404; CHECK-NEXT:    [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 504)
405; CHECK-NEXT:    ret i1 [[CMP]]
406;
407  %i32 = bitcast float %a to i32
408  %and = and i32 %i32, 2139095040
409  %cmp = icmp slt i32 %and, 2139095040
410  ret i1 %cmp
411}
412
413define i1 @f32_fcposzero_wrong_pred(float %a) {
414; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred(
415; CHECK-SAME: float [[A:%.*]]) {
416; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
417; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I32]], 0
418; CHECK-NEXT:    ret i1 [[CMP]]
419;
420  %i32 = bitcast float %a to i32
421  %cmp = icmp slt i32 %i32, 0
422  ret i1 %cmp
423}
424
425define i1 @f32_fcposzero_wrong_pred_strictfp(float %a) strictfp {
426; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred_strictfp(
427; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
428; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
429; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I32]], 0
430; CHECK-NEXT:    ret i1 [[CMP]]
431;
432  %i32 = bitcast float %a to i32
433  %cmp = icmp slt i32 %i32, 0
434  ret i1 %cmp
435}
436
437define i1 @f32_fcnan_fcinf_wrong_type1(<2 x float> %a) {
438; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1(
439; CHECK-SAME: <2 x float> [[A:%.*]]) {
440; CHECK-NEXT:    [[I64:%.*]] = bitcast <2 x float> [[A]] to i64
441; CHECK-NEXT:    [[AND:%.*]] = and i64 [[I64]], 2139095040
442; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040
443; CHECK-NEXT:    ret i1 [[CMP]]
444;
445  %i64 = bitcast <2 x float> %a to i64
446  %and = and i64 %i64, 2139095040
447  %cmp = icmp eq i64 %and, 2139095040
448  ret i1 %cmp
449}
450
451define i1 @f32_fcnan_fcinf_wrong_type1_strictfp(<2 x float> %a) strictfp {
452; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1_strictfp(
453; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {
454; CHECK-NEXT:    [[I64:%.*]] = bitcast <2 x float> [[A]] to i64
455; CHECK-NEXT:    [[AND:%.*]] = and i64 [[I64]], 2139095040
456; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040
457; CHECK-NEXT:    ret i1 [[CMP]]
458;
459  %i64 = bitcast <2 x float> %a to i64
460  %and = and i64 %i64, 2139095040
461  %cmp = icmp eq i64 %and, 2139095040
462  ret i1 %cmp
463}
464
465define i1 @f32_fcposinf_wrong_type1(<2 x float> %a) {
466; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1(
467; CHECK-SAME: <2 x float> [[A:%.*]]) {
468; CHECK-NEXT:    [[I64:%.*]] = bitcast <2 x float> [[A]] to i64
469; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[I64]], 2139095040
470; CHECK-NEXT:    ret i1 [[CMP]]
471;
472  %i64 = bitcast <2 x float> %a to i64
473  %cmp = icmp eq i64 %i64, 2139095040
474  ret i1 %cmp
475}
476
477define i1 @f32_fcposinf_wrong_type1_strictfp(<2 x float> %a) strictfp {
478; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1_strictfp(
479; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {
480; CHECK-NEXT:    [[I64:%.*]] = bitcast <2 x float> [[A]] to i64
481; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[I64]], 2139095040
482; CHECK-NEXT:    ret i1 [[CMP]]
483;
484  %i64 = bitcast <2 x float> %a to i64
485  %cmp = icmp eq i64 %i64, 2139095040
486  ret i1 %cmp
487}
488
489define i1 @f32_fcnan_fcinf_wrong_type2(x86_fp80 %a) {
490; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2(
491; CHECK-SAME: x86_fp80 [[A:%.*]]) {
492; CHECK-NEXT:    [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80
493; CHECK-NEXT:    [[AND:%.*]] = and i80 [[I80]], 2139095040
494; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i80 [[AND]], 2139095040
495; CHECK-NEXT:    ret i1 [[CMP]]
496;
497  %i80 = bitcast x86_fp80 %a to i80
498  %and = and i80 %i80, 2139095040
499  %cmp = icmp eq i80 %and, 2139095040
500  ret i1 %cmp
501}
502
503define i1 @f32_fcnan_fcinf_wrong_type2_strictfp(x86_fp80 %a) strictfp {
504; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2_strictfp(
505; CHECK-SAME: x86_fp80 [[A:%.*]]) #[[ATTR0]] {
506; CHECK-NEXT:    [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80
507; CHECK-NEXT:    [[AND:%.*]] = and i80 [[I80]], 2139095040
508; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i80 [[AND]], 2139095040
509; CHECK-NEXT:    ret i1 [[CMP]]
510;
511  %i80 = bitcast x86_fp80 %a to i80
512  %and = and i80 %i80, 2139095040
513  %cmp = icmp eq i80 %and, 2139095040
514  ret i1 %cmp
515}
516
517define i1 @f32_fcposzero_wrong_type2(x86_fp80 %a) {
518; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2(
519; CHECK-SAME: x86_fp80 [[A:%.*]]) {
520; CHECK-NEXT:    [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80
521; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i80 [[I80]], 0
522; CHECK-NEXT:    ret i1 [[CMP]]
523;
524  %i80 = bitcast x86_fp80 %a to i80
525  %cmp = icmp eq i80 %i80, 0
526  ret i1 %cmp
527}
528
529define i1 @f32_fcposzero_wrong_type2_strictfp(x86_fp80 %a) strictfp {
530; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2_strictfp(
531; CHECK-SAME: x86_fp80 [[A:%.*]]) #[[ATTR0]] {
532; CHECK-NEXT:    [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80
533; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i80 [[I80]], 0
534; CHECK-NEXT:    ret i1 [[CMP]]
535;
536  %i80 = bitcast x86_fp80 %a to i80
537  %cmp = icmp eq i80 %i80, 0
538  ret i1 %cmp
539}
540
541define i1 @f32_fcnan_fcinf_noimplicitfloat(float %a) #0 {
542; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat(
543; CHECK-SAME: float [[A:%.*]]) #[[ATTR1:[0-9]+]] {
544; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
545; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I32]], 2139095040
546; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040
547; CHECK-NEXT:    ret i1 [[CMP]]
548;
549  %i32 = bitcast float %a to i32
550  %and = and i32 %i32, 2139095040
551  %cmp = icmp eq i32 %and, 2139095040
552  ret i1 %cmp
553}
554
555define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(float %a) strictfp #0 {
556; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(
557; CHECK-SAME: float [[A:%.*]]) #[[ATTR2:[0-9]+]] {
558; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
559; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I32]], 2139095040
560; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040
561; CHECK-NEXT:    ret i1 [[CMP]]
562;
563  %i32 = bitcast float %a to i32
564  %and = and i32 %i32, 2139095040
565  %cmp = icmp eq i32 %and, 2139095040
566  ret i1 %cmp
567}
568
569define i1 @f32_fcposinf_noimplicitfloat(float %a) #0 {
570; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat(
571; CHECK-SAME: float [[A:%.*]]) #[[ATTR1]] {
572; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
573; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040
574; CHECK-NEXT:    ret i1 [[CMP]]
575;
576  %i32 = bitcast float %a to i32
577  %cmp = icmp eq i32 %i32, 2139095040
578  ret i1 %cmp
579}
580
581define i1 @f32_fcposinf_noimplicitfloat_strictfp(float %a) strictfp #0 {
582; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat_strictfp(
583; CHECK-SAME: float [[A:%.*]]) #[[ATTR2]] {
584; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
585; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040
586; CHECK-NEXT:    ret i1 [[CMP]]
587;
588  %i32 = bitcast float %a to i32
589  %cmp = icmp eq i32 %i32, 2139095040
590  ret i1 %cmp
591}
592
593define i1 @f32_fcposnan(float %a) {
594; CHECK-LABEL: define i1 @f32_fcposnan(
595; CHECK-SAME: float [[A:%.*]]) {
596; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
597; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095041
598; CHECK-NEXT:    ret i1 [[CMP]]
599;
600  %i32 = bitcast float %a to i32
601  %cmp = icmp eq i32 %i32, 2139095041
602  ret i1 %cmp
603}
604
605define i1 @f32_fcposnan_strictfp(float %a) strictfp {
606; CHECK-LABEL: define i1 @f32_fcposnan_strictfp(
607; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
608; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
609; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095041
610; CHECK-NEXT:    ret i1 [[CMP]]
611;
612  %i32 = bitcast float %a to i32
613  %cmp = icmp eq i32 %i32, 2139095041
614  ret i1 %cmp
615}
616
617define i1 @f32_fcposinf_multiuse(float %a) {
618; CHECK-LABEL: define i1 @f32_fcposinf_multiuse(
619; CHECK-SAME: float [[A:%.*]]) {
620; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
621; CHECK-NEXT:    call void @usei32(i32 [[I32]])
622; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040
623; CHECK-NEXT:    ret i1 [[CMP]]
624;
625  %i32 = bitcast float %a to i32
626  call void @usei32(i32 %i32)
627  %cmp = icmp eq i32 %i32, 2139095040
628  ret i1 %cmp
629}
630
631define i1 @f32_fcposinf_multiuse_strictfp(float %a) strictfp {
632; CHECK-LABEL: define i1 @f32_fcposinf_multiuse_strictfp(
633; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {
634; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[A]] to i32
635; CHECK-NEXT:    call void @usei32(i32 [[I32]])
636; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040
637; CHECK-NEXT:    ret i1 [[CMP]]
638;
639  %i32 = bitcast float %a to i32
640  call void @usei32(i32 %i32)
641  %cmp = icmp eq i32 %i32, 2139095040
642  ret i1 %cmp
643}
644
645define i1 @isnan_idiom(double %x) {
646; CHECK-LABEL: define i1 @isnan_idiom(
647; CHECK-SAME: double [[X:%.*]]) {
648; CHECK-NEXT:    [[RET:%.*]] = fcmp uno double [[X]], 0.000000e+00
649; CHECK-NEXT:    ret i1 [[RET]]
650;
651  %bits = bitcast double %x to i64
652  %mask1 = and i64 %bits, 9218868437227405312
653  %cond1 = icmp eq i64 %mask1, 9218868437227405312
654  %mask2 = and i64 %bits, 4503599627370495
655  %cond2 = icmp ne i64 %mask2, 0
656  %ret = and i1 %cond1, %cond2
657  ret i1 %ret
658}
659
660define <2 x i1> @isnan_idiom_vec(<2 x double> %x) {
661; CHECK-LABEL: define <2 x i1> @isnan_idiom_vec(
662; CHECK-SAME: <2 x double> [[X:%.*]]) {
663; CHECK-NEXT:    [[RET:%.*]] = fcmp uno <2 x double> [[X]], zeroinitializer
664; CHECK-NEXT:    ret <2 x i1> [[RET]]
665;
666  %bits = bitcast <2 x double> %x to <2 x i64>
667  %mask1 = and <2 x i64> %bits, splat(i64 9218868437227405312)
668  %cond1 = icmp eq <2 x i64> %mask1, splat(i64 9218868437227405312)
669  %mask2 = and <2 x i64> %bits, splat(i64 4503599627370495)
670  %cond2 = icmp ne <2 x i64> %mask2, zeroinitializer
671  %ret = and <2 x i1> %cond1, %cond2
672  ret <2 x i1> %ret
673}
674
675define i1 @isnan_idiom_commuted(double %x) {
676; CHECK-LABEL: define i1 @isnan_idiom_commuted(
677; CHECK-SAME: double [[X:%.*]]) {
678; CHECK-NEXT:    [[RET:%.*]] = fcmp uno double [[X]], 0.000000e+00
679; CHECK-NEXT:    ret i1 [[RET]]
680;
681  %bits = bitcast double %x to i64
682  %mask1 = and i64 %bits, 9218868437227405312
683  %cond1 = icmp eq i64 %mask1, 9218868437227405312
684  %mask2 = and i64 %bits, 4503599627370495
685  %cond2 = icmp ne i64 %mask2, 0
686  %ret = and i1 %cond2, %cond1
687  ret i1 %ret
688}
689
690define i1 @isnotnan_idiom(double %x) {
691; CHECK-LABEL: define i1 @isnotnan_idiom(
692; CHECK-SAME: double [[X:%.*]]) {
693; CHECK-NEXT:    [[RET:%.*]] = fcmp ord double [[X]], 0.000000e+00
694; CHECK-NEXT:    ret i1 [[RET]]
695;
696  %bits = bitcast double %x to i64
697  %mask1 = and i64 %bits, 9218868437227405312
698  %cond1 = icmp ne i64 %mask1, 9218868437227405312
699  %mask2 = and i64 %bits, 4503599627370495
700  %cond2 = icmp eq i64 %mask2, 0
701  %ret = or i1 %cond1, %cond2
702  ret i1 %ret
703}
704
705; negative tests
706
707define i1 @isnan_idiom_strictfp(double %x) strictfp {
708; CHECK-LABEL: define i1 @isnan_idiom_strictfp(
709; CHECK-SAME: double [[X:%.*]]) #[[ATTR0]] {
710; CHECK-NEXT:    [[BITS:%.*]] = bitcast double [[X]] to i64
711; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
712; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
713; CHECK-NEXT:    [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
714; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
715; CHECK-NEXT:    [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
716; CHECK-NEXT:    ret i1 [[RET]]
717;
718  %bits = bitcast double %x to i64
719  %mask1 = and i64 %bits, 9218868437227405312
720  %cond1 = icmp eq i64 %mask1, 9218868437227405312
721  %mask2 = and i64 %bits, 4503599627370495
722  %cond2 = icmp ne i64 %mask2, 0
723  %ret = and i1 %cond1, %cond2
724  ret i1 %ret
725}
726
727define i1 @isnan_idiom_wrong_pred1(double %x) {
728; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred1(
729; CHECK-SAME: double [[X:%.*]]) {
730; CHECK-NEXT:    [[BITS:%.*]] = bitcast double [[X]] to i64
731; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
732; CHECK-NEXT:    [[COND1:%.*]] = icmp ne i64 [[MASK1]], 9218868437227405312
733; CHECK-NEXT:    [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
734; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
735; CHECK-NEXT:    [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
736; CHECK-NEXT:    ret i1 [[RET]]
737;
738  %bits = bitcast double %x to i64
739  %mask1 = and i64 %bits, 9218868437227405312
740  %cond1 = icmp ne i64 %mask1, 9218868437227405312
741  %mask2 = and i64 %bits, 4503599627370495
742  %cond2 = icmp ne i64 %mask2, 0
743  %ret = and i1 %cond1, %cond2
744  ret i1 %ret
745}
746
747define i1 @isnan_idiom_wrong_pred2(double %x) {
748; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred2(
749; CHECK-SAME: double [[X:%.*]]) {
750; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])
751; CHECK-NEXT:    [[RET:%.*]] = fcmp oeq double [[TMP1]], 0x7FF0000000000000
752; CHECK-NEXT:    ret i1 [[RET]]
753;
754  %bits = bitcast double %x to i64
755  %mask1 = and i64 %bits, 9218868437227405312
756  %cond1 = icmp eq i64 %mask1, 9218868437227405312
757  %mask2 = and i64 %bits, 4503599627370495
758  %cond2 = icmp eq i64 %mask2, 0
759  %ret = and i1 %cond1, %cond2
760  ret i1 %ret
761}
762
763define i1 @isnan_idiom_wrong_pred3(double %x) {
764; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred3(
765; CHECK-SAME: double [[X:%.*]]) {
766; CHECK-NEXT:    [[BITS:%.*]] = bitcast double [[X]] to i64
767; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
768; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
769; CHECK-NEXT:    [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
770; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
771; CHECK-NEXT:    [[RET:%.*]] = or i1 [[COND1]], [[COND2]]
772; CHECK-NEXT:    ret i1 [[RET]]
773;
774  %bits = bitcast double %x to i64
775  %mask1 = and i64 %bits, 9218868437227405312
776  %cond1 = icmp eq i64 %mask1, 9218868437227405312
777  %mask2 = and i64 %bits, 4503599627370495
778  %cond2 = icmp ne i64 %mask2, 0
779  %ret = or i1 %cond1, %cond2
780  ret i1 %ret
781}
782
783define i1 @isnan_idiom_wrong_mask1(double %x) {
784; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask1(
785; CHECK-SAME: double [[X:%.*]]) {
786; CHECK-NEXT:    [[BITS:%.*]] = bitcast double [[X]] to i64
787; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405311
788; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405311
789; CHECK-NEXT:    ret i1 [[COND1]]
790;
791  %bits = bitcast double %x to i64
792  %mask1 = and i64 %bits, 9218868437227405311
793  %cond1 = icmp eq i64 %mask1, 9218868437227405311
794  %mask2 = and i64 %bits, 4503599627370495
795  %cond2 = icmp ne i64 %mask2, 0
796  %ret = and i1 %cond1, %cond2
797  ret i1 %ret
798}
799
800define i1 @isnan_idiom_wrong_mask2(double %x) {
801; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask2(
802; CHECK-SAME: double [[X:%.*]]) {
803; CHECK-NEXT:    [[BITS:%.*]] = bitcast double [[X]] to i64
804; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
805; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
806; CHECK-NEXT:    [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370494
807; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
808; CHECK-NEXT:    [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
809; CHECK-NEXT:    ret i1 [[RET]]
810;
811  %bits = bitcast double %x to i64
812  %mask1 = and i64 %bits, 9218868437227405312
813  %cond1 = icmp eq i64 %mask1, 9218868437227405312
814  %mask2 = and i64 %bits, 4503599627370494
815  %cond2 = icmp ne i64 %mask2, 0
816  %ret = and i1 %cond1, %cond2
817  ret i1 %ret
818}
819
820define i1 @isnan_idiom_wrong_mask3(double %x) {
821; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask3(
822; CHECK-SAME: double [[X:%.*]]) {
823; CHECK-NEXT:    [[BITS:%.*]] = bitcast double [[X]] to i64
824; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
825; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
826; CHECK-NEXT:    [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
827; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i64 [[MASK2]], 4503599627370495
828; CHECK-NEXT:    [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
829; CHECK-NEXT:    ret i1 [[RET]]
830;
831  %bits = bitcast double %x to i64
832  %mask1 = and i64 %bits, 9218868437227405312
833  %cond1 = icmp eq i64 %mask1, 9218868437227405312
834  %mask2 = and i64 %bits, 4503599627370495
835  %cond2 = icmp ne i64 %mask2, 4503599627370495
836  %ret = and i1 %cond1, %cond2
837  ret i1 %ret
838}
839
840define i1 @isnan_idiom_invalid_bitcast(<2 x float> %x) {
841; CHECK-LABEL: define i1 @isnan_idiom_invalid_bitcast(
842; CHECK-SAME: <2 x float> [[X:%.*]]) {
843; CHECK-NEXT:    [[BITS:%.*]] = bitcast <2 x float> [[X]] to i64
844; CHECK-NEXT:    [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
845; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
846; CHECK-NEXT:    [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
847; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
848; CHECK-NEXT:    [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
849; CHECK-NEXT:    ret i1 [[RET]]
850;
851  %bits = bitcast <2 x float> %x to i64
852  %mask1 = and i64 %bits, 9218868437227405312
853  %cond1 = icmp eq i64 %mask1, 9218868437227405312
854  %mask2 = and i64 %bits, 4503599627370495
855  %cond2 = icmp ne i64 %mask2, 0
856  %ret = and i1 %cond1, %cond2
857  ret i1 %ret
858}
859
860define i1 @isnan_idiom_ppc_fp128(ppc_fp128 %x) {
861; CHECK-LABEL: define i1 @isnan_idiom_ppc_fp128(
862; CHECK-SAME: ppc_fp128 [[X:%.*]]) {
863; CHECK-NEXT:    [[BITS:%.*]] = bitcast ppc_fp128 [[X]] to i128
864; CHECK-NEXT:    [[MASK1:%.*]] = and i128 [[BITS]], 170058106710732674489630815774616584192
865; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i128 [[MASK1]], 170058106710732674489630815774616584192
866; CHECK-NEXT:    [[MASK2:%.*]] = and i128 [[BITS]], 83076749736557242056487941267521535
867; CHECK-NEXT:    [[COND2:%.*]] = icmp ne i128 [[MASK2]], 0
868; CHECK-NEXT:    [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
869; CHECK-NEXT:    ret i1 [[RET]]
870;
871  %bits = bitcast ppc_fp128 %x to i128
872  %mask1 = and i128 %bits, 170058106710732674489630815774616584192
873  %cond1 = icmp eq i128 %mask1, 170058106710732674489630815774616584192
874  %mask2 = and i128 %bits, 83076749736557242056487941267521535
875  %cond2 = icmp ne i128 %mask2, 0
876  %ret = and i1 %cond1, %cond2
877  ret i1 %ret
878}
879
880declare void @usei32(i32)
881
882attributes #0 = { noimplicitfloat }
883