[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / fp-reciprocal-pragma.cpp
blob8398e48410e333ffd55452b31d89c70658f7cfb9
1 // RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,DEFAULT %s
2 // RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -freciprocal-math -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,FLAG %s
4 float base(float a, float b, float c) {
5 // CHECK-LABEL: _Z4basefff
6 // FLAG: %[[A:.+]] = fdiv arcp float %b, %c
7 // FLAG: %[[M:.+]] = fdiv arcp float %[[A]], %b
8 // FLAG-NEXT: fadd arcp float %c, %[[M]]
10 // DEFAULT: %[[A:.+]] = fdiv float %b, %c
11 // DEFAULT: %[[M:.+]] = fdiv float %[[A]], %b
12 // DEFAULT-NEXT: fadd float %c, %[[M]]
13 a = b / c;
14 return a / b + c;
17 // Simple case
18 float fp_recip_simple(float a, float b, float c) {
19 // CHECK-LABEL: _Z15fp_recip_simplefff
20 // CHECK: %[[A:.+]] = fdiv arcp float %b, %c
21 // CHECK: %[[M:.+]] = fdiv arcp float %[[A]], %b
22 // CHECK-NEXT: fadd arcp float %c, %[[M]]
23 #pragma clang fp reciprocal(on)
24 a = b / c;
25 return a / b + c;
28 // Test interaction with -freciprocal-math
29 float fp_recip_disable(float a, float b, float c) {
30 // CHECK-LABEL: _Z16fp_recip_disablefff
31 // CHECK: %[[A:.+]] = fdiv float %b, %c
32 // CHECK: %[[M:.+]] = fdiv float %[[A]], %b
33 // CHECK-NEXT: fadd float %c, %[[M]]
34 #pragma clang fp reciprocal(off)
35 a = b / c;
36 return a / b + c;
39 float fp_recip_with_reassoc_simple(float a, float b, float c) {
40 // CHECK-LABEL: _Z28fp_recip_with_reassoc_simplefff
41 // CHECK: %[[A:.+]] = fmul reassoc arcp float %b, %c
42 // CHECK: %[[M:.+]] = fdiv reassoc arcp float %b, %[[A]]
43 // CHECK-NEXT: fadd reassoc arcp float %c, %[[M]]
44 #pragma clang fp reciprocal(on) reassociate(on)
45 a = b / c;
46 return a / b + c;
49 // arcp pragma should only apply to its scope
50 float fp_recip_scoped(float a, float b, float c) {
51 // CHECK-LABEL: _Z15fp_recip_scopedfff
52 // DEFAULT: %[[M:.+]] = fdiv float %a, %b
53 // DEFAULT-NEXT: fadd float %[[M]], %c
54 // FLAG: %[[M:.+]] = fdiv arcp float %a, %b
55 // FLAG-NEXT: fadd arcp float %[[M]], %c
57 #pragma clang fp reciprocal(on)
59 return a / b + c;
62 // arcp pragma should apply to templates as well
63 class Foo {};
64 Foo operator+(Foo, Foo);
65 template <typename T>
66 T template_recip(T a, T b, T c) {
67 #pragma clang fp reciprocal(on)
68 return ((a / b) - c) + c;
71 float fp_recip_template(float a, float b, float c) {
72 // CHECK-LABEL: _Z17fp_recip_templatefff
73 // CHECK: %[[A1:.+]] = fdiv arcp float %a, %b
74 // CHECK-NEXT: %[[A2:.+]] = fsub arcp float %[[A1]], %c
75 // CHECK-NEXT: fadd arcp float %c, %[[A2]]
76 return template_recip<float>(a, b, c);
79 // File Scoping should work across functions
80 #pragma clang fp reciprocal(on)
81 float fp_file_scope_on(float a, float b, float c) {
82 // CHECK-LABEL: _Z16fp_file_scope_onfff
83 // CHECK: %[[M1:.+]] = fdiv arcp float %a, %c
84 // CHECK-NEXT: %[[M2:.+]] = fdiv arcp float %b, %c
85 // CHECK-NEXT: fadd arcp float %[[M1]], %[[M2]]
86 return (a / c) + (b / c);
89 // Inner pragma has precedence
90 float fp_file_scope_stop(float a, float b, float c) {
91 // CHECK-LABEL: _Z18fp_file_scope_stopfff
92 // CHECK: %[[A:.+]] = fdiv arcp float %a, %a
93 // CHECK: %[[M1:.+]] = fdiv float %[[A]], %c
94 // CHECK-NEXT: %[[M2:.+]] = fdiv float %b, %c
95 // CHECK-NEXT: fsub float %[[M1]], %[[M2]]
96 a = a / a;
98 #pragma clang fp reciprocal(off)
99 return (a / c) - (b / c);
103 #pragma clang fp reciprocal(off)
104 float fp_recip_off(float a, float b, float c) {
105 // CHECK-LABEL: _Z12fp_recip_offfff
106 // CHECK: %[[D1:.+]] = fdiv float %a, %c
107 // CHECK-NEXT: %[[D2:.+]] = fdiv float %b, %c
108 // CHECK-NEXT: fadd float %[[D1]], %[[D2]]
109 return (a / c) + (b / c);
112 // Takes latest flag
113 float fp_recip_many(float a, float b, float c) {
114 // CHECK-LABEL: _Z13fp_recip_manyfff
115 // CHECK: %[[D1:.+]] = fdiv arcp float %a, %c
116 // CHECK-NEXT: %[[D2:.+]] = fdiv arcp float %b, %c
117 // CHECK-NEXT: fadd arcp float %[[D1]], %[[D2]]
118 #pragma clang fp reciprocal(off) reciprocal(on)
119 return (a / c) + (b / c);
122 // Pragma does not propagate through called functions
123 float helper_func(float a, float b, float c) { return a + b + c; }
124 float fp_recip_call_helper(float a, float b, float c) {
125 // CHECK-LABEL: _Z20fp_recip_call_helperfff
126 // CHECK: %[[S1:.+]] = fadd float %a, %b
127 // CHECK-NEXT: fadd float %[[S1]], %c
128 #pragma clang fp reciprocal(on)
129 return helper_func(a, b, c);