blob: 868916ae993d5eb84fdf5939ec38c2a569f1a236 [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
Tom Stellard115a6152016-11-10 16:02:37 +0000119; For GFX8: since i16 is legal type, we cannot sink lshr into BBs.
Matt Arsenault59b8b772016-03-01 04:58:17 +0000120
121; GCN-LABEL: {{^}}sink_ubfe_i16:
122; GCN-NOT: lshr
Tom Stellard115a6152016-11-10 16:02:37 +0000123; VI: s_bfe_u32 s0, s0, 0xc0004
Matt Arsenault59b8b772016-03-01 04:58:17 +0000124; GCN: s_cbranch_vccnz
125
Tom Stellard115a6152016-11-10 16:02:37 +0000126; SI: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80004
127; VI: s_and_b32 s0, s0, 0xff
128
Matt Arsenault59b8b772016-03-01 04:58:17 +0000129; GCN: BB2_2:
Tom Stellard115a6152016-11-10 16:02:37 +0000130; SI: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70004
131; VI: s_and_b32 s0, s0, 0x7f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000132
133; GCN: BB2_3:
134; GCN: buffer_store_short
135; GCN: s_endpgm
136define void @sink_ubfe_i16(i16 addrspace(1)* %out, i16 %arg1) #0 {
137entry:
138 %shr = lshr i16 %arg1, 4
139 br i1 undef, label %bb0, label %bb1
140
141bb0:
142 %val0 = and i16 %shr, 255
143 store volatile i16 0, i16 addrspace(1)* undef
144 br label %ret
145
146bb1:
147 %val1 = and i16 %shr, 127
148 store volatile i16 0, i16 addrspace(1)* undef
149 br label %ret
150
151ret:
152 %phi = phi i16 [ %val0, %bb0 ], [ %val1, %bb1 ]
153 store i16 %phi, i16 addrspace(1)* %out
154 ret void
155}
156
157; We don't really want to sink this one since it isn't reducible to a
158; 32-bit BFE on one half of the integer.
159
160; OPT-LABEL: @sink_ubfe_i64_span_midpoint(
161; OPT: entry:
162; OPT-NOT: lshr
163; OPT: br i1
164
165; OPT: bb0:
166; OPT: %0 = lshr i64 %arg1, 30
167; OPT-NEXT: %val0 = and i64 %0, 255
168
169; OPT: bb1:
170; OPT: %1 = lshr i64 %arg1, 30
171; OPT-NEXT: %val1 = and i64 %1, 127
172
173; OPT: ret:
174; OPT: store
175; OPT: ret
176
177; GCN-LABEL: {{^}}sink_ubfe_i64_span_midpoint:
Matt Arsenaultf530e8b2016-11-07 19:09:33 +0000178; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
Matt Arsenault59b8b772016-03-01 04:58:17 +0000179; GCN: s_cbranch_vccnz BB3_2
180
Matt Arsenault59b8b772016-03-01 04:58:17 +0000181; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0xff
182
183; GCN: BB3_2:
Matt Arsenault59b8b772016-03-01 04:58:17 +0000184; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0x7f
185
186; GCN: BB3_3:
187; GCN: buffer_store_dwordx2
188define void @sink_ubfe_i64_span_midpoint(i64 addrspace(1)* %out, i64 %arg1) #0 {
189entry:
190 %shr = lshr i64 %arg1, 30
191 br i1 undef, label %bb0, label %bb1
192
193bb0:
194 %val0 = and i64 %shr, 255
195 store volatile i32 0, i32 addrspace(1)* undef
196 br label %ret
197
198bb1:
199 %val1 = and i64 %shr, 127
200 store volatile i32 0, i32 addrspace(1)* undef
201 br label %ret
202
203ret:
204 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
205 store i64 %phi, i64 addrspace(1)* %out
206 ret void
207}
208
209; OPT-LABEL: @sink_ubfe_i64_low32(
210; OPT: entry:
211; OPT-NOT: lshr
212; OPT: br i1
213
214; OPT: bb0:
215; OPT: %0 = lshr i64 %arg1, 15
216; OPT-NEXT: %val0 = and i64 %0, 255
217
218; OPT: bb1:
219; OPT: %1 = lshr i64 %arg1, 15
220; OPT-NEXT: %val1 = and i64 %1, 127
221
222; OPT: ret:
223; OPT: store
224; OPT: ret
225
226; GCN-LABEL: {{^}}sink_ubfe_i64_low32:
227
228; GCN: s_cbranch_vccnz BB4_2
229
Matt Arsenault8d1052f2016-04-21 18:03:06 +0000230; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x8000f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000231
232; GCN: BB4_2:
Matt Arsenault8d1052f2016-04-21 18:03:06 +0000233; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x7000f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000234
235; GCN: BB4_3:
236; GCN: buffer_store_dwordx2
237define void @sink_ubfe_i64_low32(i64 addrspace(1)* %out, i64 %arg1) #0 {
238entry:
239 %shr = lshr i64 %arg1, 15
240 br i1 undef, label %bb0, label %bb1
241
242bb0:
243 %val0 = and i64 %shr, 255
244 store volatile i32 0, i32 addrspace(1)* undef
245 br label %ret
246
247bb1:
248 %val1 = and i64 %shr, 127
249 store volatile i32 0, i32 addrspace(1)* undef
250 br label %ret
251
252ret:
253 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
254 store i64 %phi, i64 addrspace(1)* %out
255 ret void
256}
257
258; OPT-LABEL: @sink_ubfe_i64_high32(
259; OPT: entry:
260; OPT-NOT: lshr
261; OPT: br i1
262
263; OPT: bb0:
264; OPT: %0 = lshr i64 %arg1, 35
265; OPT-NEXT: %val0 = and i64 %0, 255
266
267; OPT: bb1:
268; OPT: %1 = lshr i64 %arg1, 35
269; OPT-NEXT: %val1 = and i64 %1, 127
270
271; OPT: ret:
272; OPT: store
273; OPT: ret
274
275; GCN-LABEL: {{^}}sink_ubfe_i64_high32:
276; GCN: s_cbranch_vccnz BB5_2
277; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80003
278
279; GCN: BB5_2:
280; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70003
281
282; GCN: BB5_3:
283; GCN: buffer_store_dwordx2
284define void @sink_ubfe_i64_high32(i64 addrspace(1)* %out, i64 %arg1) #0 {
285entry:
286 %shr = lshr i64 %arg1, 35
287 br i1 undef, label %bb0, label %bb1
288
289bb0:
290 %val0 = and i64 %shr, 255
291 store volatile i32 0, i32 addrspace(1)* undef
292 br label %ret
293
294bb1:
295 %val1 = and i64 %shr, 127
296 store volatile i32 0, i32 addrspace(1)* undef
297 br label %ret
298
299ret:
300 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
301 store i64 %phi, i64 addrspace(1)* %out
302 ret void
303}
304
305attributes #0 = { nounwind }