xref: /aosp_15_r20/external/llvm/test/CodeGen/AMDGPU/cgp-bitfield-extract.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1; 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
226; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x8000f
227
228; GCN: BB4_2:
229; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x7000f
230
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 }
302