1 // RUN: %clang_cc1 -fexperimental-strict-floating-point -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,STRICT %s
2 // RUN: %clang_cc1 -fexperimental-strict-floating-point -frounding-math -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,STRICT-RND %s
3 // RUN: %clang_cc1 -fexperimental-strict-floating-point -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - -fms-extensions -DMS | FileCheck --check-prefixes=CHECK,STRICT %s
4 // RUN: %clang_cc1 -fexperimental-strict-floating-point -frounding-math -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - -fms-extensions -DMS | FileCheck --check-prefixes=CHECK,STRICT-RND %s
5 // RUN: %clang_cc1 -fexperimental-strict-floating-point -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,DEFAULT %s
6 // RUN: %clang_cc1 -fexperimental-strict-floating-point -frounding-math -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,DEFAULT-RND %s
7
func_00(float x,float y)8 float func_00(float x, float y) {
9 return x + y;
10 }
11 // CHECK-LABEL: @func_00
12 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
13 // STRICT-RND: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
14 // DEFAULT-RND: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore")
15 // DEFAULT: fadd float
16
17
18 #ifdef MS
19 #pragma fenv_access (on)
20 #else
21 #pragma STDC FENV_ACCESS ON
22 #endif
23
func_01(float x,float y)24 float func_01(float x, float y) {
25 return x + y;
26 }
27 // CHECK-LABEL: @func_01
28 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
29
30
func_02(float x,float y)31 float func_02(float x, float y) {
32 #pragma float_control(except, off)
33 #pragma STDC FENV_ACCESS OFF
34 return x + y;
35 }
36 // CHECK-LABEL: @func_02
37 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
38
39
func_03(float x,float y)40 float func_03(float x, float y) {
41 return x + y;
42 }
43 // CHECK-LABEL: @func_03
44 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
45
46
47 #ifdef MS
48 #pragma fenv_access (off)
49 #else
50 #pragma STDC FENV_ACCESS OFF
51 #endif
52
func_04(float x,float y)53 float func_04(float x, float y) {
54 #pragma float_control(except, off)
55 return x + y;
56 }
57 // CHECK-LABEL: @func_04
58 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
59 // DEFAULT: fadd float
60
61
func_04a(float x,float y)62 float func_04a(float x, float y) {
63 #pragma float_control(except, on)
64 return x + y;
65 }
66 // CHECK-LABEL: @func_04a
67 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
68
69
func_05(float x,float y)70 float func_05(float x, float y) {
71 #pragma STDC FENV_ACCESS ON
72 return x + y;
73 }
74 // CHECK-LABEL: @func_05
75 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
76
77
func_06(float x,float y)78 float func_06(float x, float y) {
79 #pragma float_control(except, off)
80 return x + y;
81 }
82 // CHECK-LABEL: @func_06
83 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
84 // DEFAULT: fadd float
85
86
func_07(float x,float y)87 float func_07(float x, float y) {
88 x -= y;
89 if (x) {
90 #pragma STDC FENV_ACCESS ON
91 y *= 2.0F;
92 }
93 return y + 4.0F;
94 }
95 // CHECK-LABEL: @func_07
96 // STRICT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
97 // STRICT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
98 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
99 // DEFAULT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
100 // DEFAULT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
101 // DEFAULT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
102
103
func_08(float x,float y)104 float func_08(float x, float y) {
105 #pragma STDC FENV_ROUND FE_UPWARD
106 #pragma STDC FENV_ACCESS ON
107 return x + y;
108 }
109 // CHECK-LABEL: @func_08
110 // CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.strict")
111
112
func_09(float x,float y)113 float func_09(float x, float y) {
114 #pragma STDC FENV_ROUND FE_TONEAREST
115 #pragma STDC FENV_ACCESS ON
116 return x + y;
117 }
118 // CHECK-LABEL: @func_09
119 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
120
121
func_10(float x,float y)122 float func_10(float x, float y) {
123 #pragma STDC FENV_ROUND FE_TONEAREST
124 #pragma clang fp exceptions(ignore)
125 #pragma STDC FENV_ACCESS ON
126 return x + y;
127 }
128 // CHECK-LABEL: @func_10
129 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
130
131
func_11(float x,float y)132 float func_11(float x, float y) {
133 #pragma STDC FENV_ROUND FE_TONEAREST
134 #pragma clang fp exceptions(ignore)
135 #pragma STDC FENV_ACCESS OFF
136 return x + y;
137 }
138 // CHECK-LABEL: @func_11
139 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
140 // DEFAULT: fadd float
141
142
func_12(float x,float y)143 float func_12(float x, float y) {
144 #pragma clang fp exceptions(maytrap)
145 #pragma STDC FENV_ACCESS ON
146 return x + y;
147 }
148 // CHECK-LABEL: @func_12
149 // CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.maytrap")
150
151
func_13(float x,float y)152 float func_13(float x, float y) {
153 #pragma clang fp exceptions(maytrap)
154 #pragma STDC FENV_ROUND FE_UPWARD
155 #pragma STDC FENV_ACCESS ON
156 return x + y;
157 }
158 // CHECK-LABEL: @func_13
159 // CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.maytrap")
160
161
func_14(float x,float y,float z)162 float func_14(float x, float y, float z) {
163 #pragma STDC FENV_ACCESS ON
164 float res = x * y;
165 {
166 #pragma STDC FENV_ACCESS OFF
167 return res + z;
168 }
169 }
170 // CHECK-LABEL: @func_14
171 // STRICT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
172 // STRICT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
173 // DEFAULT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
174 // DEFAULT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
175
176
func_15(float x,float y,float z)177 float func_15(float x, float y, float z) {
178 #pragma STDC FENV_ROUND FE_TOWARDZERO
179 #pragma STDC FENV_ACCESS ON
180 float res = x * y;
181 {
182 #pragma STDC FENV_ACCESS OFF
183 return res + z;
184 }
185 }
186 // CHECK-LABEL: @func_15
187 // STRICT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.strict")
188 // STRICT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.strict")
189 // DEFAULT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.strict")
190 // DEFAULT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
191
192
func_16(float x,float y)193 float func_16(float x, float y) {
194 x -= y;
195 {
196 #pragma STDC FENV_ROUND FE_TONEAREST
197 #pragma STDC FENV_ACCESS ON
198 y *= 2.0F;
199 }
200 {
201 #pragma STDC FENV_ACCESS ON
202 return y + 4.0F;
203 }
204 }
205 // CHECK-LABEL: @func_16
206 // STRICT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
207 // STRICT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
208 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
209 // DEFAULT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
210 // DEFAULT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
211 // DEFAULT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
212
213
func_17(float x,float y)214 float func_17(float x, float y) {
215 #pragma STDC FENV_ROUND FE_DYNAMIC
216 #pragma STDC FENV_ACCESS ON
217 return x + y;
218 }
219 // CHECK-LABEL: @func_17
220 // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
221
222
func_18(float x,float y)223 float func_18(float x, float y) {
224 #pragma STDC FENV_ROUND FE_DYNAMIC
225 return x + y;
226 }
227 // CHECK-LABEL: @func_18
228 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
229 // DEFAULT: fadd float
230
231 #pragma STDC FENV_ACCESS ON
func_19(float x,float y)232 float func_19(float x, float y) {
233 return x + y;
234 }
235 // CHECK-LABEL: @func_19
236 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
237
238 #pragma STDC FENV_ACCESS OFF
func_20(float x,float y)239 float func_20(float x, float y) {
240 return x + y;
241 }
242 // CHECK-LABEL: @func_20
243 // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
244 // DEFAULT: fadd float
245