xref: /llvm-project/clang/test/CodeGen/pragma-fenv_access.c (revision 6d3b779792fbf9ec5cc119f1812655da01020b7a)
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