1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instsimplify -S < %s | FileCheck %s
3
4; Fixes PR20832
5; Make sure that we correctly fold a fused multiply-add where operands
6; are all finite constants and addend is zero.
7
8declare double @llvm.fma.f64(double, double, double)
9
10
11define double @PR20832()  {
12; CHECK-LABEL: @PR20832(
13; CHECK-NEXT:    ret double 5.600000e+01
14;
15  %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0.0)
16  ret double %1
17}
18
19; Test builtin fma with all finite non-zero constants.
20define double @test_all_finite()  {
21; CHECK-LABEL: @test_all_finite(
22; CHECK-NEXT:    ret double 6.100000e+01
23;
24  %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 5.0)
25  ret double %1
26}
27
28; Test builtin fma with a +/-NaN addend.
29define double @test_NaN_addend()  {
30; CHECK-LABEL: @test_NaN_addend(
31; CHECK-NEXT:    ret double 0x7FF8000000000000
32;
33  %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0x7FF8000000000000)
34  ret double %1
35}
36
37define double @test_NaN_addend_2()  {
38; CHECK-LABEL: @test_NaN_addend_2(
39; CHECK-NEXT:    ret double 0xFFF8000000000000
40;
41  %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0xFFF8000000000000)
42  ret double %1
43}
44
45; Test builtin fma with a +/-Inf addend.
46define double @test_Inf_addend()  {
47; CHECK-LABEL: @test_Inf_addend(
48; CHECK-NEXT:    ret double 0x7FF0000000000000
49;
50  %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0x7FF0000000000000)
51  ret double %1
52}
53
54define double @test_Inf_addend_2()  {
55; CHECK-LABEL: @test_Inf_addend_2(
56; CHECK-NEXT:    ret double 0xFFF0000000000000
57;
58  %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0xFFF0000000000000)
59  ret double %1
60}
61
62; Test builtin fma with one of the operands to the multiply being +/-NaN.
63define double @test_NaN_1()  {
64; CHECK-LABEL: @test_NaN_1(
65; CHECK-NEXT:    ret double 0x7FF8000000000000
66;
67  %1 = call double @llvm.fma.f64(double 0x7FF8000000000000, double 8.0, double 0.0)
68  ret double %1
69}
70
71define double @test_NaN_2()  {
72; CHECK-LABEL: @test_NaN_2(
73; CHECK-NEXT:    ret double 0x7FF8000000000000
74;
75  %1 = call double @llvm.fma.f64(double 7.0, double 0x7FF8000000000000, double 0.0)
76  ret double %1
77}
78
79define double @test_NaN_3()  {
80; CHECK-LABEL: @test_NaN_3(
81; CHECK-NEXT:    ret double 0xFFF8000000000000
82;
83  %1 = call double @llvm.fma.f64(double 0xFFF8000000000000, double 8.0, double 0.0)
84  ret double %1
85}
86
87define double @test_NaN_4()  {
88; CHECK-LABEL: @test_NaN_4(
89; CHECK-NEXT:    ret double 0xFFF8000000000000
90;
91  %1 = call double @llvm.fma.f64(double 7.0, double 0xFFF8000000000000, double 0.0)
92  ret double %1
93}
94
95; Test builtin fma with one of the operands to the multiply being +/-Inf.
96define double @test_Inf_1()  {
97; CHECK-LABEL: @test_Inf_1(
98; CHECK-NEXT:    ret double 0x7FF0000000000000
99;
100  %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double 8.0, double 0.0)
101  ret double %1
102}
103
104define double @test_Inf_2()  {
105; CHECK-LABEL: @test_Inf_2(
106; CHECK-NEXT:    ret double 0x7FF0000000000000
107;
108  %1 = call double @llvm.fma.f64(double 7.0, double 0x7FF0000000000000, double 0.0)
109  ret double %1
110}
111
112define double @test_Inf_3()  {
113; CHECK-LABEL: @test_Inf_3(
114; CHECK-NEXT:    ret double 0xFFF0000000000000
115;
116  %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double 8.0, double 0.0)
117  ret double %1
118}
119
120define double @test_Inf_4()  {
121; CHECK-LABEL: @test_Inf_4(
122; CHECK-NEXT:    ret double 0xFFF0000000000000
123;
124  %1 = call double @llvm.fma.f64(double 7.0, double 0xFFF0000000000000, double 0.0)
125  ret double %1
126}
127
128; -inf + inf --> NaN
129
130define double @inf_product_opposite_inf_addend_1()  {
131; CHECK-LABEL: @inf_product_opposite_inf_addend_1(
132; CHECK-NEXT:    ret double 0x7FF8000000000000
133;
134  %1 = call double @llvm.fma.f64(double 7.0, double 0xFFF0000000000000, double 0x7FF0000000000000)
135  ret double %1
136}
137
138; inf + -inf --> NaN
139
140define double @inf_product_opposite_inf_addend_2()  {
141; CHECK-LABEL: @inf_product_opposite_inf_addend_2(
142; CHECK-NEXT:    ret double 0x7FF8000000000000
143;
144  %1 = call double @llvm.fma.f64(double 7.0, double 0x7FF0000000000000, double 0xFFF0000000000000)
145  ret double %1
146}
147
148; -inf + inf --> NaN
149
150define double @inf_product_opposite_inf_addend_3()  {
151; CHECK-LABEL: @inf_product_opposite_inf_addend_3(
152; CHECK-NEXT:    ret double 0x7FF8000000000000
153;
154  %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double 42.0, double 0x7FF0000000000000)
155  ret double %1
156}
157
158; inf + -inf --> NaN
159
160define double @inf_product_opposite_inf_addend_4()  {
161; CHECK-LABEL: @inf_product_opposite_inf_addend_4(
162; CHECK-NEXT:    ret double 0x7FF8000000000000
163;
164  %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double 42.0, double 0xFFF0000000000000)
165  ret double %1
166}
167
168; 0 * -inf --> NaN
169
170define double @inf_times_zero_1()  {
171; CHECK-LABEL: @inf_times_zero_1(
172; CHECK-NEXT:    ret double 0x7FF8000000000000
173;
174  %1 = call double @llvm.fma.f64(double 0.0, double 0xFFF0000000000000, double 42.0)
175  ret double %1
176}
177
178; 0 * inf --> NaN
179
180define double @inf_times_zero_2()  {
181; CHECK-LABEL: @inf_times_zero_2(
182; CHECK-NEXT:    ret double 0x7FF8000000000000
183;
184  %1 = call double @llvm.fma.f64(double 0.0, double 0x7FF0000000000000, double 42.0)
185  ret double %1
186}
187
188; -inf * 0 --> NaN
189
190define double @inf_times_zero_3()  {
191; CHECK-LABEL: @inf_times_zero_3(
192; CHECK-NEXT:    ret double 0x7FF8000000000000
193;
194  %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double 0.0, double 42.0)
195  ret double %1
196}
197
198; inf * 0 --> NaN
199
200define double @inf_times_zero_4()  {
201; CHECK-LABEL: @inf_times_zero_4(
202; CHECK-NEXT:    ret double 0x7FF8000000000000
203;
204  %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double 0.0, double 42.0)
205  ret double %1
206}
207
208; -0 * -inf --> NaN
209
210define double @inf_times_zero_5()  {
211; CHECK-LABEL: @inf_times_zero_5(
212; CHECK-NEXT:    ret double 0x7FF8000000000000
213;
214  %1 = call double @llvm.fma.f64(double -0.0, double 0xFFF0000000000000, double 42.0)
215  ret double %1
216}
217
218; -0 * inf --> NaN
219
220define double @inf_times_zero_6()  {
221; CHECK-LABEL: @inf_times_zero_6(
222; CHECK-NEXT:    ret double 0x7FF8000000000000
223;
224  %1 = call double @llvm.fma.f64(double -0.0, double 0x7FF0000000000000, double 42.0)
225  ret double %1
226}
227
228; -inf * -0 --> NaN
229
230define double @inf_times_zero_7()  {
231; CHECK-LABEL: @inf_times_zero_7(
232; CHECK-NEXT:    ret double 0x7FF8000000000000
233;
234  %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double -0.0, double 42.0)
235  ret double %1
236}
237
238; inf * -0 --> NaN
239
240define double @inf_times_zero_8()  {
241; CHECK-LABEL: @inf_times_zero_8(
242; CHECK-NEXT:    ret double 0x7FF8000000000000
243;
244  %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double -0.0, double 42.0)
245  ret double %1
246}
247