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