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 -ffinite-math-only -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s
7 (float z) { return n * z + n; }
9 // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
10 // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
11 // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
12 // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
13 float fun_default
FUN(1)
14 //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}}
16 //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
19 // Note that backend wants constrained intrinsics used
20 // throughout the function if they are needed anywhere in the function.
21 // In that case, operations are built with constrained intrinsics operator
22 // but using default settings for exception behavior and rounding mode.
23 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
26 //CHECK-FAST: fmul fast float
27 //CHECK-FAST: fadd fast float
30 #pragma float_control(push)
32 // Rule: precise must be enabled
33 #pragma float_control(except, on)
35 // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
36 // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
37 // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
38 // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
40 //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
42 //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
45 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
48 //CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
51 //Not possible to enable float_control(except) in FAST mode.
52 //CHECK-FAST: fmul fast float
53 //CHECK-FAST: fadd fast float
56 #pragma float_control(pop)
57 // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
58 // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
59 // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
60 // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
62 //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
64 //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
67 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
70 //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
73 //CHECK-FAST: fmul fast float
74 //CHECK-FAST: fadd fast float
77 #pragma float_control(except, off)
79 //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}}
81 //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
84 //CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}}
87 //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
90 //CHECK-FAST: fmul fast float
91 //CHECK-FAST: fadd fast float
94 #pragma float_control(precise, on, push)
95 float precise_on
FUN(3)
96 //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}}
98 //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
101 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
104 // If precise is pushed then all fast-math should be off!
105 //CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}}
108 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
111 #pragma float_control(pop)
112 float precise_pop
FUN(3)
113 //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}}
115 //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
118 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
121 //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
124 //CHECK-FAST: fmul fast float
125 //CHECK-FAST: fadd fast float
127 #pragma float_control(precise, off)
128 float precise_off
FUN(4)
129 //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}}
131 // Note: precise_off enables fp_contract=fast and the instructions
132 // generated do not include the contract flag, although it was enabled
134 //CHECK-DDEFAULT: fmul fast float
135 //CHECK-DDEFAULT: fadd fast float
138 //CHECK-DEBSTRICT: fmul fast float
139 //CHECK-DEBSTRICT: fadd fast float
142 // fast math should be enabled, and contract should be fast
143 //CHECK-NOHONOR: fmul fast float
144 //CHECK-NOHONOR: fadd fast float
147 //CHECK-FAST: fmul fast float
148 //CHECK-FAST: fadd fast float
151 #pragma float_control(precise, on)
152 float precise_on2
FUN(3)
153 //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}}
155 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
158 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
161 // fast math should be off, and contract should be on
162 //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
165 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
168 #pragma float_control(push)
169 float precise_push
FUN(3)
170 //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}}
172 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
175 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
178 //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
181 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
184 #pragma float_control(precise, off)
185 float precise_off2
FUN(4)
186 //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}}
188 //CHECK-DDEFAULT: fmul fast float
189 //CHECK-DDEFAULT: fadd fast float
192 //CHECK-DEBSTRICT: fmul fast float
193 //CHECK-DEBSTRICT: fadd fast float
196 // fast math settings since precise is off
197 //CHECK-NOHONOR: fmul fast float
198 //CHECK-NOHONOR: fadd fast float
201 //CHECK-FAST: fmul fast float
202 //CHECK-FAST: fadd fast float
205 #pragma float_control(pop)
206 float precise_pop2
FUN(3)
207 //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}}
209 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
212 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
215 //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
218 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
222 // Rule: precise must be enabled
223 #pragma float_control(except, on)
226 // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
227 // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
228 // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
229 // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
231 // Settings for top level class initializer use program source setting.
232 float z
= 2 + y() * 7;
233 //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
235 // CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
238 // CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
241 // CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
244 // CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
248 #pragma float_control(except, off)
249 // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
250 // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
251 // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
252 // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
254 float w
= 2 + y() * 7;
255 // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
256 // CHECK: call float {{.*}}llvm.fmuladd
260 #pragma clang fp reassociate(on)
264 MyComplex(float x
, float y
) {
269 const MyComplex
operator+(const MyComplex other
) const {
270 // CHECK-LABEL: define {{.*}} @_ZNK9MyComplexplES_
271 // CHECK: fadd reassoc float
272 // CHECK: fadd reassoc float
273 return MyComplex(xx
+ other
.xx
, yy
+ other
.yy
);
282 // CHECK-DDEFAULT: Function Attrs: noinline nounwind{{$$}}
283 // CHECK-DEBSTRICT: Function Attrs: noinline nounwind strictfp{{$$}}
284 // CHECK-FAST: Function Attrs: noinline nounwind{{$$}}
285 // CHECK-NOHONOR: Function Attrs: noinline nounwind{{$$}}
286 // CHECK-LABEL: define{{.*}} @_GLOBAL__sub_I_fp_floatcontrol_stack
288 // CHECK-DEBSTRICT: {{[ ]}}strictfp{{[ ]}}
289 // CHECK-DEBSTRICT-NOT: "strictfp"