1 // RUN: %clang_cc1 -no-opaque-pointers -fexperimental-strict-floating-point  \
2 // RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s  \
3 // RUN: | FileCheck %s -check-prefixes=CHECK
4 
5 // RUN: %clang_cc1 -no-opaque-pointers -triple i386--linux -emit-llvm -o - %s \
6 // RUN: | FileCheck %s -check-prefixes=CHECK-EXT
7 
8 // RUN: %clang_cc1 -no-opaque-pointers -fexperimental-strict-floating-point  \
9 // RUN: -mreassociate -freciprocal-math -ffp-contract=fast \
10 // RUN: -ffast-math -triple x86_64-linux-gnu \
11 // RUN: -emit-llvm -o - %s \
12 // RUN: | FileCheck %s -check-prefixes=CHECK-FAST
13 
14 // RUN: %clang_cc1 -no-opaque-pointers -triple i386--linux -mreassociate -freciprocal-math \
15 // RUN: -ffp-contract=fast -ffast-math -emit-llvm -o - %s \
16 // RUN: | FileCheck %s -check-prefixes=CHECK-FAST
17 
18 float a = 1.0f, b = 2.0f, c = 3.0f;
19 #pragma float_control(precise, off)
20 float res2 = a + b + c;
21 int val3 = __FLT_EVAL_METHOD__;
22 #pragma float_control(precise, on)
23 float res3 = a + b + c;
24 int val4 = __FLT_EVAL_METHOD__;
25 
26 // CHECK: @val3 = global i32 -1
27 // CHECK: @val4 = global i32 0
28 
29 // CHECK-EXT: @val3 = global i32 -1
30 // CHECK-EXT: @val4 = global i32 2
31 
32 // CHECK-FAST: @val3 = global i32 -1
33 // CHECK-FAST: @val4 = global i32 -1
34 
35 float res;
add(float a,float b,float c)36 int add(float a, float b, float c) {
37   // CHECK: fadd float
38   // CHECK: load float, float*
39   // CHECK: fadd float
40   // CHECK: store float
41   // CHECK: ret i32 0
42   res = a + b + c;
43   return __FLT_EVAL_METHOD__;
44 }
45 
add_precise(float a,float b,float c)46 int add_precise(float a, float b, float c) {
47 #pragma float_control(precise, on)
48   // CHECK: fadd float
49   // CHECK: load float, float*
50   // CHECK: fadd float
51   // CHECK: store float
52   // CHECK: ret i32 0
53   res = a + b + c;
54   return __FLT_EVAL_METHOD__;
55 }
56 
57 #pragma float_control(push)
58 #pragma float_control(precise, on)
add_precise_1(float a,float b,float c)59 int add_precise_1(float a, float b, float c) {
60   // CHECK: fadd float
61   // CHECK: load float, float*
62   // CHECK: fadd float
63   // CHECK: store float
64   // CHECK: ret i32 0
65   res = a + b + c;
66   return __FLT_EVAL_METHOD__;
67 }
68 #pragma float_control(pop)
69 
add_not_precise(float a,float b,float c)70 int add_not_precise(float a, float b, float c) {
71   // Fast-math is enabled with this pragma.
72 #pragma float_control(precise, off)
73   // CHECK: fadd fast float
74   // CHECK: load float, float*
75   // CHECK: fadd fast float
76   // CHECK: float {{.*}}, float*
77   // CHECK: ret i32 -1
78   res = a + b + c;
79   return __FLT_EVAL_METHOD__;
80 }
81 
82 #pragma float_control(push)
83 // Fast-math is enabled with this pragma.
84 #pragma float_control(precise, off)
add_not_precise_1(float a,float b,float c)85 int add_not_precise_1(float a, float b, float c) {
86   // CHECK: fadd fast float
87   // CHECK: load float, float*
88   // CHECK: fadd fast float
89   // CHECK: float {{.*}}, float*
90   // CHECK: ret i32 -1
91   res = a + b + c;
92   return __FLT_EVAL_METHOD__;
93 }
94 #pragma float_control(pop)
95 
getFPEvalMethod()96 int getFPEvalMethod() {
97   // CHECK: ret i32 0
98   return __FLT_EVAL_METHOD__;
99 }
100 
101 float res1;
whatever(float a,float b,float c)102 int whatever(float a, float b, float c) {
103 #pragma float_control(precise, off)
104   // CHECK: load float, float*
105   // CHECK: fadd fast float
106   // CHECK: store float {{.*}}, float*
107   // CHECK: store i32 -1
108   // CHECK: store i32 0
109   // CHECK: ret i32 -1
110   res1 = a + b + c;
111   int val1 = __FLT_EVAL_METHOD__;
112   {
113 #pragma float_control(precise, on)
114     int val2 = __FLT_EVAL_METHOD__;
115   }
116   return __FLT_EVAL_METHOD__;
117 }
118