blob: f29cdf743bb9e0c0c8171920e58227c0bae18149 [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
226; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 15
227; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0xff
228
229; GCN: BB4_2:
230; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 15
231; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0x7f
232
233; GCN: BB4_3:
234; GCN: buffer_store_dwordx2
235define void @sink_ubfe_i64_low32(i64 addrspace(1)* %out, i64 %arg1) #0 {
236entry:
237 %shr = lshr i64 %arg1, 15
238 br i1 undef, label %bb0, label %bb1
239
240bb0:
241 %val0 = and i64 %shr, 255
242 store volatile i32 0, i32 addrspace(1)* undef
243 br label %ret
244
245bb1:
246 %val1 = and i64 %shr, 127
247 store volatile i32 0, i32 addrspace(1)* undef
248 br label %ret
249
250ret:
251 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
252 store i64 %phi, i64 addrspace(1)* %out
253 ret void
254}
255
256; OPT-LABEL: @sink_ubfe_i64_high32(
257; OPT: entry:
258; OPT-NOT: lshr
259; OPT: br i1
260
261; OPT: bb0:
262; OPT: %0 = lshr i64 %arg1, 35
263; OPT-NEXT: %val0 = and i64 %0, 255
264
265; OPT: bb1:
266; OPT: %1 = lshr i64 %arg1, 35
267; OPT-NEXT: %val1 = and i64 %1, 127
268
269; OPT: ret:
270; OPT: store
271; OPT: ret
272
273; GCN-LABEL: {{^}}sink_ubfe_i64_high32:
274; GCN: s_cbranch_vccnz BB5_2
275; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80003
276
277; GCN: BB5_2:
278; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70003
279
280; GCN: BB5_3:
281; GCN: buffer_store_dwordx2
282define void @sink_ubfe_i64_high32(i64 addrspace(1)* %out, i64 %arg1) #0 {
283entry:
284 %shr = lshr i64 %arg1, 35
285 br i1 undef, label %bb0, label %bb1
286
287bb0:
288 %val0 = and i64 %shr, 255
289 store volatile i32 0, i32 addrspace(1)* undef
290 br label %ret
291
292bb1:
293 %val1 = and i64 %shr, 127
294 store volatile i32 0, i32 addrspace(1)* undef
295 br label %ret
296
297ret:
298 %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
299 store i64 %phi, i64 addrspace(1)* %out
300 ret void
301}
302
303attributes #0 = { nounwind }