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]]
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)
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)
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)
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)
62 // arcp pragma should apply to templates as well
64 Foo
operator+(Foo
, Foo
);
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]]
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
);
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
);