1 ; RUN: llc -march=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s
2 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s
3 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
5 ; FUNC-LABEL: {{^}}s_abs_i32:
10 define void @s_abs_i32(i32 addrspace(1)* %out, i32 %val) nounwind {
11 %neg = sub i32 0, %val
12 %cond = icmp sgt i32 %val, %neg
13 %res = select i1 %cond, i32 %val, i32 %neg
14 %res2 = add i32 %res, 2
15 store i32 %res2, i32 addrspace(1)* %out, align 4
19 ; FUNC-LABEL: {{^}}v_abs_i32:
20 ; GCN: v_sub_i32_e32 [[NEG:v[0-9]+]], vcc, 0, [[SRC:v[0-9]+]]
21 ; GCN: v_max_i32_e32 {{v[0-9]+}}, [[NEG]], [[SRC]]
25 define void @v_abs_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %src) nounwind {
26 %val = load i32, i32 addrspace(1)* %src, align 4
27 %neg = sub i32 0, %val
28 %cond = icmp sgt i32 %val, %neg
29 %res = select i1 %cond, i32 %val, i32 %neg
30 %res2 = add i32 %res, 2
31 store i32 %res2, i32 addrspace(1)* %out, align 4
35 ; FUNC-LABEL: {{^}}s_abs_v2i32:
43 define void @s_abs_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %val) nounwind {
44 %z0 = insertelement <2 x i32> undef, i32 0, i32 0
45 %z1 = insertelement <2 x i32> %z0, i32 0, i32 1
46 %t0 = insertelement <2 x i32> undef, i32 2, i32 0
47 %t1 = insertelement <2 x i32> %t0, i32 2, i32 1
48 %neg = sub <2 x i32> %z1, %val
49 %cond = icmp sgt <2 x i32> %val, %neg
50 %res = select <2 x i1> %cond, <2 x i32> %val, <2 x i32> %neg
51 %res2 = add <2 x i32> %res, %t1
52 store <2 x i32> %res2, <2 x i32> addrspace(1)* %out, align 4
56 ; FUNC-LABEL: {{^}}v_abs_v2i32:
57 ; GCN-DAG: v_sub_i32_e32 [[NEG0:v[0-9]+]], vcc, 0, [[SRC0:v[0-9]+]]
58 ; GCN-DAG: v_sub_i32_e32 [[NEG1:v[0-9]+]], vcc, 0, [[SRC1:v[0-9]+]]
60 ; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG0]], [[SRC0]]
61 ; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG1]], [[SRC1]]
68 define void @v_abs_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %src) nounwind {
69 %z0 = insertelement <2 x i32> undef, i32 0, i32 0
70 %z1 = insertelement <2 x i32> %z0, i32 0, i32 1
71 %t0 = insertelement <2 x i32> undef, i32 2, i32 0
72 %t1 = insertelement <2 x i32> %t0, i32 2, i32 1
73 %val = load <2 x i32>, <2 x i32> addrspace(1)* %src, align 4
74 %neg = sub <2 x i32> %z1, %val
75 %cond = icmp sgt <2 x i32> %val, %neg
76 %res = select <2 x i1> %cond, <2 x i32> %val, <2 x i32> %neg
77 %res2 = add <2 x i32> %res, %t1
78 store <2 x i32> %res2, <2 x i32> addrspace(1)* %out, align 4
82 ; FUNC-LABEL: {{^}}s_abs_v4i32:
83 ; TODO: this should use s_abs_i32
98 define void @s_abs_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %val) nounwind {
99 %z0 = insertelement <4 x i32> undef, i32 0, i32 0
100 %z1 = insertelement <4 x i32> %z0, i32 0, i32 1
101 %z2 = insertelement <4 x i32> %z1, i32 0, i32 2
102 %z3 = insertelement <4 x i32> %z2, i32 0, i32 3
103 %t0 = insertelement <4 x i32> undef, i32 2, i32 0
104 %t1 = insertelement <4 x i32> %t0, i32 2, i32 1
105 %t2 = insertelement <4 x i32> %t1, i32 2, i32 2
106 %t3 = insertelement <4 x i32> %t2, i32 2, i32 3
107 %neg = sub <4 x i32> %z3, %val
108 %cond = icmp sgt <4 x i32> %val, %neg
109 %res = select <4 x i1> %cond, <4 x i32> %val, <4 x i32> %neg
110 %res2 = add <4 x i32> %res, %t3
111 store <4 x i32> %res2, <4 x i32> addrspace(1)* %out, align 4
115 ; FUNC-LABEL: {{^}}v_abs_v4i32:
116 ; GCN-DAG: v_sub_i32_e32 [[NEG0:v[0-9]+]], vcc, 0, [[SRC0:v[0-9]+]]
117 ; GCN-DAG: v_sub_i32_e32 [[NEG1:v[0-9]+]], vcc, 0, [[SRC1:v[0-9]+]]
118 ; GCN-DAG: v_sub_i32_e32 [[NEG2:v[0-9]+]], vcc, 0, [[SRC2:v[0-9]+]]
119 ; GCN-DAG: v_sub_i32_e32 [[NEG3:v[0-9]+]], vcc, 0, [[SRC3:v[0-9]+]]
121 ; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG0]], [[SRC0]]
122 ; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG1]], [[SRC1]]
123 ; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG2]], [[SRC2]]
124 ; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG3]], [[SRC3]]
135 define void @v_abs_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %src) nounwind {
136 %z0 = insertelement <4 x i32> undef, i32 0, i32 0
137 %z1 = insertelement <4 x i32> %z0, i32 0, i32 1
138 %z2 = insertelement <4 x i32> %z1, i32 0, i32 2
139 %z3 = insertelement <4 x i32> %z2, i32 0, i32 3
140 %t0 = insertelement <4 x i32> undef, i32 2, i32 0
141 %t1 = insertelement <4 x i32> %t0, i32 2, i32 1
142 %t2 = insertelement <4 x i32> %t1, i32 2, i32 2
143 %t3 = insertelement <4 x i32> %t2, i32 2, i32 3
144 %val = load <4 x i32>, <4 x i32> addrspace(1)* %src, align 4
145 %neg = sub <4 x i32> %z3, %val
146 %cond = icmp sgt <4 x i32> %val, %neg
147 %res = select <4 x i1> %cond, <4 x i32> %val, <4 x i32> %neg
148 %res2 = add <4 x i32> %res, %t3
149 store <4 x i32> %res2, <4 x i32> addrspace(1)* %out, align 4
153 ; FUNC-LABEL: {{^}}s_min_max_i32:
154 ; GCN: s_load_dword [[VAL0:s[0-9]+]]
155 ; GCN: s_load_dword [[VAL1:s[0-9]+]]
157 ; GCN-DAG: s_min_i32 s{{[0-9]+}}, [[VAL0]], [[VAL1]]
158 ; GCN-DAG: s_max_i32 s{{[0-9]+}}, [[VAL0]], [[VAL1]]
159 define void @s_min_max_i32(i32 addrspace(1)* %out0, i32 addrspace(1)* %out1, i32 %val0, i32 %val1) nounwind {
160 %cond0 = icmp sgt i32 %val0, %val1
161 %sel0 = select i1 %cond0, i32 %val0, i32 %val1
162 %sel1 = select i1 %cond0, i32 %val1, i32 %val0
164 store volatile i32 %sel0, i32 addrspace(1)* %out0, align 4
165 store volatile i32 %sel1, i32 addrspace(1)* %out1, align 4
169 ; FUNC-LABEL: {{^}}v_min_max_i32:
170 ; GCN: buffer_load_dword [[VAL0:v[0-9]+]]
171 ; GCN: buffer_load_dword [[VAL1:v[0-9]+]]
173 ; GCN-DAG: v_min_i32_e32 v{{[0-9]+}}, [[VAL1]], [[VAL0]]
174 ; GCN-DAG: v_max_i32_e32 v{{[0-9]+}}, [[VAL1]], [[VAL0]]
175 define void @v_min_max_i32(i32 addrspace(1)* %out0, i32 addrspace(1)* %out1, i32 addrspace(1)* %ptr0, i32 addrspace(1)* %ptr1) nounwind {
176 %val0 = load volatile i32, i32 addrspace(1)* %ptr0
177 %val1 = load volatile i32, i32 addrspace(1)* %ptr1
179 %cond0 = icmp sgt i32 %val0, %val1
180 %sel0 = select i1 %cond0, i32 %val0, i32 %val1
181 %sel1 = select i1 %cond0, i32 %val1, i32 %val0
183 store volatile i32 %sel0, i32 addrspace(1)* %out0, align 4
184 store volatile i32 %sel1, i32 addrspace(1)* %out1, align 4
188 ; FUNC-LABEL: {{^}}s_min_max_v4i32:
197 define void @s_min_max_v4i32(<4 x i32> addrspace(1)* %out0, <4 x i32> addrspace(1)* %out1, <4 x i32> %val0, <4 x i32> %val1) nounwind {
198 %cond0 = icmp sgt <4 x i32> %val0, %val1
199 %sel0 = select <4 x i1> %cond0, <4 x i32> %val0, <4 x i32> %val1
200 %sel1 = select <4 x i1> %cond0, <4 x i32> %val1, <4 x i32> %val0
202 store volatile <4 x i32> %sel0, <4 x i32> addrspace(1)* %out0, align 4
203 store volatile <4 x i32> %sel1, <4 x i32> addrspace(1)* %out1, align 4
207 ; FUNC-LABEL: {{^}}v_min_max_i32_user:
208 ; GCN: v_cmp_gt_i32_e32
209 ; GCN-DAG: v_cndmask_b32_e32
210 ; GCN-DAG: v_cndmask_b32_e32
211 ; GCN-DAG: v_cndmask_b32_e64 v{{[0-9]+}}, 0, 1, vcc
212 define void @v_min_max_i32_user(i32 addrspace(1)* %out0, i32 addrspace(1)* %out1, i32 addrspace(1)* %ptr0, i32 addrspace(1)* %ptr1) nounwind {
213 %val0 = load volatile i32, i32 addrspace(1)* %ptr0
214 %val1 = load volatile i32, i32 addrspace(1)* %ptr1
216 %cond0 = icmp sgt i32 %val0, %val1
217 %sel0 = select i1 %cond0, i32 %val0, i32 %val1
218 %sel1 = select i1 %cond0, i32 %val1, i32 %val0
220 store volatile i32 %sel0, i32 addrspace(1)* %out0, align 4
221 store volatile i32 %sel1, i32 addrspace(1)* %out1, align 4
222 store volatile i1 %cond0, i1 addrspace(1)* undef