blob: 33daf0292ae1ad5378b4da917f83070210b3c6be [file] [log] [blame]
Matt Arsenault59b8b772016-03-01 04:58:17 +00001; RUN: opt -S -mtriple=amdgcn-- -codegenprepare < %s | FileCheck -check-prefix=OPT %s
2; RUN: opt -S -mtriple=amdgcn-- -mcpu=tonga -codegenprepare < %s | FileCheck -check-prefix=OPT %s
3; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s
4; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
5
6; This particular case will actually be worse in terms of code size
7; from sinking into both.
8
9; OPT-LABEL: @sink_ubfe_i32(
10; OPT: entry:
11; OPT-NEXT: br i1
12
13; OPT: bb0:
14; OPT: %0 = lshr i32 %arg1, 8
15; OPT-NEXT: %val0 = and i32 %0, 255
16; OPT: br label
17
18; OPT: bb1:
19; OPT: %1 = lshr i32 %arg1, 8
20; OPT-NEXT: %val1 = and i32 %1, 127
21; OPT: br label
22
23; OPT: ret:
24; OPT: store
25; OPT: ret
26
27
28; GCN-LABEL: {{^}}sink_ubfe_i32:
29; GCN-NOT: lshr
30; GCN: s_cbranch_vccnz
31
32; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80008
33; GCN: BB0_2:
34; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70008
35
36; GCN: BB0_3:
37; GCN: buffer_store_dword
38; GCN: s_endpgm
39define void @sink_ubfe_i32(i32 addrspace(1)* %out, i32 %arg1) #0 {
40entry:
41 %shr = lshr i32 %arg1, 8
42 br i1 undef, label %bb0, label %bb1
43
44bb0:
45 %val0 = and i32 %shr, 255
46 store volatile i32 0, i32 addrspace(1)* undef
47 br label %ret
48
49bb1:
50 %val1 = and i32 %shr, 127
51 store volatile i32 0, i32 addrspace(1)* undef
52 br label %ret
53
54ret:
55 %phi = phi i32 [ %val0, %bb0 ], [ %val1, %bb1 ]
56 store i32 %phi, i32 addrspace(1)* %out
57 ret void
58}
59
60; OPT-LABEL: @sink_sbfe_i32(
61; OPT: entry:
62; OPT-NEXT: br i1
63
64; OPT: bb0:
65; OPT: %0 = ashr i32 %arg1, 8
66; OPT-NEXT: %val0 = and i32 %0, 255
67; OPT: br label
68
69; OPT: bb1:
70; OPT: %1 = ashr i32 %arg1, 8
71; OPT-NEXT: %val1 = and i32 %1, 127
72; OPT: br label
73
74; OPT: ret:
75; OPT: store
76; OPT: ret
77
78; GCN-LABEL: {{^}}sink_sbfe_i32:
79define void @sink_sbfe_i32(i32 addrspace(1)* %out, i32 %arg1) #0 {
80entry:
81 %shr = ashr i32 %arg1, 8
82 br i1 undef, label %bb0, label %bb1
83
84bb0:
85 %val0 = and i32 %shr, 255
86 store volatile i32 0, i32 addrspace(1)* undef
87 br label %ret
88
89bb1:
90 %val1 = and i32 %shr, 127
91 store volatile i32 0, i32 addrspace(1)* undef
92 br label %ret
93
94ret:
95 %phi = phi i32 [ %val0, %bb0 ], [ %val1, %bb1 ]
96 store i32 %phi, i32 addrspace(1)* %out
97 ret void
98}
99
100
101; OPT-LABEL: @sink_ubfe_i16(
102; OPT: entry:
103; OPT-NEXT: br i1
104
105; OPT: bb0:
106; OPT: %0 = lshr i16 %arg1, 4
107; OPT-NEXT: %val0 = and i16 %0, 255
108; OPT: br label
109
110; OPT: bb1:
111; OPT: %1 = lshr i16 %arg1, 4
112; OPT-NEXT: %val1 = and i16 %1, 127
113; OPT: br label
114
115; OPT: ret:
116; OPT: store
117; OPT: ret
118
119
120; GCN-LABEL: {{^}}sink_ubfe_i16:
121; GCN-NOT: lshr
122; GCN: s_cbranch_vccnz
123
124; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80004
125; GCN: BB2_2:
126; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70004
127
128; GCN: BB2_3:
129; GCN: buffer_store_short
130; GCN: s_endpgm
131define void @sink_ubfe_i16(i16 addrspace(1)* %out, i16 %arg1) #0 {
132entry:
133 %shr = lshr i16 %arg1, 4
134 br i1 undef, label %bb0, label %bb1
135
136bb0:
137 %val0 = and i16 %shr, 255
138 store volatile i16 0, i16 addrspace(1)* undef
139 br label %ret
140
141bb1:
142 %val1 = and i16 %shr, 127
143 store volatile i16 0, i16 addrspace(1)* undef
144 br label %ret
145
146ret:
147 %phi = phi i16 [ %val0, %bb0 ], [ %val1, %bb1 ]
148 store i16 %phi, i16 addrspace(1)* %out
149 ret void
150}
151
152; We don't really want to sink this one since it isn't reducible to a
153; 32-bit BFE on one half of the integer.
154
155; OPT-LABEL: @sink_ubfe_i64_span_midpoint(
156; OPT: entry:
157; OPT-NOT: lshr
158; OPT: br i1
159
160; OPT: bb0:
161; OPT: %0 = lshr i64 %arg1, 30
162; OPT-NEXT: %val0 = and i64 %0, 255
163
164; OPT: bb1:
165; OPT: %1 = lshr i64 %arg1, 30
166; OPT-NEXT: %val1 = and i64 %1, 127
167
168; OPT: ret:
169; OPT: store
170; OPT: ret
171
172; GCN-LABEL: {{^}}sink_ubfe_i64_span_midpoint:
173; GCN: s_cbranch_vccnz BB3_2
174
175; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
176; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0xff
177
178; GCN: BB3_2:
179; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
180; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0x7f
181
182; GCN: BB3_3:
183; GCN: buffer_store_dwordx2
184define void @sink_ubfe_i64_span_midpoint(i64 addrspace(1)* %out, i64 %arg1) #0 {
185entry:
186 %shr = lshr i64 %arg1, 30
187 br i1 undef, label %bb0, label %bb1
188
189bb0:
190 %val0 = and i64 %shr, 255
191 store volatile i32 0, i32 addrspace(1)* undef
192 br label %ret
193
194bb1:
195 %val1 = and i64 %shr, 127
196 store volatile i32 0, i32 addrspace(1)* undef
197 br label %ret
198
199ret:
200 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
201 store i64 %phi, i64 addrspace(1)* %out
202 ret void
203}
204
205; OPT-LABEL: @sink_ubfe_i64_low32(
206; OPT: entry:
207; OPT-NOT: lshr
208; OPT: br i1
209
210; OPT: bb0:
211; OPT: %0 = lshr i64 %arg1, 15
212; OPT-NEXT: %val0 = and i64 %0, 255
213
214; OPT: bb1:
215; OPT: %1 = lshr i64 %arg1, 15
216; OPT-NEXT: %val1 = and i64 %1, 127
217
218; OPT: ret:
219; OPT: store
220; OPT: ret
221
222; GCN-LABEL: {{^}}sink_ubfe_i64_low32:
223
224; GCN: s_cbranch_vccnz BB4_2
225
Matt Arsenault8d1052f2016-04-21 18:03:06 +0000226; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x8000f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000227
228; GCN: BB4_2:
Matt Arsenault8d1052f2016-04-21 18:03:06 +0000229; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x7000f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000230
231; GCN: BB4_3:
232; GCN: buffer_store_dwordx2
233define void @sink_ubfe_i64_low32(i64 addrspace(1)* %out, i64 %arg1) #0 {
234entry:
235 %shr = lshr i64 %arg1, 15
236 br i1 undef, label %bb0, label %bb1
237
238bb0:
239 %val0 = and i64 %shr, 255
240 store volatile i32 0, i32 addrspace(1)* undef
241 br label %ret
242
243bb1:
244 %val1 = and i64 %shr, 127
245 store volatile i32 0, i32 addrspace(1)* undef
246 br label %ret
247
248ret:
249 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
250 store i64 %phi, i64 addrspace(1)* %out
251 ret void
252}
253
254; OPT-LABEL: @sink_ubfe_i64_high32(
255; OPT: entry:
256; OPT-NOT: lshr
257; OPT: br i1
258
259; OPT: bb0:
260; OPT: %0 = lshr i64 %arg1, 35
261; OPT-NEXT: %val0 = and i64 %0, 255
262
263; OPT: bb1:
264; OPT: %1 = lshr i64 %arg1, 35
265; OPT-NEXT: %val1 = and i64 %1, 127
266
267; OPT: ret:
268; OPT: store
269; OPT: ret
270
271; GCN-LABEL: {{^}}sink_ubfe_i64_high32:
272; GCN: s_cbranch_vccnz BB5_2
273; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80003
274
275; GCN: BB5_2:
276; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70003
277
278; GCN: BB5_3:
279; GCN: buffer_store_dwordx2
280define void @sink_ubfe_i64_high32(i64 addrspace(1)* %out, i64 %arg1) #0 {
281entry:
282 %shr = lshr i64 %arg1, 35
283 br i1 undef, label %bb0, label %bb1
284
285bb0:
286 %val0 = and i64 %shr, 255
287 store volatile i32 0, i32 addrspace(1)* undef
288 br label %ret
289
290bb1:
291 %val1 = and i64 %shr, 127
292 store volatile i32 0, i32 addrspace(1)* undef
293 br label %ret
294
295ret:
296 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
297 store i64 %phi, i64 addrspace(1)* %out
298 ret void
299}
300
301attributes #0 = { nounwind }