[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / fp-floatcontrol-stack.cpp
blob237c9d4f9a37e283de38940303d2b9a1031de10e
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
6 #define FUN(n) \
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{{.*}}
15 #if DEFAULT
16 //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
17 #endif
18 #if EBSTRICT
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
24 #endif
25 #if FAST
26 //CHECK-FAST: fmul fast float
27 //CHECK-FAST: fadd fast float
28 #endif
30 #pragma float_control(push)
31 #ifndef FAST
32 // Rule: precise must be enabled
33 #pragma float_control(except, on)
34 #endif
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{{$$}}
39 float exc_on FUN(2)
40 //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
41 #if DEFAULT
42 //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
43 #endif
44 #if EBSTRICT
45 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
46 #endif
47 #if NOHONOR
48 //CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
49 #endif
50 #if FAST
51 //Not possible to enable float_control(except) in FAST mode.
52 //CHECK-FAST: fmul fast float
53 //CHECK-FAST: fadd fast float
54 #endif
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{{$$}}
61 float exc_pop FUN(5)
62 //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
63 #if DEFAULT
64 //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
65 #endif
66 #if EBSTRICT
67 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
68 #endif
69 #if NOHONOR
70 //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
71 #endif
72 #if FAST
73 //CHECK-FAST: fmul fast float
74 //CHECK-FAST: fadd fast float
75 #endif
77 #pragma float_control(except, off)
78 float exc_off FUN(5)
79 //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}}
80 #if DEFAULT
81 //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
82 #endif
83 #if EBSTRICT
84 //CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}}
85 #endif
86 #if NOHONOR
87 //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
88 #endif
89 #if FAST
90 //CHECK-FAST: fmul fast float
91 //CHECK-FAST: fadd fast float
92 #endif
94 #pragma float_control(precise, on, push)
95 float precise_on FUN(3)
96 //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}}
97 #if DEFAULT
98 //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
99 #endif
100 #if EBSTRICT
101 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
102 #endif
103 #if NOHONOR
104 // If precise is pushed then all fast-math should be off!
105 //CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}}
106 #endif
107 #if FAST
108 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
109 #endif
111 #pragma float_control(pop)
112 float precise_pop FUN(3)
113 //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}}
114 #if DEFAULT
115 //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
116 #endif
117 #if EBSTRICT
118 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
119 #endif
120 #if NOHONOR
121 //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
122 #endif
123 #if FAST
124 //CHECK-FAST: fmul fast float
125 //CHECK-FAST: fadd fast float
126 #endif
127 #pragma float_control(precise, off)
128 float precise_off FUN(4)
129 //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}}
130 #if DEFAULT
131 // Note: precise_off enables fp_contract=fast and the instructions
132 // generated do not include the contract flag, although it was enabled
133 // in IRBuilder.
134 //CHECK-DDEFAULT: fmul fast float
135 //CHECK-DDEFAULT: fadd fast float
136 #endif
137 #if EBSTRICT
138 //CHECK-DEBSTRICT: fmul fast float
139 //CHECK-DEBSTRICT: fadd fast float
140 #endif
141 #if NOHONOR
142 // fast math should be enabled, and contract should be fast
143 //CHECK-NOHONOR: fmul fast float
144 //CHECK-NOHONOR: fadd fast float
145 #endif
146 #if FAST
147 //CHECK-FAST: fmul fast float
148 //CHECK-FAST: fadd fast float
149 #endif
151 #pragma float_control(precise, on)
152 float precise_on2 FUN(3)
153 //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}}
154 #if DEFAULT
155 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
156 #endif
157 #if EBSTRICT
158 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
159 #endif
160 #if NOHONOR
161 // fast math should be off, and contract should be on
162 //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
163 #endif
164 #if FAST
165 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
166 #endif
168 #pragma float_control(push)
169 float precise_push FUN(3)
170 //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}}
171 #if DEFAULT
172 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
173 #endif
174 #if EBSTRICT
175 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
176 #endif
177 #if NOHONOR
178 //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
179 #endif
180 #if FAST
181 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
182 #endif
184 #pragma float_control(precise, off)
185 float precise_off2 FUN(4)
186 //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}}
187 #if DEFAULT
188 //CHECK-DDEFAULT: fmul fast float
189 //CHECK-DDEFAULT: fadd fast float
190 #endif
191 #if EBSTRICT
192 //CHECK-DEBSTRICT: fmul fast float
193 //CHECK-DEBSTRICT: fadd fast float
194 #endif
195 #if NOHONOR
196 // fast math settings since precise is off
197 //CHECK-NOHONOR: fmul fast float
198 //CHECK-NOHONOR: fadd fast float
199 #endif
200 #if FAST
201 //CHECK-FAST: fmul fast float
202 //CHECK-FAST: fadd fast float
203 #endif
205 #pragma float_control(pop)
206 float precise_pop2 FUN(3)
207 //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}}
208 #if DEFAULT
209 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
210 #endif
211 #if EBSTRICT
212 //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
213 #endif
214 #if NOHONOR
215 //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
216 #endif
217 #if FAST
218 //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
219 #endif
221 #ifndef FAST
222 // Rule: precise must be enabled
223 #pragma float_control(except, on)
224 #endif
225 float y();
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{{$$}}
230 class ON {
231 // Settings for top level class initializer use program source setting.
232 float z = 2 + y() * 7;
233 //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
234 #if DEFAULT
235 // CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
236 #endif
237 #if EBSTRICT
238 // CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
239 #endif
240 #if NOHONOR
241 // CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
242 #endif
243 #if FAST
244 // CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
245 #endif
247 ON on;
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{{$$}}
253 class OFF {
254 float w = 2 + y() * 7;
255 // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
256 // CHECK: call float {{.*}}llvm.fmuladd
258 OFF off;
260 #pragma clang fp reassociate(on)
261 struct MyComplex {
262 float xx;
263 float yy;
264 MyComplex(float x, float y) {
265 xx = x;
266 yy = y;
268 MyComplex() {}
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);
276 MyComplex useAdd() {
277 MyComplex a (1, 3);
278 MyComplex b (2, 4);
279 return a + b;
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"