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