1; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
2; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
3
4; FUNC-LABEL: {{^}}sext_bool_icmp_eq_0:
5; SI-NOT: v_cmp
6; SI: v_cmp_ne_i32_e32 vcc,
7; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
8; SI-NEXT:buffer_store_byte [[RESULT]]
9; SI-NEXT: s_endpgm
10
11; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
12; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
13define void @sext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
14  %icmp0 = icmp eq i32 %a, %b
15  %ext = sext i1 %icmp0 to i32
16  %icmp1 = icmp eq i32 %ext, 0
17  store i1 %icmp1, i1 addrspace(1)* %out
18  ret void
19}
20
21; FUNC-LABEL: {{^}}sext_bool_icmp_ne_0:
22; SI-NOT: v_cmp
23; SI: v_cmp_ne_i32_e32 vcc,
24; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
25; SI-NEXT: buffer_store_byte [[RESULT]]
26; SI-NEXT: s_endpgm
27
28; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
29; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
30define void @sext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
31  %icmp0 = icmp ne i32 %a, %b
32  %ext = sext i1 %icmp0 to i32
33  %icmp1 = icmp ne i32 %ext, 0
34  store i1 %icmp1, i1 addrspace(1)* %out
35  ret void
36}
37
38; This really folds away to false
39; FUNC-LABEL: {{^}}sext_bool_icmp_eq_1:
40; SI: v_cmp_eq_i32_e32 vcc,
41; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
42; SI-NEXT: v_cmp_eq_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}}
43; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
44; SI-NEXT: buffer_store_byte [[TMP]]
45; SI-NEXT: s_endpgm
46define void @sext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
47  %icmp0 = icmp eq i32 %a, %b
48  %ext = sext i1 %icmp0 to i32
49  %icmp1 = icmp eq i32 %ext, 1
50  store i1 %icmp1, i1 addrspace(1)* %out
51  ret void
52}
53
54; This really folds away to true
55; FUNC-LABEL: {{^}}sext_bool_icmp_ne_1:
56; SI: v_cmp_ne_i32_e32 vcc,
57; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
58; SI-NEXT: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}}
59; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
60; SI-NEXT: buffer_store_byte [[TMP]]
61; SI-NEXT: s_endpgm
62define void @sext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
63  %icmp0 = icmp ne i32 %a, %b
64  %ext = sext i1 %icmp0 to i32
65  %icmp1 = icmp ne i32 %ext, 1
66  store i1 %icmp1, i1 addrspace(1)* %out
67  ret void
68}
69
70; FUNC-LABEL: {{^}}zext_bool_icmp_eq_0:
71; SI-NOT: v_cmp
72; SI: v_cmp_ne_i32_e32 vcc,
73; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
74; SI-NEXT: buffer_store_byte [[RESULT]]
75; SI-NEXT: s_endpgm
76define void @zext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
77  %icmp0 = icmp eq i32 %a, %b
78  %ext = zext i1 %icmp0 to i32
79  %icmp1 = icmp eq i32 %ext, 0
80  store i1 %icmp1, i1 addrspace(1)* %out
81  ret void
82}
83
84; FUNC-LABEL: {{^}}zext_bool_icmp_ne_0:
85; SI-NOT: v_cmp
86; SI: v_cmp_ne_i32_e32 vcc,
87; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
88; SI-NEXT: buffer_store_byte [[RESULT]]
89; SI-NEXT: s_endpgm
90define void @zext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
91  %icmp0 = icmp ne i32 %a, %b
92  %ext = zext i1 %icmp0 to i32
93  %icmp1 = icmp ne i32 %ext, 0
94  store i1 %icmp1, i1 addrspace(1)* %out
95  ret void
96}
97
98; FUNC-LABEL: {{^}}zext_bool_icmp_eq_1:
99; SI-NOT: v_cmp
100; SI: v_cmp_eq_i32_e32 vcc,
101; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
102; SI-NEXT: buffer_store_byte [[RESULT]]
103; SI-NEXT: s_endpgm
104define void @zext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
105  %icmp0 = icmp eq i32 %a, %b
106  %ext = zext i1 %icmp0 to i32
107  %icmp1 = icmp eq i32 %ext, 1
108  store i1 %icmp1, i1 addrspace(1)* %out
109  ret void
110}
111
112; FUNC-LABEL: {{^}}zext_bool_icmp_ne_1:
113; SI-NOT: v_cmp
114; SI: v_cmp_eq_i32_e32 vcc,
115; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
116; SI-NEXT: buffer_store_byte [[RESULT]]
117define void @zext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
118  %icmp0 = icmp ne i32 %a, %b
119  %ext = zext i1 %icmp0 to i32
120  %icmp1 = icmp ne i32 %ext, 1
121  store i1 %icmp1, i1 addrspace(1)* %out
122  ret void
123}
124
125; FUNC-LABEL: {{^}}sext_bool_icmp_ne_k:
126; SI-DAG: s_load_dword [[A:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
127; SI-DAG: s_load_dword [[B:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xc
128; SI: v_mov_b32_e32 [[VB:v[0-9]+]], [[B]]
129; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[VB]], 2{{$}}
130; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
131; SI: buffer_store_byte
132; SI: s_endpgm
133define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
134  %icmp0 = icmp ne i32 %a, %b
135  %ext = sext i1 %icmp0 to i32
136  %icmp1 = icmp ne i32 %ext, 2
137  store i1 %icmp1, i1 addrspace(1)* %out
138  ret void
139}
140
141; FUNC-LABEL: {{^}}cmp_zext_k_i8max:
142; SI: buffer_load_ubyte [[B:v[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:44
143; SI: v_mov_b32_e32 [[K255:v[0-9]+]], 0xff{{$}}
144; SI: v_cmp_ne_i32_e32 vcc, [[B]], [[K255]]
145; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
146; SI-NEXT: buffer_store_byte [[RESULT]]
147; SI: s_endpgm
148define void @cmp_zext_k_i8max(i1 addrspace(1)* %out, i8 %b) nounwind {
149  %b.ext = zext i8 %b to i32
150  %icmp0 = icmp ne i32 %b.ext, 255
151  store i1 %icmp0, i1 addrspace(1)* %out
152  ret void
153}
154
155; FUNC-LABEL: {{^}}cmp_sext_k_neg1:
156; SI: buffer_load_sbyte [[B:v[0-9]+]]
157; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}}
158; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
159; SI-NEXT: buffer_store_byte [[RESULT]]
160; SI: s_endpgm
161define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nounwind {
162  %b = load i8 addrspace(1)* %b.ptr
163  %b.ext = sext i8 %b to i32
164  %icmp0 = icmp ne i32 %b.ext, -1
165  store i1 %icmp0, i1 addrspace(1)* %out
166  ret void
167}
168
169; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_sext_arg:
170; SI: s_load_dword [[B:s[0-9]+]]
171; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}}
172; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
173; SI-NEXT: buffer_store_byte [[RESULT]]
174; SI: s_endpgm
175define void @cmp_sext_k_neg1_i8_sext_arg(i1 addrspace(1)* %out, i8 signext %b) nounwind {
176  %b.ext = sext i8 %b to i32
177  %icmp0 = icmp ne i32 %b.ext, -1
178  store i1 %icmp0, i1 addrspace(1)* %out
179  ret void
180}
181
182; FIXME: This ends up doing a buffer_load_ubyte, and and compare to
183; 255. Seems to be because of ordering problems when not allowing load widths to be reduced.
184; Should do a buffer_load_sbyte and compare with -1
185
186; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_arg:
187; SI-DAG: buffer_load_ubyte [[B:v[0-9]+]]
188; SI-DAG: v_mov_b32_e32 [[K:v[0-9]+]], 0xff{{$}}
189; SI: v_cmp_ne_i32_e32 vcc, [[B]], [[K]]{{$}}
190; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
191; SI-NEXT: buffer_store_byte [[RESULT]]
192; SI: s_endpgm
193define void @cmp_sext_k_neg1_i8_arg(i1 addrspace(1)* %out, i8 %b) nounwind {
194  %b.ext = sext i8 %b to i32
195  %icmp0 = icmp ne i32 %b.ext, -1
196  store i1 %icmp0, i1 addrspace(1)* %out
197  ret void
198}
199
200; FUNC-LABEL: {{^}}cmp_zext_k_neg1:
201; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
202; SI-NEXT: buffer_store_byte [[RESULT]]
203; SI: s_endpgm
204define void @cmp_zext_k_neg1(i1 addrspace(1)* %out, i8 %b) nounwind {
205  %b.ext = zext i8 %b to i32
206  %icmp0 = icmp ne i32 %b.ext, -1
207  store i1 %icmp0, i1 addrspace(1)* %out
208  ret void
209}
210
211; FUNC-LABEL: {{^}}zext_bool_icmp_ne_k:
212; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
213; SI-NEXT: buffer_store_byte [[RESULT]]
214; SI-NEXT: s_endpgm
215define void @zext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
216  %icmp0 = icmp ne i32 %a, %b
217  %ext = zext i1 %icmp0 to i32
218  %icmp1 = icmp ne i32 %ext, 2
219  store i1 %icmp1, i1 addrspace(1)* %out
220  ret void
221}
222
223; FUNC-LABEL: {{^}}zext_bool_icmp_eq_k:
224; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
225; SI-NEXT: buffer_store_byte [[RESULT]]
226; SI-NEXT: s_endpgm
227define void @zext_bool_icmp_eq_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
228  %icmp0 = icmp ne i32 %a, %b
229  %ext = zext i1 %icmp0 to i32
230  %icmp1 = icmp eq i32 %ext, 2
231  store i1 %icmp1, i1 addrspace(1)* %out
232  ret void
233}
234