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
9*0a175ad4SMelanie Blower // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
10*0a175ad4SMelanie Blower // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
11*0a175ad4SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
12*0a175ad4SMelanie Blower // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
13f5360d4bSMelanie Blower float fun_default FUN(1)
14f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}}
15f5360d4bSMelanie Blower #if DEFAULT
16827be690SMelanie Blower //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
17f5360d4bSMelanie Blower #endif
18f5360d4bSMelanie Blower #if EBSTRICT
19f5360d4bSMelanie Blower // Note that backend wants constrained intrinsics used
20f5360d4bSMelanie Blower // throughout the function if they are needed anywhere in the function.
21f5360d4bSMelanie Blower // In that case, operations are built with constrained intrinsics operator
22f5360d4bSMelanie Blower // but using default settings for exception behavior and rounding mode.
23f5360d4bSMelanie Blower //CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
24f5360d4bSMelanie Blower #endif
25f5360d4bSMelanie Blower #if FAST
26f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
27f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
28f5360d4bSMelanie Blower #endif
29f5360d4bSMelanie Blower
30f5360d4bSMelanie Blower #pragma float_control(push)
31f5360d4bSMelanie Blower #ifndef FAST
32f5360d4bSMelanie Blower // Rule: precise must be enabled
33f5360d4bSMelanie Blower #pragma float_control(except, on)
34f5360d4bSMelanie Blower #endif
35*0a175ad4SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
36*0a175ad4SMelanie Blower // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
37*0a175ad4SMelanie Blower // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
38*0a175ad4SMelanie Blower // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
39f5360d4bSMelanie Blower float exc_on FUN(2)
40f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
41f5360d4bSMelanie Blower #if DEFAULT
42f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
43f5360d4bSMelanie Blower #endif
44f5360d4bSMelanie Blower #if EBSTRICT
45f5360d4bSMelanie Blower //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
46f5360d4bSMelanie Blower #endif
47f5360d4bSMelanie Blower #if NOHONOR
48827be690SMelanie Blower //CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
49f5360d4bSMelanie Blower #endif
50f5360d4bSMelanie Blower #if FAST
51f5360d4bSMelanie Blower //Not possible to enable float_control(except) in FAST mode.
52f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
53f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
54f5360d4bSMelanie Blower #endif
55f5360d4bSMelanie Blower
56f5360d4bSMelanie Blower #pragma float_control(pop)
57*0a175ad4SMelanie Blower // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
58*0a175ad4SMelanie Blower // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
59*0a175ad4SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
60*0a175ad4SMelanie Blower // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
61f5360d4bSMelanie Blower float exc_pop FUN(5)
62f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
63f5360d4bSMelanie Blower #if DEFAULT
64827be690SMelanie Blower //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
65f5360d4bSMelanie Blower #endif
66f5360d4bSMelanie Blower #if EBSTRICT
67f5360d4bSMelanie Blower //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
68f5360d4bSMelanie Blower #endif
69f5360d4bSMelanie Blower #if NOHONOR
70827be690SMelanie Blower //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
71f5360d4bSMelanie Blower #endif
72f5360d4bSMelanie Blower #if FAST
73f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
74f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
75f5360d4bSMelanie Blower #endif
76f5360d4bSMelanie Blower
77f5360d4bSMelanie Blower #pragma float_control(except, off)
78f5360d4bSMelanie Blower float exc_off FUN(5)
79f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}}
80f5360d4bSMelanie Blower #if DEFAULT
81827be690SMelanie Blower //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
82f5360d4bSMelanie Blower #endif
83f5360d4bSMelanie Blower #if EBSTRICT
84827be690SMelanie Blower //CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}}
85f5360d4bSMelanie Blower #endif
86f5360d4bSMelanie Blower #if NOHONOR
87827be690SMelanie Blower //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
88f5360d4bSMelanie Blower #endif
89f5360d4bSMelanie Blower #if FAST
90f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
91f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
92f5360d4bSMelanie Blower #endif
93f5360d4bSMelanie Blower
94f5360d4bSMelanie Blower #pragma float_control(precise, on, push)
95f5360d4bSMelanie Blower float precise_on FUN(3)
96f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}}
97f5360d4bSMelanie Blower #if DEFAULT
98827be690SMelanie Blower //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
99f5360d4bSMelanie Blower #endif
100f5360d4bSMelanie Blower #if EBSTRICT
101827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
102f5360d4bSMelanie Blower #endif
103f5360d4bSMelanie Blower #if NOHONOR
104f5360d4bSMelanie Blower // If precise is pushed then all fast-math should be off!
105827be690SMelanie Blower //CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}}
106f5360d4bSMelanie Blower #endif
107f5360d4bSMelanie Blower #if FAST
108827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
109f5360d4bSMelanie Blower #endif
110f5360d4bSMelanie Blower
111f5360d4bSMelanie Blower #pragma float_control(pop)
112f5360d4bSMelanie Blower float precise_pop FUN(3)
113f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}}
114f5360d4bSMelanie Blower #if DEFAULT
115827be690SMelanie Blower //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
116f5360d4bSMelanie Blower #endif
117f5360d4bSMelanie Blower #if EBSTRICT
118827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
119f5360d4bSMelanie Blower #endif
120f5360d4bSMelanie Blower #if NOHONOR
121827be690SMelanie Blower //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
122f5360d4bSMelanie Blower #endif
123f5360d4bSMelanie Blower #if FAST
124f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
125f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
126f5360d4bSMelanie Blower #endif
127f5360d4bSMelanie Blower #pragma float_control(precise, off)
128f5360d4bSMelanie Blower float precise_off FUN(4)
129f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}}
130f5360d4bSMelanie Blower #if DEFAULT
131f5360d4bSMelanie Blower // Note: precise_off enables fp_contract=fast and the instructions
132f5360d4bSMelanie Blower // generated do not include the contract flag, although it was enabled
133f5360d4bSMelanie Blower // in IRBuilder.
134f5360d4bSMelanie Blower //CHECK-DDEFAULT: fmul fast float
135f5360d4bSMelanie Blower //CHECK-DDEFAULT: fadd fast float
136f5360d4bSMelanie Blower #endif
137f5360d4bSMelanie Blower #if EBSTRICT
138f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fmul fast float
139f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fadd fast float
140f5360d4bSMelanie Blower #endif
141f5360d4bSMelanie Blower #if NOHONOR
142f5360d4bSMelanie Blower // fast math should be enabled, and contract should be fast
143f5360d4bSMelanie Blower //CHECK-NOHONOR: fmul fast float
144f5360d4bSMelanie Blower //CHECK-NOHONOR: fadd fast float
145f5360d4bSMelanie Blower #endif
146f5360d4bSMelanie Blower #if FAST
147f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
148f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
149f5360d4bSMelanie Blower #endif
150f5360d4bSMelanie Blower
151f5360d4bSMelanie Blower #pragma float_control(precise, on)
152f5360d4bSMelanie Blower float precise_on2 FUN(3)
153f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}}
154f5360d4bSMelanie Blower #if DEFAULT
155f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
156f5360d4bSMelanie Blower #endif
157f5360d4bSMelanie Blower #if EBSTRICT
158827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
159f5360d4bSMelanie Blower #endif
160f5360d4bSMelanie Blower #if NOHONOR
161f5360d4bSMelanie Blower // fast math should be off, and contract should be on
162827be690SMelanie Blower //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
163f5360d4bSMelanie Blower #endif
164f5360d4bSMelanie Blower #if FAST
165827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
166f5360d4bSMelanie Blower #endif
167f5360d4bSMelanie Blower
168f5360d4bSMelanie Blower #pragma float_control(push)
169f5360d4bSMelanie Blower float precise_push FUN(3)
170f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}}
171f5360d4bSMelanie Blower #if DEFAULT
172f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
173f5360d4bSMelanie Blower #endif
174f5360d4bSMelanie Blower #if EBSTRICT
175827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
176f5360d4bSMelanie Blower #endif
177f5360d4bSMelanie Blower #if NOHONOR
178827be690SMelanie Blower //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
179f5360d4bSMelanie Blower #endif
180f5360d4bSMelanie Blower #if FAST
181827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
182f5360d4bSMelanie Blower #endif
183f5360d4bSMelanie Blower
184f5360d4bSMelanie Blower #pragma float_control(precise, off)
185f5360d4bSMelanie Blower float precise_off2 FUN(4)
186f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}}
187f5360d4bSMelanie Blower #if DEFAULT
188f5360d4bSMelanie Blower //CHECK-DDEFAULT: fmul fast float
189f5360d4bSMelanie Blower //CHECK-DDEFAULT: fadd fast float
190f5360d4bSMelanie Blower #endif
191f5360d4bSMelanie Blower #if EBSTRICT
192f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fmul fast float
193f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fadd fast float
194f5360d4bSMelanie Blower #endif
195f5360d4bSMelanie Blower #if NOHONOR
196f5360d4bSMelanie Blower // fast math settings since precise is off
197f5360d4bSMelanie Blower //CHECK-NOHONOR: fmul fast float
198f5360d4bSMelanie Blower //CHECK-NOHONOR: fadd fast float
199f5360d4bSMelanie Blower #endif
200f5360d4bSMelanie Blower #if FAST
201f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float
202f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float
203f5360d4bSMelanie Blower #endif
204f5360d4bSMelanie Blower
205f5360d4bSMelanie Blower #pragma float_control(pop)
206f5360d4bSMelanie Blower float precise_pop2 FUN(3)
207f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}}
208f5360d4bSMelanie Blower #if DEFAULT
209f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
210f5360d4bSMelanie Blower #endif
211f5360d4bSMelanie Blower #if EBSTRICT
212827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
213f5360d4bSMelanie Blower #endif
214f5360d4bSMelanie Blower #if NOHONOR
215827be690SMelanie Blower //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
216f5360d4bSMelanie Blower #endif
217f5360d4bSMelanie Blower #if FAST
218827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
219f5360d4bSMelanie Blower #endif
220f5360d4bSMelanie Blower
221f5360d4bSMelanie Blower #ifndef FAST
222f5360d4bSMelanie Blower // Rule: precise must be enabled
223f5360d4bSMelanie Blower #pragma float_control(except, on)
224f5360d4bSMelanie Blower #endif
225f5360d4bSMelanie Blower float y();
226*0a175ad4SMelanie Blower // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
227*0a175ad4SMelanie Blower // CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}}
228*0a175ad4SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
229*0a175ad4SMelanie Blower // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
230f5360d4bSMelanie Blower class ON {
23133b1f3f4SMelanie Blower // Settings for top level class initializer use program source setting.
232f5360d4bSMelanie Blower float z = 2 + y() * 7;
233f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
234f5360d4bSMelanie Blower #if DEFAULT
235bc5b5ea0SMelanie Blower // CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
236f5360d4bSMelanie Blower #endif
237f5360d4bSMelanie Blower #if EBSTRICT
238bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
239f5360d4bSMelanie Blower #endif
240f5360d4bSMelanie Blower #if NOHONOR
241bc5b5ea0SMelanie Blower // CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
242f5360d4bSMelanie Blower #endif
243f5360d4bSMelanie Blower #if FAST
24433b1f3f4SMelanie Blower // CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
245f5360d4bSMelanie Blower #endif
246f5360d4bSMelanie Blower };
247f5360d4bSMelanie Blower ON on;
248f5360d4bSMelanie Blower #pragma float_control(except, off)
249*0a175ad4SMelanie Blower // CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}}
250*0a175ad4SMelanie Blower // CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}}
251*0a175ad4SMelanie Blower // CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}}
252*0a175ad4SMelanie Blower // CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}}
253f5360d4bSMelanie Blower class OFF {
254f5360d4bSMelanie Blower float w = 2 + y() * 7;
255f5360d4bSMelanie Blower // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
25633b1f3f4SMelanie Blower // CHECK: call float {{.*}}llvm.fmuladd
257f5360d4bSMelanie Blower };
258f5360d4bSMelanie Blower OFF off;
25933b1f3f4SMelanie Blower
26033b1f3f4SMelanie Blower #pragma clang fp reassociate(on)
26133b1f3f4SMelanie Blower struct MyComplex {
26233b1f3f4SMelanie Blower float xx;
26333b1f3f4SMelanie Blower float yy;
MyComplexMyComplex26433b1f3f4SMelanie Blower MyComplex(float x, float y) {
26533b1f3f4SMelanie Blower xx = x;
26633b1f3f4SMelanie Blower yy = y;
26733b1f3f4SMelanie Blower }
MyComplexMyComplex26833b1f3f4SMelanie Blower MyComplex() {}
operator +MyComplex26933b1f3f4SMelanie Blower const MyComplex operator+(const MyComplex other) const {
27033b1f3f4SMelanie Blower // CHECK-LABEL: define {{.*}} @_ZNK9MyComplexplES_
27133b1f3f4SMelanie Blower // CHECK: fadd reassoc float
27233b1f3f4SMelanie Blower // CHECK: fadd reassoc float
27333b1f3f4SMelanie Blower return MyComplex(xx + other.xx, yy + other.yy);
27433b1f3f4SMelanie Blower }
27533b1f3f4SMelanie Blower };
useAdd()27633b1f3f4SMelanie Blower MyComplex useAdd() {
27733b1f3f4SMelanie Blower MyComplex a (1, 3);
27833b1f3f4SMelanie Blower MyComplex b (2, 4);
27933b1f3f4SMelanie Blower return a + b;
28033b1f3f4SMelanie Blower }
281bc5b5ea0SMelanie Blower
282*0a175ad4SMelanie Blower // CHECK-DDEFAULT: Function Attrs: noinline nounwind{{$$}}
283*0a175ad4SMelanie Blower // CHECK-DEBSTRICT: Function Attrs: noinline nounwind strictfp{{$$}}
284*0a175ad4SMelanie Blower // CHECK-FAST: Function Attrs: noinline nounwind{{$$}}
285*0a175ad4SMelanie Blower // CHECK-NOHONOR: Function Attrs: noinline nounwind{{$$}}
286bc5b5ea0SMelanie Blower // CHECK-LABEL: define{{.*}} @_GLOBAL__sub_I_fp_floatcontrol_stack
287