1; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s
2; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s
3
4; CHECK-LABEL test_fabsf(
5define float @test_fabsf(float %f) {
6; CHECK: abs.f32
7  %x = call float @llvm.fabs.f32(float %f)
8  ret float %x
9}
10
11; CHECK-LABEL: test_fabs(
12define double @test_fabs(double %d) {
13; CHECK: abs.f64
14  %x = call double @llvm.fabs.f64(double %d)
15  ret double %x
16}
17
18; CHECK-LABEL: test_nvvm_sqrt(
19define float @test_nvvm_sqrt(float %a) {
20; CHECK: sqrt.rn.f32
21  %val = call float @llvm.nvvm.sqrt.f(float %a)
22  ret float %val
23}
24
25; CHECK-LABEL: test_llvm_sqrt(
26define float @test_llvm_sqrt(float %a) {
27; CHECK: sqrt.rn.f32
28  %val = call float @llvm.sqrt.f32(float %a)
29  ret float %val
30}
31
32; CHECK-LABEL: test_bitreverse32(
33define i32 @test_bitreverse32(i32 %a) {
34; CHECK: brev.b32
35  %val = call i32 @llvm.bitreverse.i32(i32 %a)
36  ret i32 %val
37}
38
39; CHECK-LABEL: test_bitreverse64(
40define i64 @test_bitreverse64(i64 %a) {
41; CHECK: brev.b64
42  %val = call i64 @llvm.bitreverse.i64(i64 %a)
43  ret i64 %val
44}
45
46; CHECK-LABEL: test_popc32(
47define i32 @test_popc32(i32 %a) {
48; CHECK: popc.b32
49  %val = call i32 @llvm.ctpop.i32(i32 %a)
50  ret i32 %val
51}
52
53; CHECK-LABEL: test_popc64
54define i64 @test_popc64(i64 %a) {
55; CHECK: popc.b64
56; CHECK: cvt.u64.u32
57  %val = call i64 @llvm.ctpop.i64(i64 %a)
58  ret i64 %val
59}
60
61; NVPTX popc.b64 returns an i32 even though @llvm.ctpop.i64 returns an i64, so
62; if this function returns an i32, there's no need to do any type conversions
63; in the ptx.
64; CHECK-LABEL: test_popc64_trunc
65define i32 @test_popc64_trunc(i64 %a) {
66; CHECK: popc.b64
67; CHECK-NOT: cvt.
68  %val = call i64 @llvm.ctpop.i64(i64 %a)
69  %trunc = trunc i64 %val to i32
70  ret i32 %trunc
71}
72
73; llvm.ctpop.i16 is implemenented by converting to i32, running popc.b32, and
74; then converting back to i16.
75; CHECK-LABEL: test_popc16
76define void @test_popc16(i16 %a, i16* %b) {
77; CHECK: cvt.u32.u16
78; CHECK: popc.b32
79; CHECK: cvt.u16.u32
80  %val = call i16 @llvm.ctpop.i16(i16 %a)
81  store i16 %val, i16* %b
82  ret void
83}
84
85; If we call llvm.ctpop.i16 and then zext the result to i32, we shouldn't need
86; to do any conversions after calling popc.b32, because that returns an i32.
87; CHECK-LABEL: test_popc16_to_32
88define i32 @test_popc16_to_32(i16 %a) {
89; CHECK: cvt.u32.u16
90; CHECK: popc.b32
91; CHECK-NOT: cvt.
92  %val = call i16 @llvm.ctpop.i16(i16 %a)
93  %zext = zext i16 %val to i32
94  ret i32 %zext
95}
96
97declare float @llvm.fabs.f32(float)
98declare double @llvm.fabs.f64(double)
99declare float @llvm.nvvm.sqrt.f(float)
100declare float @llvm.sqrt.f32(float)
101declare i32 @llvm.bitreverse.i32(i32)
102declare i64 @llvm.bitreverse.i64(i64)
103declare i16 @llvm.ctpop.i16(i16)
104declare i32 @llvm.ctpop.i32(i32)
105declare i64 @llvm.ctpop.i64(i64)
106