xref: /llvm-project/llvm/test/Transforms/InstSimplify/known-never-infinity.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -S -passes=instsimplify | FileCheck %s
3
4; largest unsigned i15 = 2^15 - 1 = 32767
5; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504
6
7define i1 @isKnownNeverInfinity_uitofp(i15 %x) {
8; CHECK-LABEL: define i1 @isKnownNeverInfinity_uitofp
9; CHECK-SAME: (i15 [[X:%.*]]) {
10; CHECK-NEXT:    ret i1 true
11;
12  %f = uitofp i15 %x to half
13  %r = fcmp une half %f, 0xH7c00
14  ret i1 %r
15}
16
17; negative test
18
19define i1 @isNotKnownNeverInfinity_uitofp(i16 %x) {
20; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_uitofp
21; CHECK-SAME: (i16 [[X:%.*]]) {
22; CHECK-NEXT:    [[F:%.*]] = uitofp i16 [[X]] to half
23; CHECK-NEXT:    [[R:%.*]] = fcmp une half [[F]], 0xH7C00
24; CHECK-NEXT:    ret i1 [[R]]
25;
26  %f = uitofp i16 %x to half
27  %r = fcmp une half %f, 0xH7c00
28  ret i1 %r
29}
30
31define i1 @isKnownNeverNegativeInfinity_uitofp(i15 %x) {
32; CHECK-LABEL: define i1 @isKnownNeverNegativeInfinity_uitofp
33; CHECK-SAME: (i15 [[X:%.*]]) {
34; CHECK-NEXT:    ret i1 false
35;
36  %f = uitofp i15 %x to half
37  %r = fcmp oeq half %f, 0xHfc00
38  ret i1 %r
39}
40
41; uitofp can't be negative, so this still works.
42
43define i1 @isNotKnownNeverNegativeInfinity_uitofp(i16 %x) {
44; CHECK-LABEL: define i1 @isNotKnownNeverNegativeInfinity_uitofp
45; CHECK-SAME: (i16 [[X:%.*]]) {
46; CHECK-NEXT:    ret i1 false
47;
48  %f = uitofp i16 %x to half
49  %r = fcmp oeq half %f, 0xHfc00
50  ret i1 %r
51}
52
53; largest magnitude signed i16 = 2^15 - 1 = 32767 --> -32768
54; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504
55
56define i1 @isKnownNeverInfinity_sitofp(i16 %x) {
57; CHECK-LABEL: define i1 @isKnownNeverInfinity_sitofp
58; CHECK-SAME: (i16 [[X:%.*]]) {
59; CHECK-NEXT:    ret i1 true
60;
61  %f = sitofp i16 %x to half
62  %r = fcmp une half %f, 0xH7c00
63  ret i1 %r
64}
65
66; negative test
67
68define i1 @isNotKnownNeverInfinity_sitofp(i17 %x) {
69; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_sitofp
70; CHECK-SAME: (i17 [[X:%.*]]) {
71; CHECK-NEXT:    [[F:%.*]] = sitofp i17 [[X]] to half
72; CHECK-NEXT:    [[R:%.*]] = fcmp une half [[F]], 0xH7C00
73; CHECK-NEXT:    ret i1 [[R]]
74;
75  %f = sitofp i17 %x to half
76  %r = fcmp une half %f, 0xH7c00
77  ret i1 %r
78}
79
80define i1 @isKnownNeverNegativeInfinity_sitofp(i16 %x) {
81; CHECK-LABEL: define i1 @isKnownNeverNegativeInfinity_sitofp
82; CHECK-SAME: (i16 [[X:%.*]]) {
83; CHECK-NEXT:    ret i1 false
84;
85  %f = sitofp i16 %x to half
86  %r = fcmp oeq half %f, 0xHfc00
87  ret i1 %r
88}
89
90; negative test
91
92define i1 @isNotKnownNeverNegativeInfinity_sitofp(i17 %x) {
93; CHECK-LABEL: define i1 @isNotKnownNeverNegativeInfinity_sitofp
94; CHECK-SAME: (i17 [[X:%.*]]) {
95; CHECK-NEXT:    [[F:%.*]] = sitofp i17 [[X]] to half
96; CHECK-NEXT:    [[R:%.*]] = fcmp oeq half [[F]], 0xHFC00
97; CHECK-NEXT:    ret i1 [[R]]
98;
99  %f = sitofp i17 %x to half
100  %r = fcmp oeq half %f, 0xHfc00
101  ret i1 %r
102}
103
104define i1 @isKnownNeverInfinity_fpext(float %x) {
105; CHECK-LABEL: define i1 @isKnownNeverInfinity_fpext
106; CHECK-SAME: (float [[X:%.*]]) {
107; CHECK-NEXT:    ret i1 true
108;
109  %a = fadd ninf float %x, 1.0
110  %e = fpext float %a to double
111  %r = fcmp une double %e, 0x7ff0000000000000
112  ret i1 %r
113}
114
115define i1 @isKnownNeverInfinity_fpext_sitofp(i16 %x) {
116; CHECK-LABEL: define i1 @isKnownNeverInfinity_fpext_sitofp
117; CHECK-SAME: (i16 [[X:%.*]]) {
118; CHECK-NEXT:    ret i1 false
119;
120  %f = sitofp i16 %x to half
121  %e = fpext half %f to double
122  %r = fcmp oeq double %e, 0xfff0000000000000
123  ret i1 %r
124}
125
126define i1 @isKnownNeverInfinity_fptrunc(double %x) {
127; CHECK-LABEL: define i1 @isKnownNeverInfinity_fptrunc
128; CHECK-SAME: (double [[X:%.*]]) {
129; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X]], 1.000000e+00
130; CHECK-NEXT:    [[E:%.*]] = fptrunc double [[A]] to float
131; CHECK-NEXT:    [[R:%.*]] = fcmp une float [[E]], 0x7FF0000000000000
132; CHECK-NEXT:    ret i1 [[R]]
133;
134  %a = fadd ninf double %x, 1.0
135  %e = fptrunc double %a to float
136  %r = fcmp une float %e, 0x7FF0000000000000
137  ret i1 %r
138}
139
140define i1 @isNotKnownNeverInfinity_fptrunc(double %unknown) {
141; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_fptrunc
142; CHECK-SAME: (double [[UNKNOWN:%.*]]) {
143; CHECK-NEXT:    [[E:%.*]] = fptrunc double [[UNKNOWN]] to float
144; CHECK-NEXT:    [[R:%.*]] = fcmp une float [[E]], 0x7FF0000000000000
145; CHECK-NEXT:    ret i1 [[R]]
146;
147  %e = fptrunc double %unknown to float
148  %r = fcmp une float %e, 0x7FF0000000000000
149  ret i1 %r
150}
151
152define i1 @isKnownNeverInfinity_canonicalize(double %x) {
153; CHECK-LABEL: define i1 @isKnownNeverInfinity_canonicalize
154; CHECK-SAME: (double [[X:%.*]]) {
155; CHECK-NEXT:    ret i1 true
156;
157  %a = fadd ninf double %x, 1.0
158  %e = call double @llvm.canonicalize.f64(double %a)
159  %r = fcmp une double %e, 0x7ff0000000000000
160  ret i1 %r
161}
162
163define i1 @isNotKnownNeverInfinity_canonicalize(double %x) {
164; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_canonicalize
165; CHECK-SAME: (double [[X:%.*]]) {
166; CHECK-NEXT:    [[E:%.*]] = call double @llvm.canonicalize.f64(double [[X]])
167; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
168; CHECK-NEXT:    ret i1 [[R]]
169;
170  %e = call double @llvm.canonicalize.f64(double %x)
171  %r = fcmp une double %e, 0x7ff0000000000000
172  ret i1 %r
173}
174
175define i1 @isKnownNeverInfinity_fabs(double %x) {
176; CHECK-LABEL: define i1 @isKnownNeverInfinity_fabs
177; CHECK-SAME: (double [[X:%.*]]) {
178; CHECK-NEXT:    ret i1 true
179;
180  %a = fadd ninf double %x, 1.0
181  %e = call double @llvm.fabs.f64(double %a)
182  %r = fcmp une double %e, 0x7ff0000000000000
183  ret i1 %r
184}
185
186define i1 @isNotKnownNeverInfinity_fabs(double %x) {
187; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_fabs
188; CHECK-SAME: (double [[X:%.*]]) {
189; CHECK-NEXT:    [[E:%.*]] = call double @llvm.fabs.f64(double [[X]])
190; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
191; CHECK-NEXT:    ret i1 [[R]]
192;
193  %e = call double @llvm.fabs.f64(double %x)
194  %r = fcmp une double %e, 0x7ff0000000000000
195  ret i1 %r
196}
197
198define i1 @isKnownNeverInfinity_fneg(double %x) {
199; CHECK-LABEL: define i1 @isKnownNeverInfinity_fneg
200; CHECK-SAME: (double [[X:%.*]]) {
201; CHECK-NEXT:    ret i1 true
202;
203  %a = fadd ninf double %x, 1.0
204  %e = fneg double %a
205  %r = fcmp une double %e, 0x7ff0000000000000
206  ret i1 %r
207}
208
209define i1 @isNotKnownNeverInfinity_fneg(double %x) {
210; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_fneg
211; CHECK-SAME: (double [[X:%.*]]) {
212; CHECK-NEXT:    [[E:%.*]] = fneg double [[X]]
213; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
214; CHECK-NEXT:    ret i1 [[R]]
215;
216  %e = fneg double %x
217  %r = fcmp une double %e, 0x7ff0000000000000
218  ret i1 %r
219}
220
221define i1 @isKnownNeverInfinity_copysign(double %x, double %sign) {
222; CHECK-LABEL: define i1 @isKnownNeverInfinity_copysign
223; CHECK-SAME: (double [[X:%.*]], double [[SIGN:%.*]]) {
224; CHECK-NEXT:    ret i1 true
225;
226  %a = fadd ninf double %x, 1.0
227  %e = call double @llvm.copysign.f64(double %a, double %sign)
228  %r = fcmp une double %e, 0x7ff0000000000000
229  ret i1 %r
230}
231
232define i1 @isNotKnownNeverInfinity_copysign(double %x, double %sign) {
233; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_copysign
234; CHECK-SAME: (double [[X:%.*]], double [[SIGN:%.*]]) {
235; CHECK-NEXT:    [[E:%.*]] = call double @llvm.copysign.f64(double [[X]], double [[SIGN]])
236; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
237; CHECK-NEXT:    ret i1 [[R]]
238;
239  %e = call double @llvm.copysign.f64(double %x, double %sign)
240  %r = fcmp une double %e, 0x7ff0000000000000
241  ret i1 %r
242}
243
244define i1 @isKnownNeverInfinity_arithmetic_fence(double %x) {
245; CHECK-LABEL: define i1 @isKnownNeverInfinity_arithmetic_fence
246; CHECK-SAME: (double [[X:%.*]]) {
247; CHECK-NEXT:    ret i1 true
248;
249  %a = fadd ninf double %x, 1.0
250  %e = call double @llvm.arithmetic.fence.f64(double %a)
251  %r = fcmp une double %e, 0x7ff0000000000000
252  ret i1 %r
253}
254
255define i1 @isNotKnownNeverInfinity_arithmetic_fence(double %x) {
256; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_arithmetic_fence
257; CHECK-SAME: (double [[X:%.*]]) {
258; CHECK-NEXT:    [[E:%.*]] = call double @llvm.arithmetic.fence.f64(double [[X]])
259; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
260; CHECK-NEXT:    ret i1 [[R]]
261;
262  %e = call double @llvm.arithmetic.fence.f64(double %x)
263  %r = fcmp une double %e, 0x7ff0000000000000
264  ret i1 %r
265}
266
267define i1 @isKnownNeverInfinity_floor(double %x) {
268; CHECK-LABEL: define i1 @isKnownNeverInfinity_floor
269; CHECK-SAME: (double [[X:%.*]]) {
270; CHECK-NEXT:    ret i1 true
271;
272  %a = fadd ninf double %x, 1.0
273  %e = call double @llvm.floor.f64(double %a)
274  %r = fcmp une double %e, 0x7ff0000000000000
275  ret i1 %r
276}
277
278define i1 @isNotKnownNeverInfinity_floor(double %x) {
279; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_floor
280; CHECK-SAME: (double [[X:%.*]]) {
281; CHECK-NEXT:    [[E:%.*]] = call double @llvm.floor.f64(double [[X]])
282; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
283; CHECK-NEXT:    ret i1 [[R]]
284;
285  %e = call double @llvm.floor.f64(double %x)
286  %r = fcmp une double %e, 0x7ff0000000000000
287  ret i1 %r
288}
289
290define i1 @isKnownNeverInfinity_ceil(double %x) {
291; CHECK-LABEL: define i1 @isKnownNeverInfinity_ceil
292; CHECK-SAME: (double [[X:%.*]]) {
293; CHECK-NEXT:    ret i1 true
294;
295  %a = fadd ninf double %x, 1.0
296  %e = call double @llvm.ceil.f64(double %a)
297  %r = fcmp une double %e, 0x7ff0000000000000
298  ret i1 %r
299}
300
301define i1 @isNotKnownNeverInfinity_ceil(double %x) {
302; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_ceil
303; CHECK-SAME: (double [[X:%.*]]) {
304; CHECK-NEXT:    [[E:%.*]] = call double @llvm.ceil.f64(double [[X]])
305; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
306; CHECK-NEXT:    ret i1 [[R]]
307;
308  %e = call double @llvm.ceil.f64(double %x)
309  %r = fcmp une double %e, 0x7ff0000000000000
310  ret i1 %r
311}
312
313define i1 @isKnownNeverInfinity_trunc(double %x) {
314; CHECK-LABEL: define i1 @isKnownNeverInfinity_trunc
315; CHECK-SAME: (double [[X:%.*]]) {
316; CHECK-NEXT:    ret i1 true
317;
318  %a = fadd ninf double %x, 1.0
319  %e = call double @llvm.trunc.f64(double %a)
320  %r = fcmp une double %e, 0x7ff0000000000000
321  ret i1 %r
322}
323
324define i1 @isNotKnownNeverInfinity_trunc(double %x) {
325; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_trunc
326; CHECK-SAME: (double [[X:%.*]]) {
327; CHECK-NEXT:    [[E:%.*]] = call double @llvm.trunc.f64(double [[X]])
328; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
329; CHECK-NEXT:    ret i1 [[R]]
330;
331  %e = call double @llvm.trunc.f64(double %x)
332  %r = fcmp une double %e, 0x7ff0000000000000
333  ret i1 %r
334}
335
336define i1 @isKnownNeverInfinity_rint(double %x) {
337; CHECK-LABEL: define i1 @isKnownNeverInfinity_rint
338; CHECK-SAME: (double [[X:%.*]]) {
339; CHECK-NEXT:    ret i1 true
340;
341  %a = fadd ninf double %x, 1.0
342  %e = call double @llvm.rint.f64(double %a)
343  %r = fcmp une double %e, 0x7ff0000000000000
344  ret i1 %r
345}
346
347define i1 @isNotKnownNeverInfinity_rint(double %x) {
348; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_rint
349; CHECK-SAME: (double [[X:%.*]]) {
350; CHECK-NEXT:    [[E:%.*]] = call double @llvm.rint.f64(double [[X]])
351; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
352; CHECK-NEXT:    ret i1 [[R]]
353;
354  %e = call double @llvm.rint.f64(double %x)
355  %r = fcmp une double %e, 0x7ff0000000000000
356  ret i1 %r
357}
358
359define i1 @isKnownNeverInfinity_nearbyint(double %x) {
360; CHECK-LABEL: define i1 @isKnownNeverInfinity_nearbyint
361; CHECK-SAME: (double [[X:%.*]]) {
362; CHECK-NEXT:    ret i1 true
363;
364  %a = fadd ninf double %x, 1.0
365  %e = call double @llvm.nearbyint.f64(double %a)
366  %r = fcmp une double %e, 0x7ff0000000000000
367  ret i1 %r
368}
369
370define i1 @isNotKnownNeverInfinity_nearbyint(double %x) {
371; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_nearbyint
372; CHECK-SAME: (double [[X:%.*]]) {
373; CHECK-NEXT:    [[E:%.*]] = call double @llvm.nearbyint.f64(double [[X]])
374; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
375; CHECK-NEXT:    ret i1 [[R]]
376;
377  %e = call double @llvm.nearbyint.f64(double %x)
378  %r = fcmp une double %e, 0x7ff0000000000000
379  ret i1 %r
380}
381
382define i1 @isKnownNeverInfinity_round(double %x) {
383; CHECK-LABEL: define i1 @isKnownNeverInfinity_round
384; CHECK-SAME: (double [[X:%.*]]) {
385; CHECK-NEXT:    ret i1 true
386;
387  %a = fadd ninf double %x, 1.0
388  %e = call double @llvm.round.f64(double %a)
389  %r = fcmp une double %e, 0x7ff0000000000000
390  ret i1 %r
391}
392
393define i1 @isNotKnownNeverInfinity_round(double %x) {
394; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_round
395; CHECK-SAME: (double [[X:%.*]]) {
396; CHECK-NEXT:    [[E:%.*]] = call double @llvm.round.f64(double [[X]])
397; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
398; CHECK-NEXT:    ret i1 [[R]]
399;
400  %e = call double @llvm.round.f64(double %x)
401  %r = fcmp une double %e, 0x7ff0000000000000
402  ret i1 %r
403}
404
405define i1 @isKnownNeverInfinity_roundeven(double %x) {
406; CHECK-LABEL: define i1 @isKnownNeverInfinity_roundeven
407; CHECK-SAME: (double [[X:%.*]]) {
408; CHECK-NEXT:    ret i1 true
409;
410  %a = fadd ninf double %x, 1.0
411  %e = call double @llvm.roundeven.f64(double %a)
412  %r = fcmp une double %e, 0x7ff0000000000000
413  ret i1 %r
414}
415
416define i1 @isNotKnownNeverInfinity_roundeven(double %x) {
417; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_roundeven
418; CHECK-SAME: (double [[X:%.*]]) {
419; CHECK-NEXT:    [[E:%.*]] = call double @llvm.roundeven.f64(double [[X]])
420; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
421; CHECK-NEXT:    ret i1 [[R]]
422;
423  %e = call double @llvm.roundeven.f64(double %x)
424  %r = fcmp une double %e, 0x7ff0000000000000
425  ret i1 %r
426}
427
428define i1 @isNotKnownNeverInfinity_fptrunc_round(double %x) {
429; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_fptrunc_round
430; CHECK-SAME: (double [[X:%.*]]) {
431; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X]], 1.000000e+00
432; CHECK-NEXT:    [[E:%.*]] = call float @llvm.fptrunc.round.f32.f64(double [[A]], metadata !"round.downward")
433; CHECK-NEXT:    [[R:%.*]] = fcmp une float [[E]], 0x7FF0000000000000
434; CHECK-NEXT:    ret i1 [[R]]
435;
436  %a = fadd ninf double %x, 1.0
437  %e = call float @llvm.fptrunc.round.f32.f64(double %a, metadata !"round.downward")
438  %r = fcmp une float %e, 0x7ff0000000000000
439  ret i1 %r
440}
441
442define i1 @isKnownNeverInfinity_floor_ppcf128(ppc_fp128 %x) {
443; CHECK-LABEL: define i1 @isKnownNeverInfinity_floor_ppcf128
444; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
445; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X]], [[X]]
446; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.floor.ppcf128(ppc_fp128 [[A]])
447; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
448; CHECK-NEXT:    ret i1 [[R]]
449;
450  %a = fadd ninf ppc_fp128 %x, %x
451  %e = call ppc_fp128 @llvm.floor.ppcf128(ppc_fp128 %a)
452  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
453  ret i1 %r
454}
455
456define i1 @isKnownNeverInfinity_ceil_ppcf128(ppc_fp128 %x) {
457; CHECK-LABEL: define i1 @isKnownNeverInfinity_ceil_ppcf128
458; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
459; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X]], [[X]]
460; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128 [[A]])
461; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
462; CHECK-NEXT:    ret i1 [[R]]
463;
464  %a = fadd ninf ppc_fp128 %x, %x
465  %e = call ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128 %a)
466  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
467  ret i1 %r
468}
469
470define i1 @isKnownNeverInfinity_rint_ppcf128(ppc_fp128 %x) {
471; CHECK-LABEL: define i1 @isKnownNeverInfinity_rint_ppcf128
472; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
473; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X]], [[X]]
474; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.rint.ppcf128(ppc_fp128 [[A]])
475; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
476; CHECK-NEXT:    ret i1 [[R]]
477;
478  %a = fadd ninf ppc_fp128 %x, %x
479  %e = call ppc_fp128 @llvm.rint.ppcf128(ppc_fp128 %a)
480  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
481  ret i1 %r
482}
483
484define i1 @isKnownNeverInfinity_nearbyint_ppcf128(ppc_fp128 %x) {
485; CHECK-LABEL: define i1 @isKnownNeverInfinity_nearbyint_ppcf128
486; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
487; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X]], [[X]]
488; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128 [[A]])
489; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
490; CHECK-NEXT:    ret i1 [[R]]
491;
492  %a = fadd ninf ppc_fp128 %x, %x
493  %e = call ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128 %a)
494  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
495  ret i1 %r
496}
497
498define i1 @isKnownNeverInfinity_round_ppcf128(ppc_fp128 %x) {
499; CHECK-LABEL: define i1 @isKnownNeverInfinity_round_ppcf128
500; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
501; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X]], [[X]]
502; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.round.ppcf128(ppc_fp128 [[A]])
503; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
504; CHECK-NEXT:    ret i1 [[R]]
505;
506  %a = fadd ninf ppc_fp128 %x, %x
507  %e = call ppc_fp128 @llvm.round.ppcf128(ppc_fp128 %a)
508  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
509  ret i1 %r
510}
511
512define i1 @isKnownNeverInfinity_roundeven_ppcf128(ppc_fp128 %x) {
513; CHECK-LABEL: define i1 @isKnownNeverInfinity_roundeven_ppcf128
514; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
515; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X]], [[X]]
516; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128 [[A]])
517; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
518; CHECK-NEXT:    ret i1 [[R]]
519;
520  %a = fadd ninf ppc_fp128 %x, %x
521  %e = call ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128 %a)
522  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
523  ret i1 %r
524}
525
526define i1 @isKnownNeverInfinity_trunc_ppcf128(ppc_fp128 %x) {
527; CHECK-LABEL: define i1 @isKnownNeverInfinity_trunc_ppcf128
528; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
529; CHECK-NEXT:    ret i1 true
530;
531  %a = fadd ninf ppc_fp128 %x, %x
532  %e = call ppc_fp128 @llvm.trunc.ppcf128(ppc_fp128 %a)
533  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
534  ret i1 %r
535}
536
537define i1 @isKnownNeverInfinity_ceil_x86_fp80(x86_fp80 %x) {
538; CHECK-LABEL: define i1 @isKnownNeverInfinity_ceil_x86_fp80
539; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
540; CHECK-NEXT:    ret i1 true
541;
542  %a = fadd ninf x86_fp80 %x, %x
543  %e = call x86_fp80 @llvm.ceil.f80(x86_fp80 %a)
544  %r = fcmp une x86_fp80 %e, 0xK7FFF8000000000000000
545  ret i1 %r
546}
547
548define i1 @isKnownNeverInfinity_minnum(double %x, double %y) {
549; CHECK-LABEL: define i1 @isKnownNeverInfinity_minnum
550; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
551; CHECK-NEXT:    ret i1 true
552;
553  %ninf.x = fadd ninf double %x, 1.0
554  %ninf.y = fadd ninf double %y, 1.0
555  %op = call double @llvm.minnum.f64(double %ninf.x, double %ninf.y)
556  %cmp = fcmp une double %op, 0x7ff0000000000000
557  ret i1 %cmp
558}
559
560define i1 @isNotKnownNeverInfinity_minnum_lhs(double %x, double %y) {
561; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_minnum_lhs
562; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
563; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
564; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.minnum.f64(double [[X]], double [[NINF_Y]])
565; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
566; CHECK-NEXT:    ret i1 [[CMP]]
567;
568  %ninf.y = fadd ninf double %y, 1.0
569  %op = call double @llvm.minnum.f64(double %x, double %ninf.y)
570  %cmp = fcmp une double %op, 0x7ff0000000000000
571  ret i1 %cmp
572}
573
574define i1 @isNotKnownNeverInfinity_minnum_rhs(double %x, double %y) {
575; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_minnum_rhs
576; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
577; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
578; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.minnum.f64(double [[NINF_X]], double [[Y]])
579; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
580; CHECK-NEXT:    ret i1 [[CMP]]
581;
582  %ninf.x = fadd ninf double %x, 1.0
583  %op = call double @llvm.minnum.f64(double %ninf.x, double %y)
584  %cmp = fcmp une double %op, 0x7ff0000000000000
585  ret i1 %cmp
586}
587
588define i1 @isKnownNeverInfinity_maxnum(double %x, double %y) {
589; CHECK-LABEL: define i1 @isKnownNeverInfinity_maxnum
590; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
591; CHECK-NEXT:    ret i1 true
592;
593  %ninf.x = fadd ninf double %x, 1.0
594  %ninf.y = fadd ninf double %y, 1.0
595  %op = call double @llvm.maxnum.f64(double %ninf.x, double %ninf.y)
596  %cmp = fcmp une double %op, 0x7ff0000000000000
597  ret i1 %cmp
598}
599
600define i1 @isNotKnownNeverInfinity_maxnum_lhs(double %x, double %y) {
601; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_maxnum_lhs
602; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
603; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
604; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.maxnum.f64(double [[X]], double [[NINF_Y]])
605; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
606; CHECK-NEXT:    ret i1 [[CMP]]
607;
608  %ninf.y = fadd ninf double %y, 1.0
609  %op = call double @llvm.maxnum.f64(double %x, double %ninf.y)
610  %cmp = fcmp une double %op, 0x7ff0000000000000
611  ret i1 %cmp
612}
613
614define i1 @isNotKnownNeverInfinity_maxnum_rhs(double %x, double %y) {
615; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_maxnum_rhs
616; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
617; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
618; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.maxnum.f64(double [[NINF_X]], double [[Y]])
619; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
620; CHECK-NEXT:    ret i1 [[CMP]]
621;
622  %ninf.x = fadd ninf double %x, 1.0
623  %op = call double @llvm.maxnum.f64(double %ninf.x, double %y)
624  %cmp = fcmp une double %op, 0x7ff0000000000000
625  ret i1 %cmp
626}
627
628define i1 @isKnownNeverInfinity_minimum(double %x, double %y) {
629; CHECK-LABEL: define i1 @isKnownNeverInfinity_minimum
630; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
631; CHECK-NEXT:    ret i1 true
632;
633  %ninf.x = fadd ninf double %x, 1.0
634  %ninf.y = fadd ninf double %y, 1.0
635  %op = call double @llvm.minimum.f64(double %ninf.x, double %ninf.y)
636  %cmp = fcmp une double %op, 0x7ff0000000000000
637  ret i1 %cmp
638}
639
640define i1 @isNotKnownNeverInfinity_minimum_lhs(double %x, double %y) {
641; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_minimum_lhs
642; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
643; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
644; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.minimum.f64(double [[X]], double [[NINF_Y]])
645; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
646; CHECK-NEXT:    ret i1 [[CMP]]
647;
648  %ninf.y = fadd ninf double %y, 1.0
649  %op = call double @llvm.minimum.f64(double %x, double %ninf.y)
650  %cmp = fcmp une double %op, 0x7ff0000000000000
651  ret i1 %cmp
652}
653
654define i1 @isNotKnownNeverInfinity_minimum_rhs(double %x, double %y) {
655; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_minimum_rhs
656; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
657; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
658; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.minimum.f64(double [[NINF_X]], double [[Y]])
659; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
660; CHECK-NEXT:    ret i1 [[CMP]]
661;
662  %ninf.x = fadd ninf double %x, 1.0
663  %op = call double @llvm.minimum.f64(double %ninf.x, double %y)
664  %cmp = fcmp une double %op, 0x7ff0000000000000
665  ret i1 %cmp
666}
667
668define i1 @isKnownNeverInfinity_maximum(double %x, double %y) {
669; CHECK-LABEL: define i1 @isKnownNeverInfinity_maximum
670; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
671; CHECK-NEXT:    ret i1 true
672;
673  %ninf.x = fadd ninf double %x, 1.0
674  %ninf.y = fadd ninf double %y, 1.0
675  %op = call double @llvm.maximum.f64(double %ninf.x, double %ninf.y)
676  %cmp = fcmp une double %op, 0x7ff0000000000000
677  ret i1 %cmp
678}
679
680define i1 @isNotKnownNeverInfinity_maximum_lhs(double %x, double %y) {
681; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_maximum_lhs
682; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
683; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
684; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.maximum.f64(double [[X]], double [[NINF_Y]])
685; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
686; CHECK-NEXT:    ret i1 [[CMP]]
687;
688  %ninf.y = fadd ninf double %y, 1.0
689  %op = call double @llvm.maximum.f64(double %x, double %ninf.y)
690  %cmp = fcmp une double %op, 0x7ff0000000000000
691  ret i1 %cmp
692}
693
694define i1 @isNotKnownNeverInfinity_maximum_rhs(double %x, double %y) {
695; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_maximum_rhs
696; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
697; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
698; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.maximum.f64(double [[NINF_X]], double [[Y]])
699; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
700; CHECK-NEXT:    ret i1 [[CMP]]
701;
702  %ninf.x = fadd ninf double %x, 1.0
703  %op = call double @llvm.maximum.f64(double %ninf.x, double %y)
704  %cmp = fcmp une double %op, 0x7ff0000000000000
705  ret i1 %cmp
706}
707
708define i1 @isKnownNeverInfinity_sqrt(double %x) {
709; CHECK-LABEL: define i1 @isKnownNeverInfinity_sqrt
710; CHECK-SAME: (double [[X:%.*]]) {
711; CHECK-NEXT:    ret i1 true
712;
713  %a = fadd ninf double %x, 1.0
714  %e = call double @llvm.sqrt.f64(double %a)
715  %r = fcmp une double %e, 0x7ff0000000000000
716  ret i1 %r
717}
718
719define i1 @isNotKnownNeverInfinity_sqrt(double %x) {
720; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_sqrt
721; CHECK-SAME: (double [[X:%.*]]) {
722; CHECK-NEXT:    [[E:%.*]] = call double @llvm.sqrt.f64(double [[X]])
723; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
724; CHECK-NEXT:    ret i1 [[R]]
725;
726  %e = call double @llvm.sqrt.f64(double %x)
727  %r = fcmp une double %e, 0x7ff0000000000000
728  ret i1 %r
729}
730
731; No source check required
732define i1 @isKnownNeverInfinity_sin(double %x) {
733; CHECK-LABEL: define i1 @isKnownNeverInfinity_sin
734; CHECK-SAME: (double [[X:%.*]]) {
735; CHECK-NEXT:    ret i1 true
736;
737  %e = call double @llvm.sin.f64(double %x)
738  %r = fcmp une double %e, 0x7ff0000000000000
739  ret i1 %r
740}
741
742; No source check required
743define i1 @isKnownNeverInfinity_cos(double %x) {
744; CHECK-LABEL: define i1 @isKnownNeverInfinity_cos
745; CHECK-SAME: (double [[X:%.*]]) {
746; CHECK-NEXT:    ret i1 true
747;
748  %e = call double @llvm.cos.f64(double %x)
749  %r = fcmp une double %e, 0x7ff0000000000000
750  ret i1 %r
751}
752
753define i1 @isKnownNeverInfinity_log(double %x) {
754; CHECK-LABEL: define i1 @isKnownNeverInfinity_log
755; CHECK-SAME: (double [[X:%.*]]) {
756; CHECK-NEXT:    ret i1 true
757;
758  %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
759  %a = fadd ninf double %x.clamp.zero, 1.0
760  %e = call double @llvm.log.f64(double %a)
761  %r = fcmp une double %e, 0x7ff0000000000000
762  ret i1 %r
763}
764
765define i1 @isNotKnownNeverInfinity_log_maybe_negative(double %x) {
766; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log_maybe_negative
767; CHECK-SAME: (double [[X:%.*]]) {
768; CHECK-NEXT:    ret i1 true
769;
770
771  %x.not.inf = fadd ninf double %x, 1.0
772  %e = call double @llvm.log.f64(double %x.not.inf)
773  %r = fcmp une double %e, 0x7ff0000000000000
774  ret i1 %r
775}
776
777define i1 @isNotKnownNeverInfinity_log_maybe_inf(double %x) {
778; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log_maybe_inf
779; CHECK-SAME: (double [[X:%.*]]) {
780; CHECK-NEXT:    [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00)
781; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log.f64(double [[X_CLAMP_ZERO]])
782; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
783; CHECK-NEXT:    ret i1 [[R]]
784;
785  %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
786  %e = call double @llvm.log.f64(double %x.clamp.zero)
787  %r = fcmp une double %e, 0x7ff0000000000000
788  ret i1 %r
789}
790
791define i1 @isKnownNeverNegInfinity_log_maybe_0(double %x) {
792; CHECK-LABEL: define i1 @isKnownNeverNegInfinity_log_maybe_0
793; CHECK-SAME: (double [[X:%.*]]) {
794; CHECK-NEXT:    [[A:%.*]] = call ninf double @llvm.sqrt.f64(double [[X]])
795; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log.f64(double [[A]])
796; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0xFFF0000000000000
797; CHECK-NEXT:    ret i1 [[R]]
798;
799  %a = call ninf double @llvm.sqrt.f64(double %x) ; could be 0.0
800  %e = call double @llvm.log.f64(double %a) ; log(0.0) --> -inf
801  %r = fcmp une double %e, 0xfff0000000000000
802  ret i1 %r
803}
804
805define i1 @isKnownNeverInfinity_log10(double %x) {
806; CHECK-LABEL: define i1 @isKnownNeverInfinity_log10
807; CHECK-SAME: (double [[X:%.*]]) {
808; CHECK-NEXT:    ret i1 true
809;
810  %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
811  %a = fadd ninf double %x.clamp.zero, 1.0
812  %e = call double @llvm.log10.f64(double %a)
813  %r = fcmp une double %e, 0x7ff0000000000000
814  ret i1 %r
815}
816
817define i1 @isNotKnownNeverInfinity_log10_maybe_negative(double %x) {
818; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log10_maybe_negative
819; CHECK-SAME: (double [[X:%.*]]) {
820; CHECK-NEXT:    ret i1 true
821;
822
823  %x.not.inf = fadd ninf double %x, 1.0
824  %e = call double @llvm.log10.f64(double %x.not.inf)
825  %r = fcmp une double %e, 0x7ff0000000000000
826  ret i1 %r
827}
828
829define i1 @isNotKnownNeverInfinity_log10_maybe_inf(double %x) {
830; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log10_maybe_inf
831; CHECK-SAME: (double [[X:%.*]]) {
832; CHECK-NEXT:    [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00)
833; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log10.f64(double [[X_CLAMP_ZERO]])
834; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
835; CHECK-NEXT:    ret i1 [[R]]
836;
837  %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
838  %e = call double @llvm.log10.f64(double %x.clamp.zero)
839  %r = fcmp une double %e, 0x7ff0000000000000
840  ret i1 %r
841}
842
843define i1 @isKnownNeverNegInfinity_log10_maybe_0(double %x) {
844; CHECK-LABEL: define i1 @isKnownNeverNegInfinity_log10_maybe_0
845; CHECK-SAME: (double [[X:%.*]]) {
846; CHECK-NEXT:    [[A:%.*]] = call ninf double @llvm.sqrt.f64(double [[X]])
847; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log10.f64(double [[A]])
848; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0xFFF0000000000000
849; CHECK-NEXT:    ret i1 [[R]]
850;
851  %a = call ninf double @llvm.sqrt.f64(double %x) ; could be 0.0
852  %e = call double @llvm.log10.f64(double %a) ; log(0.0) --> -inf
853  %r = fcmp une double %e, 0xfff0000000000000
854  ret i1 %r
855}
856
857define i1 @isKnownNeverInfinity_log2(double %x) {
858; CHECK-LABEL: define i1 @isKnownNeverInfinity_log2
859; CHECK-SAME: (double [[X:%.*]]) {
860; CHECK-NEXT:    ret i1 true
861;
862  %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
863  %a = fadd ninf double %x.clamp.zero, 1.0
864  %e = call double @llvm.log2.f64(double %a)
865  %r = fcmp une double %e, 0x7ff0000000000000
866  ret i1 %r
867}
868
869define i1 @isNotKnownNeverInfinity_log2_maybe_negative(double %x) {
870; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log2_maybe_negative
871; CHECK-SAME: (double [[X:%.*]]) {
872; CHECK-NEXT:    ret i1 true
873;
874
875  %x.not.inf = fadd ninf double %x, 1.0
876  %e = call double @llvm.log2.f64(double %x.not.inf)
877  %r = fcmp une double %e, 0x7ff0000000000000
878  ret i1 %r
879}
880
881define i1 @isNotKnownNeverInfinity_log2_maybe_inf(double %x) {
882; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log2_maybe_inf
883; CHECK-SAME: (double [[X:%.*]]) {
884; CHECK-NEXT:    [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00)
885; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log2.f64(double [[X_CLAMP_ZERO]])
886; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
887; CHECK-NEXT:    ret i1 [[R]]
888;
889  %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
890  %e = call double @llvm.log2.f64(double %x.clamp.zero)
891  %r = fcmp une double %e, 0x7ff0000000000000
892  ret i1 %r
893}
894
895define i1 @isKnownNeverNegInfinity_log2_maybe_0(double %x) {
896; CHECK-LABEL: define i1 @isKnownNeverNegInfinity_log2_maybe_0
897; CHECK-SAME: (double [[X:%.*]]) {
898; CHECK-NEXT:    [[A:%.*]] = call ninf double @llvm.sqrt.f64(double [[X]])
899; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log2.f64(double [[A]])
900; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0xFFF0000000000000
901; CHECK-NEXT:    ret i1 [[R]]
902;
903  %a = call ninf double @llvm.sqrt.f64(double %x) ; could be 0.0
904  %e = call double @llvm.log2.f64(double %a) ; log(0.0) --> -inf
905  %r = fcmp une double %e, 0xfff0000000000000
906  ret i1 %r
907}
908
909define i1 @isNotKnownNeverInfinity_pow(double %x, double %y) {
910; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_pow
911; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
912; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
913; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
914; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.pow.f64(double [[NINF_X]], double [[NINF_Y]])
915; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
916; CHECK-NEXT:    ret i1 [[CMP]]
917;
918  %ninf.x = fadd ninf double %x, 1.0
919  %ninf.y = fadd ninf double %y, 1.0
920  %op = call double @llvm.pow.f64(double %ninf.x, double %ninf.y)
921  %cmp = fcmp une double %op, 0x7ff0000000000000
922  ret i1 %cmp
923}
924
925define i1 @isNotKnownNeverInfinity_powi(double %x) {
926; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_powi
927; CHECK-SAME: (double [[X:%.*]]) {
928; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
929; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.powi.f64.i32(double [[NINF_X]], i32 2)
930; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
931; CHECK-NEXT:    ret i1 [[CMP]]
932;
933  %ninf.x = fadd ninf double %x, 1.0
934  %op = call double @llvm.powi.f64.i32(double %ninf.x, i32 2)
935  %cmp = fcmp une double %op, 0x7ff0000000000000
936  ret i1 %cmp
937}
938
939define i1 @isNotKnownNeverInfinity_exp(double %x) {
940; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_exp
941; CHECK-SAME: (double [[X:%.*]]) {
942; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X]], 1.000000e+00
943; CHECK-NEXT:    [[E:%.*]] = call double @llvm.exp.f64(double [[A]])
944; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
945; CHECK-NEXT:    ret i1 [[R]]
946;
947  %a = fadd ninf double %x, 1.0
948  %e = call double @llvm.exp.f64(double %a)
949  %r = fcmp une double %e, 0x7ff0000000000000
950  ret i1 %r
951}
952
953define i1 @isNotKnownNeverInfinity_exp2(double %x) {
954; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_exp2
955; CHECK-SAME: (double [[X:%.*]]) {
956; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X]], 1.000000e+00
957; CHECK-NEXT:    [[E:%.*]] = call double @llvm.exp2.f64(double [[A]])
958; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
959; CHECK-NEXT:    ret i1 [[R]]
960;
961  %a = fadd ninf double %x, 1.0
962  %e = call double @llvm.exp2.f64(double %a)
963  %r = fcmp une double %e, 0x7ff0000000000000
964  ret i1 %r
965}
966
967define i1 @isNotKnownNeverInfinity_fma(double %x, double %y, double %z) {
968; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_fma
969; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]], double [[Z:%.*]]) {
970; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
971; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
972; CHECK-NEXT:    [[NINF_Z:%.*]] = fadd ninf double [[Z]], 1.000000e+00
973; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.fma.f64(double [[NINF_X]], double [[NINF_Y]], double [[NINF_Z]])
974; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
975; CHECK-NEXT:    ret i1 [[CMP]]
976;
977  %ninf.x = fadd ninf double %x, 1.0
978  %ninf.y = fadd ninf double %y, 1.0
979  %ninf.z = fadd ninf double %z, 1.0
980  %op = call double @llvm.fma.f64(double %ninf.x, double %ninf.y, double %ninf.z)
981  %cmp = fcmp une double %op, 0x7ff0000000000000
982  ret i1 %cmp
983}
984
985define i1 @isNotKnownNeverInfinity_fmuladd(double %x, double %y, double %z) {
986; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_fmuladd
987; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]], double [[Z:%.*]]) {
988; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf double [[X]], 1.000000e+00
989; CHECK-NEXT:    [[NINF_Y:%.*]] = fadd ninf double [[Y]], 1.000000e+00
990; CHECK-NEXT:    [[NINF_Z:%.*]] = fadd ninf double [[Z]], 1.000000e+00
991; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.fmuladd.f64(double [[NINF_X]], double [[NINF_Y]], double [[NINF_Z]])
992; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
993; CHECK-NEXT:    ret i1 [[CMP]]
994;
995  %ninf.x = fadd ninf double %x, 1.0
996  %ninf.y = fadd ninf double %y, 1.0
997  %ninf.z = fadd ninf double %z, 1.0
998  %op = call double @llvm.fmuladd.f64(double %ninf.x, double %ninf.y, double %ninf.z)
999  %cmp = fcmp une double %op, 0x7ff0000000000000
1000  ret i1 %cmp
1001}
1002
1003define i1 @not_inf_fabs_select_pzero_or_ninf(i1 %cond) {
1004; CHECK-LABEL: define i1 @not_inf_fabs_select_pzero_or_ninf
1005; CHECK-SAME: (i1 [[COND:%.*]]) {
1006; CHECK-NEXT:  entry:
1007; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 0.000000e+00, float 0xFFF0000000000000
1008; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
1009; CHECK-NEXT:    [[ONE:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
1010; CHECK-NEXT:    ret i1 [[ONE]]
1011;
1012entry:
1013  %select = select i1 %cond, float 0.000000e+00, float 0xFFF0000000000000
1014  %fabs = call float @llvm.fabs.f32(float %select)
1015  %one = fcmp one float %fabs, 0x7FF0000000000000
1016  ret i1 %one
1017}
1018
1019define i1 @not_inf_fabs_select_nzero_or_pinf(i1 %cond) {
1020; CHECK-LABEL: define i1 @not_inf_fabs_select_nzero_or_pinf
1021; CHECK-SAME: (i1 [[COND:%.*]]) {
1022; CHECK-NEXT:  entry:
1023; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float -0.000000e+00, float 0x7FF0000000000000
1024; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
1025; CHECK-NEXT:    [[ONE:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
1026; CHECK-NEXT:    ret i1 [[ONE]]
1027;
1028entry:
1029  %select = select i1 %cond, float -0.000000e+00, float 0x7FF0000000000000
1030  %fabs = call float @llvm.fabs.f32(float %select)
1031  %one = fcmp one float %fabs, 0x7FF0000000000000
1032  ret i1 %one
1033}
1034
1035define i1 @not_ninf_fabs_select_nzero_or_pinf(i1 %cond) {
1036; CHECK-LABEL: define i1 @not_ninf_fabs_select_nzero_or_pinf
1037; CHECK-SAME: (i1 [[COND:%.*]]) {
1038; CHECK-NEXT:  entry:
1039; CHECK-NEXT:    ret i1 true
1040;
1041entry:
1042  %select = select i1 %cond, float -0.000000e+00, float 0x7FF0000000000000
1043  %fabs = call float @llvm.fabs.f32(float %select)
1044  %one = fcmp one float %fabs, 0xFFF0000000000000
1045  ret i1 %one
1046}
1047
1048define i1 @not_ninf_fneg_fabs_select_nzero_or_pinf(i1 %cond) {
1049; CHECK-LABEL: define i1 @not_ninf_fneg_fabs_select_nzero_or_pinf
1050; CHECK-SAME: (i1 [[COND:%.*]]) {
1051; CHECK-NEXT:  entry:
1052; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float -0.000000e+00, float 0x7FF0000000000000
1053; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
1054; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1055; CHECK-NEXT:    [[ONE:%.*]] = fcmp one float [[FNEG_FABS]], 0xFFF0000000000000
1056; CHECK-NEXT:    ret i1 [[ONE]]
1057;
1058entry:
1059  %select = select i1 %cond, float -0.000000e+00, float 0x7FF0000000000000
1060  %fabs = call float @llvm.fabs.f32(float %select)
1061  %fneg.fabs = fneg float %fabs
1062  %one = fcmp one float %fneg.fabs, 0xFFF0000000000000
1063  ret i1 %one
1064}
1065
1066; This asserted because we didn't handle non-equality comparisons to
1067; negative infinity when recognizing is.fpclass-like compares.
1068define float @fcmp_ogt_neginf_implies_class_assert(float %arg) {
1069; CHECK-LABEL: define float @fcmp_ogt_neginf_implies_class_assert
1070; CHECK-SAME: (float [[ARG:%.*]]) {
1071; CHECK-NEXT:    ret float 0.000000e+00
1072;
1073  %cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
1074  %select_1_0 = select i1 %cmp.ogt.neginf, float 1.0, float 0.0
1075  %mul_by_zero = fmul float %select_1_0, 0.0
1076  ret float %mul_by_zero
1077}
1078
1079define float @fcmp_ule_neginf_implies_class_assert(float %arg) {
1080; CHECK-LABEL: define float @fcmp_ule_neginf_implies_class_assert
1081; CHECK-SAME: (float [[ARG:%.*]]) {
1082; CHECK-NEXT:    ret float 0.000000e+00
1083;
1084  %cmp.ule.neginf = fcmp ule float %arg, 0xFFF0000000000000
1085  %select_1_0 = select i1 %cmp.ule.neginf, float 1.0, float 0.0
1086  %mul_by_zero = fmul float %select_1_0, 0.0
1087  ret float %mul_by_zero
1088}
1089
1090define float @fcmp_oge_neginf_implies_class_assert(float %arg) {
1091; CHECK-LABEL: define float @fcmp_oge_neginf_implies_class_assert
1092; CHECK-SAME: (float [[ARG:%.*]]) {
1093; CHECK-NEXT:    ret float 0.000000e+00
1094;
1095  %cmp.oge.neginf = fcmp oge float %arg, 0xFFF0000000000000
1096  %select_1_0 = select i1 %cmp.oge.neginf, float 1.0, float 0.0
1097  %mul_by_zero = fmul float %select_1_0, 0.0
1098  ret float %mul_by_zero
1099}
1100
1101define float @fcmp_ult_neginf_implies_class_assert(float %arg) {
1102; CHECK-LABEL: define float @fcmp_ult_neginf_implies_class_assert
1103; CHECK-SAME: (float [[ARG:%.*]]) {
1104; CHECK-NEXT:    ret float 0.000000e+00
1105;
1106  %cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
1107  %select_1_0 = select i1 %cmp.ult.neginf, float 1.0, float 0.0
1108  %mul_by_zero = fmul float %select_1_0, 0.0
1109  ret float %mul_by_zero
1110}
1111
1112define i1 @isKnownNeverInfinity_vector_reduce_maximum(<4 x double> %x) {
1113; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_maximum
1114; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1115; CHECK-NEXT:    ret i1 true
1116;
1117  %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1118  %op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %ninf.x)
1119  %cmp = fcmp une double %op, 0x7ff0000000000000
1120  ret i1 %cmp
1121}
1122
1123define i1 @isKnownNeverInfinity_vector_reduce_maximum_fail(<4 x double> %x) {
1124; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_maximum_fail
1125; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1126; CHECK-NEXT:    [[NINF_X:%.*]] = fadd <4 x double> [[X]], splat (double 1.000000e+00)
1127; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> [[NINF_X]])
1128; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
1129; CHECK-NEXT:    ret i1 [[CMP]]
1130;
1131  %ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1132  %op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %ninf.x)
1133  %cmp = fcmp une double %op, 0x7ff0000000000000
1134  ret i1 %cmp
1135}
1136
1137define i1 @isKnownNeverInfinity_vector_reduce_minimum(<4 x double> %x) {
1138; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_minimum
1139; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1140; CHECK-NEXT:    ret i1 true
1141;
1142  %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1143  %op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %ninf.x)
1144  %cmp = fcmp une double %op, 0x7ff0000000000000
1145  ret i1 %cmp
1146}
1147
1148define i1 @isKnownNeverInfinity_vector_reduce_minimum_fail(<4 x double> %x) {
1149; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_minimum_fail
1150; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1151; CHECK-NEXT:    [[NINF_X:%.*]] = fadd <4 x double> [[X]], splat (double 1.000000e+00)
1152; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> [[NINF_X]])
1153; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
1154; CHECK-NEXT:    ret i1 [[CMP]]
1155;
1156  %ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1157  %op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %ninf.x)
1158  %cmp = fcmp une double %op, 0x7ff0000000000000
1159  ret i1 %cmp
1160}
1161
1162define i1 @isKnownNeverInfinity_vector_reduce_fmax(<4 x double> %x) {
1163; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmax
1164; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1165; CHECK-NEXT:    ret i1 true
1166;
1167  %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1168  %op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %ninf.x)
1169  %cmp = fcmp une double %op, 0x7ff0000000000000
1170  ret i1 %cmp
1171}
1172
1173define i1 @isKnownNeverInfinity_vector_reduce_fmax_fail(<4 x double> %x) {
1174; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmax_fail
1175; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1176; CHECK-NEXT:    [[NINF_X:%.*]] = fadd <4 x double> [[X]], splat (double 1.000000e+00)
1177; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> [[NINF_X]])
1178; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
1179; CHECK-NEXT:    ret i1 [[CMP]]
1180;
1181  %ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1182  %op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %ninf.x)
1183  %cmp = fcmp une double %op, 0x7ff0000000000000
1184  ret i1 %cmp
1185}
1186
1187define i1 @isKnownNeverInfinity_vector_reduce_fmin(<4 x double> %x) {
1188; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmin
1189; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1190; CHECK-NEXT:    ret i1 true
1191;
1192  %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1193  %op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %ninf.x)
1194  %cmp = fcmp une double %op, 0x7ff0000000000000
1195  ret i1 %cmp
1196}
1197
1198define i1 @isKnownNeverInfinity_vector_reduce_fmin_fail(<4 x double> %x) {
1199; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmin_fail
1200; CHECK-SAME: (<4 x double> [[X:%.*]]) {
1201; CHECK-NEXT:    [[NINF_X:%.*]] = fadd <4 x double> [[X]], splat (double 1.000000e+00)
1202; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> [[NINF_X]])
1203; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
1204; CHECK-NEXT:    ret i1 [[CMP]]
1205;
1206  %ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
1207  %op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %ninf.x)
1208  %cmp = fcmp une double %op, 0x7ff0000000000000
1209  ret i1 %cmp
1210}
1211
1212declare double @llvm.arithmetic.fence.f64(double)
1213declare double @llvm.canonicalize.f64(double)
1214declare double @llvm.ceil.f64(double)
1215declare double @llvm.copysign.f64(double, double)
1216declare double @llvm.cos.f64(double)
1217declare double @llvm.exp2.f64(double)
1218declare double @llvm.exp.f64(double)
1219declare double @llvm.fabs.f64(double)
1220declare float @llvm.fabs.f32(float)
1221declare double @llvm.floor.f64(double)
1222declare double @llvm.fma.f64(double, double, double)
1223declare double @llvm.fmuladd.f64(double, double, double)
1224declare double @llvm.log10.f64(double)
1225declare double @llvm.log2.f64(double)
1226declare double @llvm.log.f64(double)
1227declare double @llvm.maximum.f64(double, double)
1228declare double @llvm.maxnum.f64(double, double)
1229declare double @llvm.minimum.f64(double, double)
1230declare double @llvm.minnum.f64(double, double)
1231declare double @llvm.nearbyint.f64(double)
1232declare double @llvm.pow.f64(double, double)
1233declare double @llvm.powi.f64.i32(double, i32)
1234declare double @llvm.rint.f64(double)
1235declare double @llvm.roundeven.f64(double)
1236declare double @llvm.round.f64(double)
1237declare double @llvm.sin.f64(double)
1238declare double @llvm.sqrt.f64(double)
1239declare double @llvm.trunc.f64(double)
1240declare float @llvm.fptrunc.round.f32.f64(double, metadata)
1241declare ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128)
1242declare ppc_fp128 @llvm.floor.ppcf128(ppc_fp128)
1243declare ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128)
1244declare ppc_fp128 @llvm.rint.ppcf128(ppc_fp128)
1245declare ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128)
1246declare ppc_fp128 @llvm.round.ppcf128(ppc_fp128)
1247declare ppc_fp128 @llvm.trunc.ppcf128(ppc_fp128)
1248declare x86_fp80 @llvm.ceil.f80(x86_fp80)
1249