xref: /llvm-project/llvm/test/Transforms/InstSimplify/constant-fold-fp-denormal.ll (revision d4a0154902fb9b0611ed857134b26a64a1d5ad1e)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
3
4; Test cases for denormal handling mode when constant folding floating point
5; operations. Input and output modes are checked separately.
6
7; ============================================================================ ;
8; fadd tests
9; Denormal operand added to normal operand produces denormal result.
10; If denormal outputs should be flushed to zero, the result should be zero.
11; If denormal inputs should be treated as zero, the result should be the
12; normal operand (a number plus zero is the same number).
13; ============================================================================ ;
14
15define float @test_float_fadd_ieee() #0 {
16; CHECK-LABEL: @test_float_fadd_ieee(
17; CHECK-NEXT:    ret float 0xB800000000000000
18;
19; default ieee mode leaves result as a denormal
20  %result = fadd float 0xB810000000000000, 0x3800000000000000
21  ret float %result
22}
23
24define float @test_float_fadd_pzero_out() #1 {
25; CHECK-LABEL: @test_float_fadd_pzero_out(
26; CHECK-NEXT:    ret float 0.000000e+00
27;
28; denormal result is flushed to positive zero
29  %result = fadd float 0xB810000000000000, 0x3800000000000000
30  ret float %result
31}
32
33define float @test_float_fadd_psign_out() #2 {
34; CHECK-LABEL: @test_float_fadd_psign_out(
35; CHECK-NEXT:    ret float -0.000000e+00
36;
37; denormal result is flushed to sign preserved zero
38  %result = fadd float 0xB810000000000000, 0x3800000000000000
39  ret float %result
40}
41
42define float @test_float_fadd_pzero_in() #3 {
43; CHECK-LABEL: @test_float_fadd_pzero_in(
44; CHECK-NEXT:    ret float 0xB810000000000000
45;
46; denormal operand is treated as zero
47; normal operand added to zero results in the same operand as a result
48  %result = fadd float 0xB810000000000000, 0x3800000000000000
49  ret float %result
50}
51
52define float @test_float_fadd_psign_in() #4 {
53; CHECK-LABEL: @test_float_fadd_psign_in(
54; CHECK-NEXT:    ret float 0xB810000000000000
55;
56; denormal operand is treated as zero
57; normal operand added to zero results in the same operand as a result
58  %result = fadd float 0xB810000000000000, 0x3800000000000000
59  ret float %result
60}
61
62define float @test_float_fadd_pzero_f32_out() #5 {
63; CHECK-LABEL: @test_float_fadd_pzero_f32_out(
64; CHECK-NEXT:    ret float 0.000000e+00
65;
66; f32 only attribute should flush float output
67; default ieee mode leaves result as a denormal
68  %result = fadd float 0xB810000000000000, 0x3800000000000000
69  ret float %result
70}
71
72define double @test_double_fadd_ieee() #0 {
73; CHECK-LABEL: @test_double_fadd_ieee(
74; CHECK-NEXT:    ret double 0x8008000000000000
75;
76; default ieee mode leaves result as a denormal
77  %result = fadd double 0x8010000000000000, 0x0008000000000000
78  ret double %result
79}
80
81define double @test_double_fadd_pzero_out() #1 {
82; CHECK-LABEL: @test_double_fadd_pzero_out(
83; CHECK-NEXT:    ret double 0.000000e+00
84;
85; denormal result is flushed to positive zero
86  %result = fadd double 0x8010000000000000, 0x0008000000000000
87  ret double %result
88}
89
90define double @test_double_fadd_psign_out() #2 {
91; CHECK-LABEL: @test_double_fadd_psign_out(
92; CHECK-NEXT:    ret double -0.000000e+00
93;
94; denormal result is flushed to sign preserved zero
95  %result = fadd double 0x8010000000000000, 0x0008000000000000
96  ret double %result
97}
98
99define double @test_double_fadd_pzero_in() #3 {
100; CHECK-LABEL: @test_double_fadd_pzero_in(
101; CHECK-NEXT:    ret double 0x8010000000000000
102;
103; denormal operand is treated as zero
104; normal operand added to zero results in the same operand as a result
105  %result = fadd double 0x8010000000000000, 0x0008000000000000
106  ret double %result
107}
108
109define double @test_double_fadd_psign_in() #4 {
110; CHECK-LABEL: @test_double_fadd_psign_in(
111; CHECK-NEXT:    ret double 0x8010000000000000
112;
113; denormal operand is treated as zero
114; normal operand added to zero results in the same operand as a result
115  %result = fadd double 0x8010000000000000, 0x0008000000000000
116  ret double %result
117}
118
119define double @test_double_fadd_f32_ieee() #5 {
120; CHECK-LABEL: @test_double_fadd_f32_ieee(
121; CHECK-NEXT:    ret double 0x8008000000000000
122;
123; f32 only attribute should not flush doubles
124; default ieee mode leaves result as a denormal
125  %result = fadd double 0x8010000000000000, 0x0008000000000000
126  ret double %result
127}
128
129; ============================================================================ ;
130; fsub tests
131; Normal operand subtracted from denormal operand produces denormal result
132; If denormal outputs should be flushed to zero, the result should be zero.
133; If denormal inputs should be treated as zero, the result should be the
134; negated normal operand (zero minus the original operand).
135; ============================================================================ ;
136
137define float @test_float_fsub_ieee() #0 {
138; CHECK-LABEL: @test_float_fsub_ieee(
139; CHECK-NEXT:    ret float 0xB800000000000000
140;
141; default ieee mode leaves result as a denormal
142  %result = fsub float 0x3800000000000000, 0x3810000000000000
143  ret float %result
144}
145
146define float @test_float_fsub_pzero_out() #1 {
147; CHECK-LABEL: @test_float_fsub_pzero_out(
148; CHECK-NEXT:    ret float 0.000000e+00
149;
150; denormal result is flushed to positive zero
151  %result = fsub float 0x3800000000000000, 0x3810000000000000
152  ret float %result
153}
154
155define float @test_float_fsub_psign_out() #2 {
156; CHECK-LABEL: @test_float_fsub_psign_out(
157; CHECK-NEXT:    ret float -0.000000e+00
158;
159; denormal result is flushed to sign preserved zero
160  %result = fsub float 0x3800000000000000, 0x3810000000000000
161  ret float %result
162}
163
164define float @test_float_fsub_pzero_in() #3 {
165; CHECK-LABEL: @test_float_fsub_pzero_in(
166; CHECK-NEXT:    ret float 0xB810000000000000
167;
168; denormal operand is treated as zero
169; normal operand subtracted from zero produces the same operand, negated
170  %result = fsub float 0x3800000000000000, 0x3810000000000000
171  ret float %result
172}
173
174define float @test_float_fsub_psign_in() #4 {
175; CHECK-LABEL: @test_float_fsub_psign_in(
176; CHECK-NEXT:    ret float 0xB810000000000000
177;
178; denormal operand is treated as zero
179; normal operand subtracted from zero produces the same operand, negated
180  %result = fsub float 0x3800000000000000, 0x3810000000000000
181  ret float %result
182}
183
184define float @test_float_fsub_pzero_f32_out() #5 {
185; CHECK-LABEL: @test_float_fsub_pzero_f32_out(
186; CHECK-NEXT:    ret float 0.000000e+00
187;
188; f32 only attribute should flush float output
189; same as pzero_out above
190  %result = fsub float 0x3800000000000000, 0x3810000000000000
191  ret float %result
192}
193
194define double @test_double_fsub_ieee() #0 {
195; CHECK-LABEL: @test_double_fsub_ieee(
196; CHECK-NEXT:    ret double 0x8008000000000000
197;
198; default ieee mode leaves result as a denormal
199  %result = fsub double 0x0008000000000000, 0x0010000000000000
200  ret double %result
201}
202
203define double @test_double_fsub_pzero_out() #1 {
204; CHECK-LABEL: @test_double_fsub_pzero_out(
205; CHECK-NEXT:    ret double 0.000000e+00
206;
207; denormal result is flushed to positive zero
208  %result = fsub double 0x0008000000000000, 0x0010000000000000
209  ret double %result
210}
211
212define double @test_double_fsub_psign_out() #2 {
213; CHECK-LABEL: @test_double_fsub_psign_out(
214; CHECK-NEXT:    ret double -0.000000e+00
215;
216; denormal result is flushed to sign preserved zero
217  %result = fsub double 0x0008000000000000, 0x0010000000000000
218  ret double %result
219}
220
221define double @test_double_fsub_pzero_in() #3 {
222; CHECK-LABEL: @test_double_fsub_pzero_in(
223; CHECK-NEXT:    ret double 0x8010000000000000
224;
225; denormal operand is treated as zero
226; normal operand subtracted from zero produces the same operand, negated
227  %result = fsub double 0x0008000000000000, 0x0010000000000000
228  ret double %result
229}
230
231define double @test_double_fsub_psign_in() #4 {
232; CHECK-LABEL: @test_double_fsub_psign_in(
233; CHECK-NEXT:    ret double 0x8010000000000000
234;
235; denormal operand is treated as zero
236; normal operand subtracted from zero produces the same operand, negated
237  %result = fsub double 0x0008000000000000, 0x0010000000000000
238  ret double %result
239}
240
241define double @test_double_fsub_f32_ieee() #5 {
242; CHECK-LABEL: @test_double_fsub_f32_ieee(
243; CHECK-NEXT:    ret double 0x8008000000000000
244;
245; f32 only attribute should not flush doubles
246; default ieee mode leaves result as a denormal
247  %result = fsub double 0x0008000000000000, 0x0010000000000000
248  ret double %result
249}
250
251; ============================================================================ ;
252; fmul tests
253; Output modes are tested by multiplying the smallest normal number by 0.5,
254; producing a denormal result. If denormal outputs should be flushed to zero,
255; the result should be zero.
256; Input modes are tested by the reverse operation: taking the denormal and
257; multiplying by 2 to produce a normal number. If denormal inputs should be
258; treated as zero, the result should also be zero.
259; ============================================================================ ;
260
261define float @test_float_fmul_ieee() #0 {
262; CHECK-LABEL: @test_float_fmul_ieee(
263; CHECK-NEXT:    ret float 0xB800000000000000
264;
265; default ieee mode leaves result as a denormal
266  %result = fmul float 0x3810000000000000, -5.000000e-01
267  ret float %result
268}
269
270define float @test_float_fmul_pzero_out() #1 {
271; CHECK-LABEL: @test_float_fmul_pzero_out(
272; CHECK-NEXT:    ret float 0.000000e+00
273;
274; denormal result is flushed to positive zero
275  %result = fmul float 0x3810000000000000, -5.000000e-01
276  ret float %result
277}
278
279define float @test_float_fmul_psign_out() #2 {
280; CHECK-LABEL: @test_float_fmul_psign_out(
281; CHECK-NEXT:    ret float -0.000000e+00
282;
283; denormal result is flushed to sign preserved zero
284  %result = fmul float 0x3810000000000000, -5.000000e-01
285  ret float %result
286}
287
288define float @test_float_fmul_pzero_in() #3 {
289; CHECK-LABEL: @test_float_fmul_pzero_in(
290; CHECK-NEXT:    ret float 0.000000e+00
291;
292; denormal operand is treated as positive zero
293; anything multiplied by zero gives a zero result
294  %result = fmul float 0xB800000000000000, 2.000000e-00
295  ret float %result
296}
297
298define float @test_float_fmul_psign_in() #4 {
299; CHECK-LABEL: @test_float_fmul_psign_in(
300; CHECK-NEXT:    ret float -0.000000e+00
301;
302; denormal operand is treated as signed zero
303; anything multiplied by zero gives a zero result
304  %result = fmul float 0xB800000000000000, 2.000000e-00
305  ret float %result
306}
307
308define float @test_float_fmul_pzero_f32_out() #1 {
309; CHECK-LABEL: @test_float_fmul_pzero_f32_out(
310; CHECK-NEXT:    ret float 0.000000e+00
311;
312; f32 only attribute should flush float output
313; same as pzero_out above
314  %result = fmul float 0x3810000000000000, -5.000000e-01
315  ret float %result
316}
317
318define double @test_double_fmul_ieee() #0 {
319; CHECK-LABEL: @test_double_fmul_ieee(
320; CHECK-NEXT:    ret double 0x8008000000000000
321;
322; default ieee mode leaves result as a denormal
323  %result = fmul double 0x00010000000000000, -5.000000e-01
324  ret double %result
325}
326
327define double @test_double_fmul_pzero_out() #1 {
328; CHECK-LABEL: @test_double_fmul_pzero_out(
329; CHECK-NEXT:    ret double 0.000000e+00
330;
331; denormal result is flushed to positive zero
332  %result = fmul double 0x00010000000000000, -5.000000e-01
333  ret double %result
334}
335
336define double @test_double_fmul_psign_out() #2 {
337; CHECK-LABEL: @test_double_fmul_psign_out(
338; CHECK-NEXT:    ret double -0.000000e+00
339;
340; denormal result is flushed to sign preserved zero
341  %result = fmul double 0x0010000000000000, -5.000000e-01
342  ret double %result
343}
344
345define double @test_double_fmul_pzero_in() #3 {
346; CHECK-LABEL: @test_double_fmul_pzero_in(
347; CHECK-NEXT:    ret double 0.000000e+00
348;
349; denormal operand is treated as positive zero
350; anything multiplied by zero gives a zero result
351  %result = fmul double 0x8008000000000000, 2.000000e-00
352  ret double %result
353}
354
355define double @test_double_fmul_psign_in() #4 {
356; CHECK-LABEL: @test_double_fmul_psign_in(
357; CHECK-NEXT:    ret double -0.000000e+00
358;
359; denormal operand is treated as signed zero
360; anything multiplied by zero gives a zero result
361  %result = fmul double 0x8008000000000000, 2.000000e-00
362  ret double %result
363}
364
365define double @test_double_fmul_f32_ieee() #5 {
366; CHECK-LABEL: @test_double_fmul_f32_ieee(
367; CHECK-NEXT:    ret double 0x8008000000000000
368;
369; f32 only attribute should not flush doubles
370; default ieee mode leaves result as a denormal
371  %result = fmul double 0x0010000000000000, -5.000000e-01
372  ret double %result
373}
374
375; ============================================================================ ;
376; fdiv tests
377; Output modes are tested by dividing the smallest normal number by 2,
378; producing a denormal result. If denormal outputs should be flushed to zero,
379; the result should be zero.
380; Input modes are tested by the reverse operation: taking the denormal and
381; dividing by 0.5 to produce a normal number. If denormal inputs should be
382; treated as zero, the result should also be zero.
383; ============================================================================ ;
384
385define float @test_float_fdiv_ieee() #0 {
386; CHECK-LABEL: @test_float_fdiv_ieee(
387; CHECK-NEXT:    ret float 0xB800000000000000
388;
389; default ieee mode leaves result as a denormal
390  %result = fdiv float 0x3810000000000000, -2.000000e-00
391  ret float %result
392}
393
394define float @test_float_fdiv_pzero_out() #1 {
395; CHECK-LABEL: @test_float_fdiv_pzero_out(
396; CHECK-NEXT:    ret float 0.000000e+00
397;
398; denormal result is flushed to positive zero
399  %result = fdiv float 0x3810000000000000, -2.000000e-00
400  ret float %result
401}
402
403define float @test_float_fdiv_psign_out() #2 {
404; CHECK-LABEL: @test_float_fdiv_psign_out(
405; CHECK-NEXT:    ret float -0.000000e+00
406;
407; denormal result is flushed to sign preserved zero
408  %result = fdiv float 0x3810000000000000, -2.000000e-00
409  ret float %result
410}
411
412define float @test_float_fdiv_pzero_in() #3 {
413; CHECK-LABEL: @test_float_fdiv_pzero_in(
414; CHECK-NEXT:    ret float 0.000000e+00
415;
416; denormal operand is treated as zero
417; zero divided by anything gives a zero result
418  %result = fdiv float 0xB800000000000000, 5.000000e-01
419  ret float %result
420}
421
422define float @test_float_fdiv_psign_in() #4 {
423; CHECK-LABEL: @test_float_fdiv_psign_in(
424; CHECK-NEXT:    ret float -0.000000e+00
425;
426; denormal operand is treated as zero
427; zero divided by anything gives a zero result
428  %result = fmul float 0xB800000000000000, 5.000000e-01
429  ret float %result
430}
431
432define float @test_float_fdiv_pzero_f32_out() #1 {
433; CHECK-LABEL: @test_float_fdiv_pzero_f32_out(
434; CHECK-NEXT:    ret float 0.000000e+00
435;
436; f32 only attribute should flush float output
437; same as pzero_out above
438  %result = fdiv float 0x3810000000000000, -2.000000e-00
439  ret float %result
440}
441
442define double @test_double_fdiv_ieee() #0 {
443; CHECK-LABEL: @test_double_fdiv_ieee(
444; CHECK-NEXT:    ret double 0x8008000000000000
445;
446; default ieee mode leaves result as a denormal
447  %result = fdiv double 0x0010000000000000, -2.000000e-00
448  ret double %result
449}
450
451define double @test_double_fdiv_pzero_out() #1 {
452; CHECK-LABEL: @test_double_fdiv_pzero_out(
453; CHECK-NEXT:    ret double 0.000000e+00
454;
455; denormal result is flushed to positive zero
456  %result = fdiv double 0x0010000000000000, -2.000000e-00
457  ret double %result
458}
459
460define double @test_double_fdiv_psign_out() #2 {
461; CHECK-LABEL: @test_double_fdiv_psign_out(
462; CHECK-NEXT:    ret double -0.000000e+00
463;
464; denormal result is flushed to sign preserved zero
465  %result = fdiv double 0x0010000000000000, -2.000000e-00
466  ret double %result
467}
468
469define double @test_double_fdiv_pzero_in() #3 {
470; CHECK-LABEL: @test_double_fdiv_pzero_in(
471; CHECK-NEXT:    ret double 0.000000e+00
472;
473; denormal operand is treated as zero
474; zero divided by anything gives a zero result
475  %result = fdiv double 0x8008000000000000, 5.000000e-01
476  ret double %result
477}
478
479define double @test_double_fdiv_psign_in() #4 {
480; CHECK-LABEL: @test_double_fdiv_psign_in(
481; CHECK-NEXT:    ret double -0.000000e+00
482;
483; denormal operand is treated as zero
484; zero divided by anything gives a zero result
485  %result = fdiv double 0x8008000000000000, 5.000000e-01
486  ret double %result
487}
488
489define double @test_double_fdiv_f32_ieee() #5 {
490; CHECK-LABEL: @test_double_fdiv_f32_ieee(
491; CHECK-NEXT:    ret double 0x8008000000000000
492;
493; f32 only attribute should not flush doubles
494; default ieee mode leaves result as a denormal
495  %result = fdiv double 0x0010000000000000, -2.000000e-00
496  ret double %result
497}
498
499; ============================================================================ ;
500; frem tests
501; Output modes are tested by using two small normal numbers to produce a
502; denormal result. If denormal outputs should be flushed to zero, the result
503; should be zero.
504; Input modes are tested by calculating the remainder of a denormal number
505; and a larger normal number. If denormal inputs should be treated as zero
506; the result also becomes zero.
507; ============================================================================ ;
508
509define float @test_float_frem_ieee_out() #0 {
510; CHECK-LABEL: @test_float_frem_ieee_out(
511; CHECK-NEXT:    ret float 0xB800000000000000
512;
513; default ieee mode leaves result as a denormal
514  %result = frem float 0xB818000000000000, 0x3810000000000000
515  ret float %result
516}
517
518define float @test_float_frem_pzero_out() #1 {
519; CHECK-LABEL: @test_float_frem_pzero_out(
520; CHECK-NEXT:    ret float 0.000000e+00
521;
522; denormal result is flushed to positive zero
523  %result = frem float 0xB818000000000000, 0x3810000000000000
524  ret float %result
525}
526
527define float @test_float_frem_psign_out() #2 {
528; CHECK-LABEL: @test_float_frem_psign_out(
529; CHECK-NEXT:    ret float -0.000000e+00
530;
531; denormal result is flushed to sign preserved zero
532  %result = frem float 0xB818000000000000, 0x3810000000000000
533  ret float %result
534}
535
536define float @test_float_frem_ieee_in() #0 {
537; CHECK-LABEL: @test_float_frem_ieee_in(
538; CHECK-NEXT:    ret float 0x3800000000000000
539;
540; default ieee mode leaves result same as input
541  %result = frem float 0x3800000000000000, 2.000000e+00
542  ret float %result
543}
544
545define float @test_float_frem_pzero_in() #3 {
546; CHECK-LABEL: @test_float_frem_pzero_in(
547; CHECK-NEXT:    ret float 0.000000e+00
548;
549; denormal operand is treated as zero
550; remainder is now zero
551  %result = frem float 0x3800000000000000, 2.000000e+00
552  ret float %result
553}
554
555define float @test_float_frem_psign_in() #4 {
556; CHECK-LABEL: @test_float_frem_psign_in(
557; CHECK-NEXT:    ret float 0.000000e+00
558;
559; denormal operand is treated as zero
560; remainder is now zero
561  %result = frem float 0x3800000000000000, 2.000000e+00
562  ret float %result
563}
564
565define float @test_float_frem_pzero_f32_out() #1 {
566; CHECK-LABEL: @test_float_frem_pzero_f32_out(
567; CHECK-NEXT:    ret float 0.000000e+00
568;
569; f32 only attribute should flush float output
570; same as pzero_out above
571  %result = frem float 0xB818000000000000, 0x3810000000000000
572  ret float %result
573}
574
575define double @test_double_frem_ieee_out() #0 {
576; CHECK-LABEL: @test_double_frem_ieee_out(
577; CHECK-NEXT:    ret double 0x8008000000000000
578;
579; default ieee mode leaves result as a denormal
580  %result = frem double 0x8018000000000000, 0x0010000000000000
581  ret double %result
582}
583
584define double @test_double_frem_pzero_out() #1 {
585; CHECK-LABEL: @test_double_frem_pzero_out(
586; CHECK-NEXT:    ret double 0.000000e+00
587;
588; denormal result is flushed to positive zero
589  %result = frem double 0x8018000000000000, 0x0010000000000000
590  ret double %result
591}
592
593define double @test_double_frem_psign_out() #2 {
594; CHECK-LABEL: @test_double_frem_psign_out(
595; CHECK-NEXT:    ret double -0.000000e+00
596;
597; denormal result is flushed to sign preserved zero
598  %result = frem double 0x8018000000000000, 0x0010000000000000
599  ret double %result
600}
601
602define double @test_double_frem_ieee_in() #0 {
603; CHECK-LABEL: @test_double_frem_ieee_in(
604; CHECK-NEXT:    ret double 0x8000000000000
605;
606; default ieee mode leaves result same as input
607  %result = frem double 0x0008000000000000, 2.000000e+00
608  ret double %result
609}
610
611define double @test_double_frem_pzero_in() #3 {
612; CHECK-LABEL: @test_double_frem_pzero_in(
613; CHECK-NEXT:    ret double 0.000000e+00
614;
615; denormal operand is treated as zero
616; remainder is now zero
617  %result = frem double 0x0008000000000000, 2.000000e+00
618  ret double %result
619}
620
621define double @test_double_frem_psign_in() #4 {
622; CHECK-LABEL: @test_double_frem_psign_in(
623; CHECK-NEXT:    ret double 0.000000e+00
624;
625; denormal operand is treated as zero
626; remainder is now zero
627  %result = frem double 0x0008000000000000, 2.000000e+00
628  ret double %result
629}
630
631define double @test_double_frem_f32_ieee() #5 {
632; CHECK-LABEL: @test_double_frem_f32_ieee(
633; CHECK-NEXT:    ret double 0x8008000000000000
634;
635; f32 only attribute should not flush doubles
636; default ieee mode leaves result as a denormal
637  %result = frem double 0x8018000000000000, 0x0010000000000000
638  ret double %result
639}
640
641; ============================================================================ ;
642; fneg tests
643; fneg should NOT be affected by denormal handling mode
644; these tests confirm fneg results are unchanged
645; ============================================================================ ;
646
647define float @test_float_fneg_ieee() #0 {
648; CHECK-LABEL: @test_float_fneg_ieee(
649; CHECK-NEXT:    ret float 0xB800000000000000
650;
651  %result = fneg float 0x3800000000000000
652  ret float %result
653}
654
655define float @test_float_fneg_pzero_out() #0 {
656; CHECK-LABEL: @test_float_fneg_pzero_out(
657; CHECK-NEXT:    ret float 0xB800000000000000
658;
659  %result = fneg float 0x3800000000000000
660  ret float %result
661}
662
663define float @test_float_fneg_psign_out() #0 {
664; CHECK-LABEL: @test_float_fneg_psign_out(
665; CHECK-NEXT:    ret float 0xB800000000000000
666;
667  %result = fneg float 0x3800000000000000
668  ret float %result
669}
670
671define float @test_float_fneg_pzero_in() #0 {
672; CHECK-LABEL: @test_float_fneg_pzero_in(
673; CHECK-NEXT:    ret float 0xB800000000000000
674;
675  %result = fneg float 0x3800000000000000
676  ret float %result
677}
678
679define float @test_float_fneg_psign_in() #0 {
680; CHECK-LABEL: @test_float_fneg_psign_in(
681; CHECK-NEXT:    ret float 0xB800000000000000
682;
683  %result = fneg float 0x3800000000000000
684  ret float %result
685}
686
687define float @test_float_fneg_pzero_f32_out() #5 {
688; CHECK-LABEL: @test_float_fneg_pzero_f32_out(
689; CHECK-NEXT:    ret float 0xB800000000000000
690;
691  %result = fneg float 0x3800000000000000
692  ret float %result
693}
694
695define double @test_double_fneg_ieee() #0 {
696; CHECK-LABEL: @test_double_fneg_ieee(
697; CHECK-NEXT:    ret double 0x8008000000000000
698;
699  %result = fneg double 0x0008000000000000
700  ret double %result
701}
702
703define double @test_double_fneg_pzero_out() #1 {
704; CHECK-LABEL: @test_double_fneg_pzero_out(
705; CHECK-NEXT:    ret double 0x8008000000000000
706;
707  %result = fneg double 0x0008000000000000
708  ret double %result
709}
710
711define double @test_double_fneg_psign_out() #2 {
712; CHECK-LABEL: @test_double_fneg_psign_out(
713; CHECK-NEXT:    ret double 0x8008000000000000
714;
715  %result = fneg double 0x0008000000000000
716  ret double %result
717}
718
719define double @test_double_fneg_pzero_in() #3 {
720; CHECK-LABEL: @test_double_fneg_pzero_in(
721; CHECK-NEXT:    ret double 0x8008000000000000
722;
723  %result = fneg double 0x0008000000000000
724  ret double %result
725}
726
727define double @test_double_fneg_psign_in() #4 {
728; CHECK-LABEL: @test_double_fneg_psign_in(
729; CHECK-NEXT:    ret double 0x8008000000000000
730;
731  %result = fneg double 0x0008000000000000
732  ret double %result
733}
734
735define double @test_double_fneg_f32_ieee() #5 {
736; CHECK-LABEL: @test_double_fneg_f32_ieee(
737; CHECK-NEXT:    ret double 0x8008000000000000
738;
739  %result = fneg double 0x0008000000000000
740  ret double %result
741}
742
743define i1 @fcmp_double_ieee_in_ieee_out() #0 {
744; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out(
745; CHECK-NEXT:  entry:
746; CHECK-NEXT:    ret i1 true
747;
748entry:
749  %cmp = fcmp une double 0x0008000000000000, 0x0
750  ret i1 %cmp
751}
752
753define i1 @fcmp_float_ieee_in_ieee_out() #0 {
754; CHECK-LABEL: @fcmp_float_ieee_in_ieee_out(
755; CHECK-NEXT:  entry:
756; CHECK-NEXT:    ret i1 true
757;
758entry:
759  %cmp = fcmp une float 0x3800000000000000, 0x0
760  ret i1 %cmp
761}
762
763define i1 @fcmp_double_pz_in_pz_out() #6 {
764; CHECK-LABEL: @fcmp_double_pz_in_pz_out(
765; CHECK-NEXT:  entry:
766; CHECK-NEXT:    ret i1 false
767;
768entry:
769  %cmp = fcmp une double 0x0008000000000000, 0x0
770  ret i1 %cmp
771}
772
773define i1 @fcmp_float_pz_in_pz_out() #6 {
774; CHECK-LABEL: @fcmp_float_pz_in_pz_out(
775; CHECK-NEXT:  entry:
776; CHECK-NEXT:    ret i1 false
777;
778entry:
779  %cmp = fcmp une float 0x3800000000000000, 0x0
780  ret i1 %cmp
781}
782
783define i1 @fcmp_double_ps_in_ps_out() #7 {
784; CHECK-LABEL: @fcmp_double_ps_in_ps_out(
785; CHECK-NEXT:  entry:
786; CHECK-NEXT:    ret i1 false
787;
788entry:
789  %cmp = fcmp une double 0x0008000000000000, 0x0
790  ret i1 %cmp
791}
792
793define i1 @fcmp_float_ps_in_ps_out() #7 {
794; CHECK-LABEL: @fcmp_float_ps_in_ps_out(
795; CHECK-NEXT:  entry:
796; CHECK-NEXT:    ret i1 false
797;
798entry:
799  %cmp = fcmp une float 0x3800000000000000, 0x0
800  ret i1 %cmp
801}
802
803define i1 @fcmp_double_pz_out_ieee_in() #1 {
804; CHECK-LABEL: @fcmp_double_pz_out_ieee_in(
805; CHECK-NEXT:  entry:
806; CHECK-NEXT:    ret i1 true
807;
808entry:
809  %cmp = fcmp une double 0x0008000000000000, 0x0
810  ret i1 %cmp
811}
812
813define i1 @fcmp_double_ps_out_ieee_in() #2 {
814; CHECK-LABEL: @fcmp_double_ps_out_ieee_in(
815; CHECK-NEXT:  entry:
816; CHECK-NEXT:    ret i1 true
817;
818entry:
819  %cmp = fcmp une double 0x0008000000000000, 0x0
820  ret i1 %cmp
821}
822
823define i1 @fcmp_double_ieee_out_pz_in() #3 {
824; CHECK-LABEL: @fcmp_double_ieee_out_pz_in(
825; CHECK-NEXT:  entry:
826; CHECK-NEXT:    ret i1 false
827;
828entry:
829  %cmp = fcmp une double 0x0008000000000000, 0x0
830  ret i1 %cmp
831}
832
833define i1 @fcmp_double_ieee_out_ps_in() #4 {
834; CHECK-LABEL: @fcmp_double_ieee_out_ps_in(
835; CHECK-NEXT:  entry:
836; CHECK-NEXT:    ret i1 false
837;
838entry:
839  %cmp = fcmp une double 0x0008000000000000, 0x0
840  ret i1 %cmp
841}
842
843define i1 @fcmp_double_f32_pz_in() #8 {
844; CHECK-LABEL: @fcmp_double_f32_pz_in(
845; CHECK-NEXT:  entry:
846; CHECK-NEXT:    ret i1 true
847;
848entry:
849  %cmp = fcmp une double 0x0008000000000000, 0x0
850  ret i1 %cmp
851}
852
853define i1 @fcmp_double_two_denormal_ins() #6 {
854; CHECK-LABEL: @fcmp_double_two_denormal_ins(
855; CHECK-NEXT:  entry:
856; CHECK-NEXT:    ret i1 false
857;
858entry:
859  %cmp = fcmp une double 0x0008100000000000, 0x0008000000000000
860  ret i1 %cmp
861}
862
863define i1 @fcmp_double_ps_in_ps_out_false() #6 {
864; CHECK-LABEL: @fcmp_double_ps_in_ps_out_false(
865; CHECK-NEXT:  entry:
866; CHECK-NEXT:    ret i1 false
867;
868entry:
869  %cmp = fcmp false double 0x0008100000000000, 0x0008000000000000
870  ret i1 %cmp
871}
872
873define i1 @fcmp_double_ieee_in_ieee_out_false() #0 {
874; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_false(
875; CHECK-NEXT:  entry:
876; CHECK-NEXT:    ret i1 false
877;
878entry:
879  %cmp = fcmp false double 0x0008100000000000, 0x0008000000000000
880  ret i1 %cmp
881}
882
883define i1 @fcmp_double_ps_in_ps_out_true() #6 {
884; CHECK-LABEL: @fcmp_double_ps_in_ps_out_true(
885; CHECK-NEXT:  entry:
886; CHECK-NEXT:    ret i1 true
887;
888entry:
889  %cmp = fcmp true double 0x0008100000000000, 0x0008000000000000
890  ret i1 %cmp
891}
892
893define i1 @fcmp_double_ieee_in_ieee_out_true() #0 {
894; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_true(
895; CHECK-NEXT:  entry:
896; CHECK-NEXT:    ret i1 true
897;
898entry:
899  %cmp = fcmp true double 0x0008100000000000, 0x0008000000000000
900  ret i1 %cmp
901}
902
903define i1 @fcmp_double_ps_in_ps_out_oeq() #6 {
904; CHECK-LABEL: @fcmp_double_ps_in_ps_out_oeq(
905; CHECK-NEXT:  entry:
906; CHECK-NEXT:    ret i1 true
907;
908entry:
909  %cmp = fcmp oeq double 0x0008100000000000, 0x0008000000000000
910  ret i1 %cmp
911}
912
913define i1 @fcmp_double_ieee_in_ieee_out_oeq() #0 {
914; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_oeq(
915; CHECK-NEXT:  entry:
916; CHECK-NEXT:    ret i1 false
917;
918entry:
919  %cmp = fcmp oeq double 0x0008100000000000, 0x0008000000000000
920  ret i1 %cmp
921}
922
923define i1 @fcmp_double_ps_in_ps_out_one() #6 {
924; CHECK-LABEL: @fcmp_double_ps_in_ps_out_one(
925; CHECK-NEXT:  entry:
926; CHECK-NEXT:    ret i1 false
927;
928entry:
929  %cmp = fcmp one double 0x0008100000000000, 0x0008000000000000
930  ret i1 %cmp
931}
932
933define i1 @fcmp_double_ieee_in_ieee_out_one() #0 {
934; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_one(
935; CHECK-NEXT:  entry:
936; CHECK-NEXT:    ret i1 true
937;
938entry:
939  %cmp = fcmp one double 0x0008100000000000, 0x0008000000000000
940  ret i1 %cmp
941}
942
943define i1 @fcmp_double_ps_in_ps_out_ord1() #6 {
944; CHECK-LABEL: @fcmp_double_ps_in_ps_out_ord1(
945; CHECK-NEXT:  entry:
946; CHECK-NEXT:    ret i1 false
947;
948entry:
949  %cmp = fcmp ord double 0x0008000000000000, 0x7ff1000000000000
950  ret i1 %cmp
951}
952
953define i1 @fcmp_double_ieee_in_ieee_out_ord1() #0 {
954; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_ord1(
955; CHECK-NEXT:  entry:
956; CHECK-NEXT:    ret i1 false
957;
958entry:
959  %cmp = fcmp ord double 0x0008000000000000, 0x7ff1000000000000
960  ret i1 %cmp
961}
962
963define i1 @fcmp_double_ps_in_ps_out_ord2() #6 {
964; CHECK-LABEL: @fcmp_double_ps_in_ps_out_ord2(
965; CHECK-NEXT:  entry:
966; CHECK-NEXT:    ret i1 true
967;
968entry:
969  %cmp = fcmp ord double 0x0008000000000000, 0x1ff1000000000000
970  ret i1 %cmp
971}
972
973define i1 @fcmp_double_ieee_in_ieee_out_ord2() #0 {
974; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_ord2(
975; CHECK-NEXT:  entry:
976; CHECK-NEXT:    ret i1 true
977;
978entry:
979  %cmp = fcmp ord double 0x0008000000000000, 0x1ff1000000000000
980  ret i1 %cmp
981}
982
983define i1 @fcmp_double_pz_in_pz_out_ugt() #7 {
984; CHECK-LABEL: @fcmp_double_pz_in_pz_out_ugt(
985; CHECK-NEXT:  entry:
986; CHECK-NEXT:    ret i1 false
987;
988entry:
989  %cmp = fcmp ugt double 0x0008000000000000, 0x0
990  ret i1 %cmp
991}
992
993define i1 @fcmp_double_ieee_in_ieee_out_ugt() #0 {
994; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_ugt(
995; CHECK-NEXT:  entry:
996; CHECK-NEXT:    ret i1 true
997;
998entry:
999  %cmp = fcmp ugt double 0x0008000000000000, 0x0
1000  ret i1 %cmp
1001}
1002
1003define i1 @fcmp_double_pz_in_pz_out_ult() #7 {
1004; CHECK-LABEL: @fcmp_double_pz_in_pz_out_ult(
1005; CHECK-NEXT:  entry:
1006; CHECK-NEXT:    ret i1 false
1007;
1008entry:
1009  %cmp = fcmp ult double 0x0008000000000000, 0x0
1010  ret i1 %cmp
1011}
1012
1013define i1 @fcmp_double_ieee_in_ieee_out_ult() #0 {
1014; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_ult(
1015; CHECK-NEXT:  entry:
1016; CHECK-NEXT:    ret i1 false
1017;
1018entry:
1019  %cmp = fcmp ult double 0x0008000000000000, 0x0
1020  ret i1 %cmp
1021}
1022
1023define i1 @fcmp_double_pz_in_pz_out_uge() #7 {
1024; CHECK-LABEL: @fcmp_double_pz_in_pz_out_uge(
1025; CHECK-NEXT:  entry:
1026; CHECK-NEXT:    ret i1 true
1027;
1028entry:
1029  %cmp = fcmp uge double 0x0008000000000000, 0x0
1030  ret i1 %cmp
1031}
1032
1033define i1 @fcmp_double_ieee_in_ieee_out_uge() #0 {
1034; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_uge(
1035; CHECK-NEXT:  entry:
1036; CHECK-NEXT:    ret i1 true
1037;
1038entry:
1039  %cmp = fcmp uge double 0x0008000000000000, 0x0
1040  ret i1 %cmp
1041}
1042
1043define i1 @fcmp_double_pz_in_pz_out_ule() #7 {
1044; CHECK-LABEL: @fcmp_double_pz_in_pz_out_ule(
1045; CHECK-NEXT:  entry:
1046; CHECK-NEXT:    ret i1 true
1047;
1048entry:
1049  %cmp = fcmp ule double 0x0008000000000000, 0x0
1050  ret i1 %cmp
1051}
1052
1053define i1 @fcmp_double_ieee_in_ieee_out_ule() #0 {
1054; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_ule(
1055; CHECK-NEXT:  entry:
1056; CHECK-NEXT:    ret i1 false
1057;
1058entry:
1059  %cmp = fcmp ule double 0x0008000000000000, 0x0
1060  ret i1 %cmp
1061}
1062
1063define i1 @fcmp_double_pz_in_pz_out_uno() #7 {
1064; CHECK-LABEL: @fcmp_double_pz_in_pz_out_uno(
1065; CHECK-NEXT:  entry:
1066; CHECK-NEXT:    ret i1 true
1067;
1068entry:
1069  %cmp = fcmp uno double 0x0008000000000000, 0x7ff1000000000000
1070  ret i1 %cmp
1071}
1072
1073define i1 @fcmp_double_ieee_in_ieee_out_uno() #0 {
1074; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_uno(
1075; CHECK-NEXT:  entry:
1076; CHECK-NEXT:    ret i1 true
1077;
1078entry:
1079  %cmp = fcmp uno double 0x0008000000000000, 0x7ff1000000000000
1080  ret i1 %cmp
1081}
1082
1083define i1 @fcmp_double_pz_in_pz_out_uno2() #7 {
1084; CHECK-LABEL: @fcmp_double_pz_in_pz_out_uno2(
1085; CHECK-NEXT:  entry:
1086; CHECK-NEXT:    ret i1 false
1087;
1088entry:
1089  %cmp = fcmp uno double 0x0008000000000000, 0x1ff1000000000000
1090  ret i1 %cmp
1091}
1092
1093define i1 @fcmp_double_ieee_in_ieee_out_uno2() #0 {
1094; CHECK-LABEL: @fcmp_double_ieee_in_ieee_out_uno2(
1095; CHECK-NEXT:  entry:
1096; CHECK-NEXT:    ret i1 false
1097;
1098entry:
1099  %cmp = fcmp uno double 0x0008000000000000, 0x1ff1000000000000
1100  ret i1 %cmp
1101}
1102
1103; ============================================================================ ;
1104; dynamic mode tests
1105; ============================================================================ ;
1106
1107define float @test_float_fadd_dynamic_ieee() #9 {
1108; CHECK-LABEL: @test_float_fadd_dynamic_ieee(
1109; CHECK-NEXT:    [[RESULT:%.*]] = fadd float 0xB810000000000000, 0x3800000000000000
1110; CHECK-NEXT:    ret float [[RESULT]]
1111;
1112  %result = fadd float 0xB810000000000000, 0x3800000000000000
1113  ret float %result
1114}
1115
1116define float @test_float_fadd_ieee_dynamic() #10 {
1117; CHECK-LABEL: @test_float_fadd_ieee_dynamic(
1118; CHECK-NEXT:    [[RESULT:%.*]] = fadd float 0xB810000000000000, 0x3800000000000000
1119; CHECK-NEXT:    ret float [[RESULT]]
1120;
1121  %result = fadd float 0xB810000000000000, 0x3800000000000000
1122  ret float %result
1123}
1124
1125define float @test_float_fadd_dynamic_dynamic() #11 {
1126; CHECK-LABEL: @test_float_fadd_dynamic_dynamic(
1127; CHECK-NEXT:    [[RESULT:%.*]] = fadd float 0xB810000000000000, 0x3800000000000000
1128; CHECK-NEXT:    ret float [[RESULT]]
1129;
1130  %result = fadd float 0xB810000000000000, 0x3800000000000000
1131  ret float %result
1132}
1133
1134; Check for failed to fold on each operand
1135define float @test_float_fadd_dynamic_dynamic_commute() #11 {
1136; CHECK-LABEL: @test_float_fadd_dynamic_dynamic_commute(
1137; CHECK-NEXT:    [[RESULT:%.*]] = fadd float 0x3800000000000000, 0xB810000000000000
1138; CHECK-NEXT:    ret float [[RESULT]]
1139;
1140  %result = fadd float 0x3800000000000000, 0xB810000000000000
1141  ret float %result
1142}
1143
1144define i1 @fcmp_double_dynamic_ieee() #9 {
1145; CHECK-LABEL: @fcmp_double_dynamic_ieee(
1146; CHECK-NEXT:    ret i1 true
1147;
1148  %cmp = fcmp une double 0x0008000000000000, 0x0
1149  ret i1 %cmp
1150}
1151
1152define i1 @fcmp_double_ieee_dynamic() #10 {
1153; CHECK-LABEL: @fcmp_double_ieee_dynamic(
1154; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double 0x8000000000000, 0.000000e+00
1155; CHECK-NEXT:    ret i1 [[CMP]]
1156;
1157  %cmp = fcmp une double 0x0008000000000000, 0x0
1158  ret i1 %cmp
1159}
1160
1161define i1 @fcmp_double_dynamic_dynamic() #11 {
1162; CHECK-LABEL: @fcmp_double_dynamic_dynamic(
1163; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double 0x8000000000000, 0.000000e+00
1164; CHECK-NEXT:    ret i1 [[CMP]]
1165;
1166  %cmp = fcmp une double 0x0008000000000000, 0x0
1167  ret i1 %cmp
1168}
1169
1170define i1 @fcmp_double_dynamic_dynamic_commute() #11 {
1171; CHECK-LABEL: @fcmp_double_dynamic_dynamic_commute(
1172; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double 0.000000e+00, 0x8000000000000
1173; CHECK-NEXT:    ret i1 [[CMP]]
1174;
1175  %cmp = fcmp une double 0x0, 0x0008000000000000
1176  ret i1 %cmp
1177}
1178
1179; Output doesn't matter.
1180define i1 @fcmp_double_dynamic_psz() #12 {
1181; CHECK-LABEL: @fcmp_double_dynamic_psz(
1182; CHECK-NEXT:    ret i1 false
1183;
1184  %cmp = fcmp une double 0x0008000000000000, 0x0
1185  ret i1 %cmp
1186}
1187
1188; Non-denormal values should fold
1189define float @test_float_fadd_dynamic_dynamic_normals() #11 {
1190; CHECK-LABEL: @test_float_fadd_dynamic_dynamic_normals(
1191; CHECK-NEXT:    ret float 3.000000e+00
1192;
1193  %result = fadd float 1.0, 2.0
1194  ret float %result
1195}
1196
1197; Non-denormal values should fold
1198define i1 @fcmp_double_dynamic_dynamic_normals() #11 {
1199; CHECK-LABEL: @fcmp_double_dynamic_dynamic_normals(
1200; CHECK-NEXT:    ret i1 true
1201;
1202  %cmp = fcmp une double 1.0, 2.0
1203  ret i1 %cmp
1204}
1205
1206attributes #0 = { nounwind "denormal-fp-math"="ieee,ieee" }
1207attributes #1 = { nounwind "denormal-fp-math"="positive-zero,ieee" }
1208attributes #2 = { nounwind "denormal-fp-math"="preserve-sign,ieee" }
1209attributes #3 = { nounwind "denormal-fp-math"="ieee,positive-zero" }
1210attributes #4 = { nounwind "denormal-fp-math"="ieee,preserve-sign" }
1211attributes #5 = { nounwind "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="positive-zero,ieee" }
1212attributes #6 = { nounwind "denormal-fp-math"="positive-zero,positive-zero" }
1213attributes #7 = { nounwind "denormal-fp-math"="preserve-sign,preserve-sign" }
1214attributes #8 = { nounwind "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="positive-zero,positive-zero" }
1215attributes #9 = { nounwind "denormal-fp-math"="dynamic,ieee" }
1216attributes #10 = { nounwind "denormal-fp-math"="ieee,dynamic" }
1217attributes #11 = { nounwind "denormal-fp-math"="dynamic,dynamic" }
1218attributes #12 = { nounwind "denormal-fp-math"="dynamic,preserve-sign" }
1219