1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s
2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s
3 // RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s
4 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s
5 
6 #define FUN(n) \
7   (float z) { return n * z + n; }
8 
9 float fun_default FUN(1)
10 //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}}
11 #if DEFAULT
12 //CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}}
13 #endif
14 #if EBSTRICT
15 // Note that backend wants constrained intrinsics used
16 // throughout the function if they are needed anywhere in the function.
17 // In that case, operations are built with constrained intrinsics operator
18 // but using default settings for exception behavior and rounding mode.
19 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
20 #endif
21 #if FAST
22 //CHECK-FAST: fmul fast float
23 //CHECK-FAST: fadd fast float
24 #endif
25 
26 #pragma float_control(push)
27 #ifndef FAST
28 // Rule: precise must be enabled
29 #pragma float_control(except, on)
30 #endif
31     float exc_on FUN(2)
32 //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
33 #if DEFAULT
34 //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
35 #endif
36 #if EBSTRICT
37 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
38 #endif
39 #if NOHONOR
40 //CHECK-NOHONOR: nnan ninf contract float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
41 #endif
42 #if FAST
43 //Not possible to enable float_control(except) in FAST mode.
44 //CHECK-FAST: fmul fast float
45 //CHECK-FAST: fadd fast float
46 #endif
47 
48 #pragma float_control(pop)
49         float exc_pop FUN(5)
50 //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
51 #if DEFAULT
52 //CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}}
53 #endif
54 #if EBSTRICT
55 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
56 #endif
57 #if NOHONOR
58 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
59 #endif
60 #if FAST
61 //CHECK-FAST: fmul fast float
62 //CHECK-FAST: fadd fast float
63 #endif
64 
65 #pragma float_control(except, off)
66             float exc_off FUN(5)
67 //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}}
68 #if DEFAULT
69 //CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}}
70 #endif
71 #if EBSTRICT
72 //CHECK-DEBSTRICT: call contract float @llvm.fmuladd{{.*}}
73 #endif
74 #if NOHONOR
75 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
76 #endif
77 #if FAST
78 //CHECK-FAST: fmul fast float
79 //CHECK-FAST: fadd fast float
80 #endif
81 
82 #pragma float_control(precise, on, push)
83                 float precise_on FUN(3)
84 //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}}
85 #if DEFAULT
86 //CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}}
87 #endif
88 #if EBSTRICT
89 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
90 #endif
91 #if NOHONOR
92 // If precise is pushed then all fast-math should be off!
93 //CHECK-NOHONOR: call contract float {{.*}}llvm.fmuladd{{.*}}
94 #endif
95 #if FAST
96 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
97 #endif
98 
99 #pragma float_control(pop)
100                     float precise_pop FUN(3)
101 //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}}
102 #if DEFAULT
103 //CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}}
104 #endif
105 #if EBSTRICT
106 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
107 #endif
108 #if NOHONOR
109 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
110 #endif
111 #if FAST
112 //CHECK-FAST: fmul fast float
113 //CHECK-FAST: fadd fast float
114 #endif
115 #pragma float_control(precise, off)
116                         float precise_off FUN(4)
117 //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}}
118 #if DEFAULT
119 // Note: precise_off enables fp_contract=fast and the instructions
120 // generated do not include the contract flag, although it was enabled
121 // in IRBuilder.
122 //CHECK-DDEFAULT: fmul fast float
123 //CHECK-DDEFAULT: fadd fast float
124 #endif
125 #if EBSTRICT
126 //CHECK-DEBSTRICT: fmul fast float
127 //CHECK-DEBSTRICT: fadd fast float
128 #endif
129 #if NOHONOR
130 // fast math should be enabled, and contract should be fast
131 //CHECK-NOHONOR: fmul fast float
132 //CHECK-NOHONOR: fadd fast float
133 #endif
134 #if FAST
135 //CHECK-FAST: fmul fast float
136 //CHECK-FAST: fadd fast float
137 #endif
138 
139 #pragma float_control(precise, on)
140                             float precise_on2 FUN(3)
141 //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}}
142 #if DEFAULT
143 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
144 #endif
145 #if EBSTRICT
146 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
147 #endif
148 #if NOHONOR
149 // fast math should be off, and contract should be on
150 //CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}}
151 #endif
152 #if FAST
153 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
154 #endif
155 
156 #pragma float_control(push)
157                                 float precise_push FUN(3)
158 //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}}
159 #if DEFAULT
160 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
161 #endif
162 #if EBSTRICT
163 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
164 #endif
165 #if NOHONOR
166 //CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}}
167 #endif
168 #if FAST
169 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
170 #endif
171 
172 #pragma float_control(precise, off)
173                                     float precise_off2 FUN(4)
174 //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}}
175 #if DEFAULT
176 //CHECK-DDEFAULT: fmul fast float
177 //CHECK-DDEFAULT: fadd fast float
178 #endif
179 #if EBSTRICT
180 //CHECK-DEBSTRICT: fmul fast float
181 //CHECK-DEBSTRICT: fadd fast float
182 #endif
183 #if NOHONOR
184 // fast math settings since precise is off
185 //CHECK-NOHONOR: fmul fast float
186 //CHECK-NOHONOR: fadd fast float
187 #endif
188 #if FAST
189 //CHECK-FAST: fmul fast float
190 //CHECK-FAST: fadd fast float
191 #endif
192 
193 #pragma float_control(pop)
194                                         float precise_pop2 FUN(3)
195 //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}}
196 #if DEFAULT
197 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
198 #endif
199 #if EBSTRICT
200 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
201 #endif
202 #if NOHONOR
203 //CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}}
204 #endif
205 #if FAST
206 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
207 #endif
208 
209 #ifndef FAST
210 // Rule: precise must be enabled
211 #pragma float_control(except, on)
212 #endif
213                                             float y();
214 class ON {
215   // Settings for top level class initializer revert to command line
216   // source pragma's do not pertain.
217   float z = 2 + y() * 7;
218 //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
219 #if DEFAULT
220 //CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd
221 #endif
222 #if EBSTRICT
223 //Currently, same as default [command line options not considered]
224 //CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd
225 #endif
226 #if NOHONOR
227 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
228 #endif
229 #if FAST
230 //CHECK-FAST: fmul fast float
231 //CHECK-FAST: fadd fast float
232 #endif
233 };
234 ON on;
235 #pragma float_control(except, off)
236 class OFF {
237   float w = 2 + y() * 7;
238 //CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
239 #if DEFAULT
240 //CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd
241 #endif
242 #if EBSTRICT
243 //CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd
244 #endif
245 #if NOHONOR
246 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
247 #endif
248 #if FAST
249 //CHECK-FAST: fmul fast float
250 //CHECK-FAST: fadd fast float
251 #endif
252 };
253 OFF off;
254