blob: a80a4d377660173faa9313a4842bc026278b11a6 [file] [log] [blame]
Melanie Blower7f2db992020-05-08 08:05:34 -07001// RUN: %clang_cc1 -DEXCEPT=1 -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NS %s
Melanie Blowerf5360d42020-05-01 10:32:06 -07002// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
Melanie Blowere5578012020-05-06 11:45:55 -07003// RUN: %clang_cc1 -verify -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
Melanie Blowerf5360d42020-05-01 10:32:06 -07004
5float fff(float x, float y) {
6// CHECK-LABEL: define float @_Z3fffff{{.*}}
7// CHECK: entry
8#pragma float_control(except, on)
9 float z;
10 z = z * z;
11 //CHECK: llvm.experimental.constrained.fmul{{.*}}
12 {
13 z = x * y;
14 //CHECK: llvm.experimental.constrained.fmul{{.*}}
15 }
16 {
17// This pragma has no effect since if there are any fp intrin in the
18// function then all the operations need to be fp intrin
19#pragma float_control(except, off)
20 z = z + x * y;
21 //CHECK: llvm.experimental.constrained.fmul{{.*}}
22 }
23 z = z * z;
24 //CHECK: llvm.experimental.constrained.fmul{{.*}}
25 return z;
26}
27float check_precise(float x, float y) {
28 // CHECK-LABEL: define float @_Z13check_preciseff{{.*}}
29 float z;
30 {
31#pragma float_control(precise, on)
32 z = x * y + z;
33 //CHECK: llvm.fmuladd{{.*}}
34 }
35 {
36#pragma float_control(precise, off)
37 z = x * y + z;
38 //CHECK: fmul fast float
39 //CHECK: fadd fast float
40 }
41 return z;
42}
Melanie Blowere5578012020-05-06 11:45:55 -070043
Melanie Blowerf5360d42020-05-01 10:32:06 -070044float fma_test1(float a, float b, float c) {
45// CHECK-LABEL define float @_Z9fma_test1fff{{.*}}
46#pragma float_control(precise, on)
47 float x = a * b + c;
48 //CHECK: fmuladd
49 return x;
50}
Melanie Blowere5578012020-05-06 11:45:55 -070051
52#if FENV_ON
53// expected-warning@+1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
54#pragma STDC FENV_ACCESS ON
55#endif
56// CHECK-LABEL: define {{.*}}callt{{.*}}
57
58void callt() {
59 volatile float z;
60 z = z * z;
61//CHECK: = fmul float
62}
Melanie Blower7f2db992020-05-08 08:05:34 -070063
64#if EXCEPT
65namespace ns {
66// Check that pragma float_control can appear in namespace.
67#pragma float_control(except, on, push)
68float exc_on(double x, float zero) {
69// CHECK-NS: define {{.*}}exc_on{{.*}}
70 {} try {
71 x = 1.0 / zero; /* division by zero, the result unused */
72//CHECK-NS: llvm.experimental.constrained.fdiv{{.*}}
73 } catch (...) {}
74 return zero;
75}
76}
77
78// Check pragma is still effective after namespace closes
79float exc_still_on(double x, float zero) {
80// CHECK-NS: define {{.*}}exc_still_on{{.*}}
81 {} try {
82 x = 1.0 / zero; /* division by zero, the result unused */
83//CHECK-NS: llvm.experimental.constrained.fdiv{{.*}}
84 } catch (...) {}
85 return zero;
86}
87
88#pragma float_control(pop)
89float exc_off(double x, float zero) {
90// CHECK-NS: define {{.*}}exc_off{{.*}}
91 {} try {
92 x = 1.0 / zero; /* division by zero, the result unused */
93//CHECK-NS: fdiv contract double
94 } catch (...) {}
95 return zero;
96}
97
98namespace fc_template_namespace {
99#pragma float_control(except, on, push)
100template <class T>
101T exc_on(double x, T zero) {
102// CHECK-NS: define {{.*}}fc_template_namespace{{.*}}
103 {} try {
104 x = 1.0 / zero; /* division by zero, the result unused */
105//CHECK-NS: llvm.experimental.constrained.fdiv{{.*}}
106 } catch (...) {}
107 return zero;
108}
109}
110
111#pragma float_control(pop)
112float xx(double x, float z) {
113 return fc_template_namespace::exc_on<float>(x, z);
114}
115#endif // EXCEPT