Skip to content

Commit ea4550d

Browse files
fhahnrorth
authored andcommitted
[VectorCombine] Add test cases for scalarizing extracts of extends.
Add test cases where scalarizing extracts of a zext can be profitable.
1 parent cf46e8d commit ea4550d

File tree

1 file changed

+268
-0
lines changed

1 file changed

+268
-0
lines changed
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -p vector-combine -mtriple=arm64-apple-macosx -S %s | FileCheck %s
3+
4+
declare void @use.i32(i32)
5+
declare void @use.i64(i64)
6+
declare void @use.v4i32(<4 x i32>)
7+
8+
define void @zext_v4i8_all_lanes_used(<4 x i8> %src) {
9+
; CHECK-LABEL: define void @zext_v4i8_all_lanes_used(
10+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
11+
; CHECK-NEXT: [[ENTRY:.*:]]
12+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
13+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i32> [[EXT9]], i64 0
14+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
15+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
16+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i32> [[EXT9]], i64 3
17+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_0]])
18+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
19+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
20+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_3]])
21+
; CHECK-NEXT: ret void
22+
;
23+
entry:
24+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
25+
%ext.0 = extractelement <4 x i32> %ext9, i64 0
26+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
27+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
28+
%ext.3 = extractelement <4 x i32> %ext9, i64 3
29+
30+
call void @use.i32(i32 %ext.0)
31+
call void @use.i32(i32 %ext.1)
32+
call void @use.i32(i32 %ext.2)
33+
call void @use.i32(i32 %ext.3)
34+
ret void
35+
}
36+
37+
define void @sext_v4i8_all_lanes_used(<4 x i8> %src) {
38+
; CHECK-LABEL: define void @sext_v4i8_all_lanes_used(
39+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
40+
; CHECK-NEXT: [[ENTRY:.*:]]
41+
; CHECK-NEXT: [[EXT9:%.*]] = sext <4 x i8> [[SRC]] to <4 x i32>
42+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i32> [[EXT9]], i64 0
43+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
44+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
45+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i32> [[EXT9]], i64 3
46+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_0]])
47+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
48+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
49+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_3]])
50+
; CHECK-NEXT: ret void
51+
;
52+
entry:
53+
%ext9 = sext <4 x i8> %src to <4 x i32>
54+
%ext.0 = extractelement <4 x i32> %ext9, i64 0
55+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
56+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
57+
%ext.3 = extractelement <4 x i32> %ext9, i64 3
58+
59+
call void @use.i32(i32 %ext.0)
60+
call void @use.i32(i32 %ext.1)
61+
call void @use.i32(i32 %ext.2)
62+
call void @use.i32(i32 %ext.3)
63+
ret void
64+
}
65+
66+
67+
define void @zext_v4i8_3_lanes_used_1(<4 x i8> %src) {
68+
; CHECK-LABEL: define void @zext_v4i8_3_lanes_used_1(
69+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
70+
; CHECK-NEXT: [[ENTRY:.*:]]
71+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
72+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
73+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
74+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i32> [[EXT9]], i64 3
75+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
76+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
77+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_3]])
78+
; CHECK-NEXT: ret void
79+
;
80+
entry:
81+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
82+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
83+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
84+
%ext.3 = extractelement <4 x i32> %ext9, i64 3
85+
86+
call void @use.i32(i32 %ext.1)
87+
call void @use.i32(i32 %ext.2)
88+
call void @use.i32(i32 %ext.3)
89+
ret void
90+
}
91+
92+
define void @zext_v4i8_3_lanes_used_2(<4 x i8> %src) {
93+
; CHECK-LABEL: define void @zext_v4i8_3_lanes_used_2(
94+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
95+
; CHECK-NEXT: [[ENTRY:.*:]]
96+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
97+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i32> [[EXT9]], i64 0
98+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
99+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i32> [[EXT9]], i64 3
100+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_0]])
101+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
102+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_3]])
103+
; CHECK-NEXT: ret void
104+
;
105+
entry:
106+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
107+
%ext.0 = extractelement <4 x i32> %ext9, i64 0
108+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
109+
%ext.3 = extractelement <4 x i32> %ext9, i64 3
110+
111+
call void @use.i32(i32 %ext.0)
112+
call void @use.i32(i32 %ext.1)
113+
call void @use.i32(i32 %ext.3)
114+
ret void
115+
}
116+
117+
define void @zext_v4i8_2_lanes_used_1(<4 x i8> %src) {
118+
; CHECK-LABEL: define void @zext_v4i8_2_lanes_used_1(
119+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
120+
; CHECK-NEXT: [[ENTRY:.*:]]
121+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
122+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
123+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
124+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
125+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
126+
; CHECK-NEXT: ret void
127+
;
128+
entry:
129+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
130+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
131+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
132+
133+
call void @use.i32(i32 %ext.1)
134+
call void @use.i32(i32 %ext.2)
135+
ret void
136+
}
137+
138+
define void @zext_v4i8_2_lanes_used_2(<4 x i8> %src) {
139+
; CHECK-LABEL: define void @zext_v4i8_2_lanes_used_2(
140+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
141+
; CHECK-NEXT: [[ENTRY:.*:]]
142+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
143+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i32> [[EXT9]], i64 0
144+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
145+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_0]])
146+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
147+
; CHECK-NEXT: ret void
148+
;
149+
entry:
150+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
151+
%ext.0 = extractelement <4 x i32> %ext9, i64 0
152+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
153+
154+
call void @use.i32(i32 %ext.0)
155+
call void @use.i32(i32 %ext.2)
156+
ret void
157+
}
158+
159+
define void @zext_v4i8_all_lanes_used_noundef(<4 x i8> noundef %src) {
160+
; CHECK-LABEL: define void @zext_v4i8_all_lanes_used_noundef(
161+
; CHECK-SAME: <4 x i8> noundef [[SRC:%.*]]) {
162+
; CHECK-NEXT: [[ENTRY:.*:]]
163+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
164+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i32> [[EXT9]], i64 0
165+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
166+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
167+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i32> [[EXT9]], i64 3
168+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_0]])
169+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
170+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
171+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_3]])
172+
; CHECK-NEXT: ret void
173+
;
174+
entry:
175+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
176+
%ext.0 = extractelement <4 x i32> %ext9, i64 0
177+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
178+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
179+
%ext.3 = extractelement <4 x i32> %ext9, i64 3
180+
181+
call void @use.i32(i32 %ext.0)
182+
call void @use.i32(i32 %ext.1)
183+
call void @use.i32(i32 %ext.2)
184+
call void @use.i32(i32 %ext.3)
185+
ret void
186+
}
187+
188+
define void @zext_v4i8_all_lanes_used_zext_other_users(<4 x i8> %src) {
189+
; CHECK-LABEL: define void @zext_v4i8_all_lanes_used_zext_other_users(
190+
; CHECK-SAME: <4 x i8> [[SRC:%.*]]) {
191+
; CHECK-NEXT: [[ENTRY:.*:]]
192+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i8> [[SRC]] to <4 x i32>
193+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i32> [[EXT9]], i64 0
194+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i32> [[EXT9]], i64 1
195+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i32> [[EXT9]], i64 2
196+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i32> [[EXT9]], i64 3
197+
; CHECK-NEXT: call void @use.v4i32(<4 x i32> [[EXT9]])
198+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_0]])
199+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_1]])
200+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_2]])
201+
; CHECK-NEXT: call void @use.i32(i32 [[EXT_3]])
202+
; CHECK-NEXT: ret void
203+
;
204+
entry:
205+
%ext9 = zext nneg <4 x i8> %src to <4 x i32>
206+
%ext.0 = extractelement <4 x i32> %ext9, i64 0
207+
%ext.1 = extractelement <4 x i32> %ext9, i64 1
208+
%ext.2 = extractelement <4 x i32> %ext9, i64 2
209+
%ext.3 = extractelement <4 x i32> %ext9, i64 3
210+
211+
call void @use.v4i32(<4 x i32> %ext9)
212+
213+
call void @use.i32(i32 %ext.0)
214+
call void @use.i32(i32 %ext.1)
215+
call void @use.i32(i32 %ext.2)
216+
call void @use.i32(i32 %ext.3)
217+
ret void
218+
}
219+
220+
define void @zext_v4i16_all_lanes_used(<4 x i16> %src) {
221+
; CHECK-LABEL: define void @zext_v4i16_all_lanes_used(
222+
; CHECK-SAME: <4 x i16> [[SRC:%.*]]) {
223+
; CHECK-NEXT: [[ENTRY:.*:]]
224+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <4 x i16> [[SRC]] to <4 x i64>
225+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <4 x i64> [[EXT9]], i64 0
226+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <4 x i64> [[EXT9]], i64 1
227+
; CHECK-NEXT: [[EXT_2:%.*]] = extractelement <4 x i64> [[EXT9]], i64 2
228+
; CHECK-NEXT: [[EXT_3:%.*]] = extractelement <4 x i64> [[EXT9]], i64 3
229+
; CHECK-NEXT: call void @use.i64(i64 [[EXT_0]])
230+
; CHECK-NEXT: call void @use.i64(i64 [[EXT_1]])
231+
; CHECK-NEXT: call void @use.i64(i64 [[EXT_2]])
232+
; CHECK-NEXT: call void @use.i64(i64 [[EXT_3]])
233+
; CHECK-NEXT: ret void
234+
;
235+
entry:
236+
%ext9 = zext nneg <4 x i16> %src to <4 x i64>
237+
%ext.0 = extractelement <4 x i64> %ext9, i64 0
238+
%ext.1 = extractelement <4 x i64> %ext9, i64 1
239+
%ext.2 = extractelement <4 x i64> %ext9, i64 2
240+
%ext.3 = extractelement <4 x i64> %ext9, i64 3
241+
242+
call void @use.i64(i64 %ext.0)
243+
call void @use.i64(i64 %ext.1)
244+
call void @use.i64(i64 %ext.2)
245+
call void @use.i64(i64 %ext.3)
246+
ret void
247+
}
248+
249+
define void @zext_v2i32_all_lanes_used(<2 x i32> %src) {
250+
; CHECK-LABEL: define void @zext_v2i32_all_lanes_used(
251+
; CHECK-SAME: <2 x i32> [[SRC:%.*]]) {
252+
; CHECK-NEXT: [[ENTRY:.*:]]
253+
; CHECK-NEXT: [[EXT9:%.*]] = zext nneg <2 x i32> [[SRC]] to <2 x i64>
254+
; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <2 x i64> [[EXT9]], i64 0
255+
; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <2 x i64> [[EXT9]], i64 1
256+
; CHECK-NEXT: call void @use.i64(i64 [[EXT_0]])
257+
; CHECK-NEXT: call void @use.i64(i64 [[EXT_1]])
258+
; CHECK-NEXT: ret void
259+
;
260+
entry:
261+
%ext9 = zext nneg <2 x i32> %src to <2 x i64>
262+
%ext.0 = extractelement <2 x i64> %ext9, i64 0
263+
%ext.1 = extractelement <2 x i64> %ext9, i64 1
264+
265+
call void @use.i64(i64 %ext.0)
266+
call void @use.i64(i64 %ext.1)
267+
ret void
268+
}

0 commit comments

Comments
 (0)