1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
2; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
3
4declare float @llvm.fabs.f32(float) #1
5declare double @llvm.fabs.f64(double) #1
6
7; SI-LABEL: {{^}}test_isinf_pattern:
8; SI: v_mov_b32_e32 [[MASK:v[0-9]+]], 0x204{{$}}
9; SI: v_cmp_class_f32_e32 vcc, s{{[0-9]+}}, [[MASK]]
10; SI-NOT: v_cmp
11; SI: s_endpgm
12define amdgpu_kernel void @test_isinf_pattern(i32 addrspace(1)* nocapture %out, float %x) #0 {
13  %fabs = tail call float @llvm.fabs.f32(float %x) #1
14  %cmp = fcmp oeq float %fabs, 0x7FF0000000000000
15  %ext = zext i1 %cmp to i32
16  store i32 %ext, i32 addrspace(1)* %out, align 4
17  ret void
18}
19
20; SI-LABEL: {{^}}test_not_isinf_pattern_0:
21; SI-NOT: v_cmp_class
22; SI: s_endpgm
23define amdgpu_kernel void @test_not_isinf_pattern_0(i32 addrspace(1)* nocapture %out, float %x) #0 {
24  %fabs = tail call float @llvm.fabs.f32(float %x) #1
25  %cmp = fcmp ueq float %fabs, 0x7FF0000000000000
26  %ext = zext i1 %cmp to i32
27  store i32 %ext, i32 addrspace(1)* %out, align 4
28  ret void
29}
30
31; SI-LABEL: {{^}}test_not_isinf_pattern_1:
32; SI-NOT: v_cmp_class
33; SI: s_endpgm
34define amdgpu_kernel void @test_not_isinf_pattern_1(i32 addrspace(1)* nocapture %out, float %x) #0 {
35  %fabs = tail call float @llvm.fabs.f32(float %x) #1
36  %cmp = fcmp oeq float %fabs, 0xFFF0000000000000
37  %ext = zext i1 %cmp to i32
38  store i32 %ext, i32 addrspace(1)* %out, align 4
39  ret void
40}
41
42; SI-LABEL: {{^}}test_isfinite_pattern_0:
43; SI-NOT: v_cmp
44; SI: v_mov_b32_e32 [[MASK:v[0-9]+]], 0x1f8{{$}}
45; SI: v_cmp_class_f32_e32 vcc, s{{[0-9]+}}, [[MASK]]
46; SI-NOT: v_cmp
47; SI: s_endpgm
48define amdgpu_kernel void @test_isfinite_pattern_0(i32 addrspace(1)* nocapture %out, float %x) #0 {
49  %ord = fcmp ord float %x, 0.000000e+00
50  %x.fabs = tail call float @llvm.fabs.f32(float %x) #1
51  %ninf = fcmp une float %x.fabs, 0x7FF0000000000000
52  %and = and i1 %ord, %ninf
53  %ext = zext i1 %and to i32
54  store i32 %ext, i32 addrspace(1)* %out, align 4
55  ret void
56}
57
58; Use negative infinity
59; SI-LABEL: {{^}}test_isfinite_not_pattern_0:
60; SI-NOT: v_cmp_class_f32
61; SI: s_endpgm
62define amdgpu_kernel void @test_isfinite_not_pattern_0(i32 addrspace(1)* nocapture %out, float %x) #0 {
63  %ord = fcmp ord float %x, 0.000000e+00
64  %x.fabs = tail call float @llvm.fabs.f32(float %x) #1
65  %ninf = fcmp une float %x.fabs, 0xFFF0000000000000
66  %and = and i1 %ord, %ninf
67  %ext = zext i1 %and to i32
68  store i32 %ext, i32 addrspace(1)* %out, align 4
69  ret void
70}
71
72; No fabs
73; SI-LABEL: {{^}}test_isfinite_not_pattern_1:
74; SI-NOT: v_cmp_class_f32
75; SI: s_endpgm
76define amdgpu_kernel void @test_isfinite_not_pattern_1(i32 addrspace(1)* nocapture %out, float %x) #0 {
77  %ord = fcmp ord float %x, 0.000000e+00
78  %ninf = fcmp une float %x, 0x7FF0000000000000
79  %and = and i1 %ord, %ninf
80  %ext = zext i1 %and to i32
81  store i32 %ext, i32 addrspace(1)* %out, align 4
82  ret void
83}
84
85; fabs of different value
86; SI-LABEL: {{^}}test_isfinite_not_pattern_2:
87; SI-NOT: v_cmp_class_f32
88; SI: s_endpgm
89define amdgpu_kernel void @test_isfinite_not_pattern_2(i32 addrspace(1)* nocapture %out, float %x, float %y) #0 {
90  %ord = fcmp ord float %x, 0.000000e+00
91  %x.fabs = tail call float @llvm.fabs.f32(float %y) #1
92  %ninf = fcmp une float %x.fabs, 0x7FF0000000000000
93  %and = and i1 %ord, %ninf
94  %ext = zext i1 %and to i32
95  store i32 %ext, i32 addrspace(1)* %out, align 4
96  ret void
97}
98
99; Wrong ordered compare type
100; SI-LABEL: {{^}}test_isfinite_not_pattern_3:
101; SI-NOT: v_cmp_class_f32
102; SI: s_endpgm
103define amdgpu_kernel void @test_isfinite_not_pattern_3(i32 addrspace(1)* nocapture %out, float %x) #0 {
104  %ord = fcmp uno float %x, 0.000000e+00
105  %x.fabs = tail call float @llvm.fabs.f32(float %x) #1
106  %ninf = fcmp une float %x.fabs, 0x7FF0000000000000
107  %and = and i1 %ord, %ninf
108  %ext = zext i1 %and to i32
109  store i32 %ext, i32 addrspace(1)* %out, align 4
110  ret void
111}
112
113; Wrong unordered compare
114; SI-LABEL: {{^}}test_isfinite_not_pattern_4:
115; SI-NOT: v_cmp_class_f32
116; SI: s_endpgm
117define amdgpu_kernel void @test_isfinite_not_pattern_4(i32 addrspace(1)* nocapture %out, float %x) #0 {
118  %ord = fcmp ord float %x, 0.000000e+00
119  %x.fabs = tail call float @llvm.fabs.f32(float %x) #1
120  %ninf = fcmp one float %x.fabs, 0x7FF0000000000000
121  %and = and i1 %ord, %ninf
122  %ext = zext i1 %and to i32
123  store i32 %ext, i32 addrspace(1)* %out, align 4
124  ret void
125}
126
127attributes #0 = { nounwind }
128attributes #1 = { nounwind readnone }
129