blob: 066ef951cc31bd42532a716fb63fe5f20a22cb74 [file] [log] [blame]
Matt Arsenault59b8b772016-03-01 04:58:17 +00001; RUN: opt -S -mtriple=amdgcn-- -codegenprepare < %s | FileCheck -check-prefix=OPT %s
Matt Arsenault7aad8fd2017-01-24 22:02:15 +00002; RUN: opt -S -mtriple=amdgcn-- -mcpu=tonga -mattr=-flat-for-global -codegenprepare < %s | FileCheck -check-prefix=OPT %s
Matt Arsenault59b8b772016-03-01 04:58:17 +00003; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s
Matt Arsenault7aad8fd2017-01-24 22:02:15 +00004; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
Matt Arsenault59b8b772016-03-01 04:58:17 +00005
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
Matt Arsenault327188a2016-12-15 21:57:11 +000030; GCN: s_cbranch_scc1
Matt Arsenault59b8b772016-03-01 04:58:17 +000031
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 Arsenault327188a2016-12-15 21:57:11 +0000124; GCN: s_cbranch_scc1
Matt Arsenault59b8b772016-03-01 04:58:17 +0000125
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 Arsenault327188a2016-12-15 21:57:11 +0000178; GCN: s_cbranch_scc1 BB3_2
Matt Arsenault59b8b772016-03-01 04:58:17 +0000179
Matt Arsenault327188a2016-12-15 21:57:11 +0000180; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
Matt Arsenault59b8b772016-03-01 04:58:17 +0000181; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0xff
182
183; GCN: BB3_2:
Matt Arsenault327188a2016-12-15 21:57:11 +0000184; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
Matt Arsenault59b8b772016-03-01 04:58:17 +0000185; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0x7f
186
187; GCN: BB3_3:
188; GCN: buffer_store_dwordx2
189define void @sink_ubfe_i64_span_midpoint(i64 addrspace(1)* %out, i64 %arg1) #0 {
190entry:
191 %shr = lshr i64 %arg1, 30
192 br i1 undef, label %bb0, label %bb1
193
194bb0:
195 %val0 = and i64 %shr, 255
196 store volatile i32 0, i32 addrspace(1)* undef
197 br label %ret
198
199bb1:
200 %val1 = and i64 %shr, 127
201 store volatile i32 0, i32 addrspace(1)* undef
202 br label %ret
203
204ret:
205 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
206 store i64 %phi, i64 addrspace(1)* %out
207 ret void
208}
209
210; OPT-LABEL: @sink_ubfe_i64_low32(
211; OPT: entry:
212; OPT-NOT: lshr
213; OPT: br i1
214
215; OPT: bb0:
216; OPT: %0 = lshr i64 %arg1, 15
217; OPT-NEXT: %val0 = and i64 %0, 255
218
219; OPT: bb1:
220; OPT: %1 = lshr i64 %arg1, 15
221; OPT-NEXT: %val1 = and i64 %1, 127
222
223; OPT: ret:
224; OPT: store
225; OPT: ret
226
227; GCN-LABEL: {{^}}sink_ubfe_i64_low32:
228
Matt Arsenault327188a2016-12-15 21:57:11 +0000229; GCN: s_cbranch_scc1 BB4_2
Matt Arsenault59b8b772016-03-01 04:58:17 +0000230
Matt Arsenault8d1052f2016-04-21 18:03:06 +0000231; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x8000f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000232
233; GCN: BB4_2:
Matt Arsenault8d1052f2016-04-21 18:03:06 +0000234; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x7000f
Matt Arsenault59b8b772016-03-01 04:58:17 +0000235
236; GCN: BB4_3:
237; GCN: buffer_store_dwordx2
238define void @sink_ubfe_i64_low32(i64 addrspace(1)* %out, i64 %arg1) #0 {
239entry:
240 %shr = lshr i64 %arg1, 15
241 br i1 undef, label %bb0, label %bb1
242
243bb0:
244 %val0 = and i64 %shr, 255
245 store volatile i32 0, i32 addrspace(1)* undef
246 br label %ret
247
248bb1:
249 %val1 = and i64 %shr, 127
250 store volatile i32 0, i32 addrspace(1)* undef
251 br label %ret
252
253ret:
254 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
255 store i64 %phi, i64 addrspace(1)* %out
256 ret void
257}
258
259; OPT-LABEL: @sink_ubfe_i64_high32(
260; OPT: entry:
261; OPT-NOT: lshr
262; OPT: br i1
263
264; OPT: bb0:
265; OPT: %0 = lshr i64 %arg1, 35
266; OPT-NEXT: %val0 = and i64 %0, 255
267
268; OPT: bb1:
269; OPT: %1 = lshr i64 %arg1, 35
270; OPT-NEXT: %val1 = and i64 %1, 127
271
272; OPT: ret:
273; OPT: store
274; OPT: ret
275
276; GCN-LABEL: {{^}}sink_ubfe_i64_high32:
Matt Arsenault327188a2016-12-15 21:57:11 +0000277; GCN: s_cbranch_scc1 BB5_2
Matt Arsenault59b8b772016-03-01 04:58:17 +0000278; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80003
279
280; GCN: BB5_2:
281; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70003
282
283; GCN: BB5_3:
284; GCN: buffer_store_dwordx2
285define void @sink_ubfe_i64_high32(i64 addrspace(1)* %out, i64 %arg1) #0 {
286entry:
287 %shr = lshr i64 %arg1, 35
288 br i1 undef, label %bb0, label %bb1
289
290bb0:
291 %val0 = and i64 %shr, 255
292 store volatile i32 0, i32 addrspace(1)* undef
293 br label %ret
294
295bb1:
296 %val1 = and i64 %shr, 127
297 store volatile i32 0, i32 addrspace(1)* undef
298 br label %ret
299
300ret:
301 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
302 store i64 %phi, i64 addrspace(1)* %out
303 ret void
304}
305
306attributes #0 = { nounwind }