1; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s
2
3declare float @llvm.sqrt.f32(float)
4declare double @llvm.sqrt.f64(double)
5
6; CHECK-LABEL: sqrt_div(
7; CHECK: sqrt.rn.f32
8; CHECK: div.rn.f32
9define float @sqrt_div(float %a, float %b) {
10  %t1 = tail call float @llvm.sqrt.f32(float %a)
11  %t2 = fdiv float %t1, %b
12  ret float %t2
13}
14
15; CHECK-LABEL: sqrt_div_fast(
16; CHECK: sqrt.rn.f32
17; CHECK: div.approx.f32
18define float @sqrt_div_fast(float %a, float %b) #0 {
19  %t1 = tail call float @llvm.sqrt.f32(float %a)
20  %t2 = fdiv float %t1, %b
21  ret float %t2
22}
23
24; CHECK-LABEL: sqrt_div_fast_ninf(
25; CHECK: sqrt.approx.f32
26; CHECK: div.approx.f32
27define float @sqrt_div_fast_ninf(float %a, float %b) #0 {
28  %t1 = tail call ninf float @llvm.sqrt.f32(float %a)
29  %t2 = fdiv float %t1, %b
30  ret float %t2
31}
32
33; CHECK-LABEL: sqrt_div_ftz(
34; CHECK: sqrt.rn.ftz.f32
35; CHECK: div.rn.ftz.f32
36define float @sqrt_div_ftz(float %a, float %b) #1 {
37  %t1 = tail call float @llvm.sqrt.f32(float %a)
38  %t2 = fdiv float %t1, %b
39  ret float %t2
40}
41
42; CHECK-LABEL: sqrt_div_fast_ftz(
43; CHECK: sqrt.rn.ftz.f32
44; CHECK: div.approx.ftz.f32
45define float @sqrt_div_fast_ftz(float %a, float %b) #0 #1 {
46  %t1 = tail call float @llvm.sqrt.f32(float %a)
47  %t2 = fdiv float %t1, %b
48  ret float %t2
49}
50
51; CHECK-LABEL: sqrt_div_fast_ftz_ninf(
52; CHECK: sqrt.approx.ftz.f32
53; CHECK: div.approx.ftz.f32
54define float @sqrt_div_fast_ftz_ninf(float %a, float %b) #0 #1 {
55  %t1 = tail call ninf float @llvm.sqrt.f32(float %a)
56  %t2 = fdiv float %t1, %b
57  ret float %t2
58}
59
60; There are no fast-math or ftz versions of sqrt and div for f64.  We use
61; reciprocal(rsqrt(x)) for sqrt(x), and emit a vanilla divide.
62
63; CHECK-LABEL: sqrt_div_fast_ftz_f64(
64; CHECK: sqrt.rn.f64
65; CHECK: div.rn.f64
66define double @sqrt_div_fast_ftz_f64(double %a, double %b) #0 #1 {
67  %t1 = tail call double @llvm.sqrt.f64(double %a)
68  %t2 = fdiv double %t1, %b
69  ret double %t2
70}
71
72; CHECK-LABEL: sqrt_div_fast_ftz_f64_ninf(
73; CHECK: rsqrt.approx.f64
74; CHECK: rcp.approx.ftz.f64
75; CHECK: div.rn.f64
76define double @sqrt_div_fast_ftz_f64_ninf(double %a, double %b) #0 #1 {
77  %t1 = tail call ninf double @llvm.sqrt.f64(double %a)
78  %t2 = fdiv double %t1, %b
79  ret double %t2
80}
81
82; CHECK-LABEL: rsqrt(
83; CHECK-NOT: rsqrt.approx
84; CHECK: sqrt.rn.f32
85; CHECK-NOT: rsqrt.approx
86define float @rsqrt(float %a) {
87  %b = tail call float @llvm.sqrt.f32(float %a)
88  %ret = fdiv float 1.0, %b
89  ret float %ret
90}
91
92; CHECK-LABEL: rsqrt_fast(
93; CHECK-NOT: div.
94; CHECK-NOT: sqrt.
95; CHECK: rsqrt.approx.f32
96; CHECK-NOT: div.
97; CHECK-NOT: sqrt.
98define float @rsqrt_fast(float %a) #0 {
99  %b = tail call float @llvm.sqrt.f32(float %a)
100  %ret = fdiv float 1.0, %b
101  ret float %ret
102}
103
104; CHECK-LABEL: rsqrt_fast_ftz(
105; CHECK-NOT: div.
106; CHECK-NOT: sqrt.
107; CHECK: rsqrt.approx.ftz.f32
108; CHECK-NOT: div.
109; CHECK-NOT: sqrt.
110define float @rsqrt_fast_ftz(float %a) #0 #1 {
111  %b = tail call float @llvm.sqrt.f32(float %a)
112  %ret = fdiv float 1.0, %b
113  ret float %ret
114}
115
116; CHECK-LABEL: fadd
117; CHECK: add.rn.f32
118define float @fadd(float %a, float %b) {
119  %t1 = fadd float %a, %b
120  ret float %t1
121}
122
123; CHECK-LABEL: fadd_ftz
124; CHECK: add.rn.ftz.f32
125define float @fadd_ftz(float %a, float %b) #1 {
126  %t1 = fadd float %a, %b
127  ret float %t1
128}
129
130declare float @llvm.sin.f32(float)
131declare float @llvm.cos.f32(float)
132
133; CHECK-LABEL: fsin_approx
134; CHECK:       sin.approx.f32
135define float @fsin_approx(float %a) #0 {
136  %r = tail call float @llvm.sin.f32(float %a)
137  ret float %r
138}
139
140; CHECK-LABEL: fcos_approx
141; CHECK:       cos.approx.f32
142define float @fcos_approx(float %a) #0 {
143  %r = tail call float @llvm.cos.f32(float %a)
144  ret float %r
145}
146
147; CHECK-LABEL: repeated_div_recip_allowed
148define float @repeated_div_recip_allowed(i1 %pred, float %a, float %b, float %divisor) {
149; CHECK: rcp.rn.f32
150; CHECK: mul.rn.f32
151; CHECK: mul.rn.f32
152  %x = fdiv arcp float %a, %divisor
153  %y = fdiv arcp float %b, %divisor
154  %z = select i1 %pred, float %x, float %y
155  ret float %z
156}
157
158; CHECK-LABEL: repeated_div_recip_allowed_ftz
159define float @repeated_div_recip_allowed_ftz(i1 %pred, float %a, float %b, float %divisor) #1 {
160; CHECK: rcp.rn.ftz.f32
161; CHECK: mul.rn.ftz.f32
162; CHECK: mul.rn.ftz.f32
163  %x = fdiv arcp float %a, %divisor
164  %y = fdiv arcp float %b, %divisor
165  %z = select i1 %pred, float %x, float %y
166  ret float %z
167}
168
169; CHECK-LABEL: repeated_div_fast
170define float @repeated_div_fast(i1 %pred, float %a, float %b, float %divisor) #0 {
171; CHECK: rcp.approx.f32
172; CHECK: mul.f32
173; CHECK: mul.f32
174  %x = fdiv float %a, %divisor
175  %y = fdiv float %b, %divisor
176  %z = select i1 %pred, float %x, float %y
177  ret float %z
178}
179
180; CHECK-LABEL: repeated_div_fast_ftz
181define float @repeated_div_fast_ftz(i1 %pred, float %a, float %b, float %divisor) #0 #1 {
182; CHECK: rcp.approx.ftz.f32
183; CHECK: mul.ftz.f32
184; CHECK: mul.ftz.f32
185  %x = fdiv float %a, %divisor
186  %y = fdiv float %b, %divisor
187  %z = select i1 %pred, float %x, float %y
188  ret float %z
189}
190
191attributes #0 = { "unsafe-fp-math" = "true" }
192attributes #1 = { "denormal-fp-math-f32" = "preserve-sign" }
193