1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple=aarch64 -run-pass=aarch64-postlegalizer-lowering --aarch64postlegalizerlowering-only-enable-rule="shuf_to_ins" -verify-machineinstrs %s -o - | FileCheck %s
5 # Check that we can recognize an ins mask for a shuffle vector.
9 name: v2s32_match_left_0
11 tracksRegLiveness: true
16 ; 2 elts -> need 1 match.
18 ; Matched M[0] = 0 -> G_INSERT_VECTOR_ELT should use %left.
19 ; DstLane (G_INSERT_VECTOR_ELT) : 1, because M[1] != 1.
20 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[DstLane] = 0
22 ; CHECK-LABEL: name: v2s32_match_left_0
23 ; CHECK: liveins: $d0, $d1
24 ; CHECK: %left:_(<2 x s32>) = COPY $d0
25 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
26 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](s64)
27 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
28 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](s64)
29 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
30 ; CHECK: RET_ReallyLR implicit $d0
31 %left:_(<2 x s32>) = COPY $d0
32 %right:_(<2 x s32>) = COPY $d1
33 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(0, 0)
34 $d0 = COPY %shuf(<2 x s32>)
35 RET_ReallyLR implicit $d0
39 name: v2s32_match_left_1
41 tracksRegLiveness: true
46 ; 2 elts -> need 1 match.
48 ; Matched M[1] = 1 -> G_INSERT_VECTOR_ELT should use %left.
49 ; DstLane (G_INSERT_VECTOR_ELT) : 0, because M[0] != 0.
50 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[0] = 1
52 ; CHECK-LABEL: name: v2s32_match_left_1
53 ; CHECK: liveins: $d0, $d1
54 ; CHECK: %left:_(<2 x s32>) = COPY $d0
55 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
56 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](s64)
57 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
58 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](s64)
59 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
60 ; CHECK: RET_ReallyLR implicit $d0
61 %left:_(<2 x s32>) = COPY $d0
62 %right:_(<2 x s32>) = COPY $d1
63 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(1, 1)
64 $d0 = COPY %shuf(<2 x s32>)
65 RET_ReallyLR implicit $d0
69 name: v2s32_match_left_3
71 tracksRegLiveness: true
76 ; 2 elts -> need 1 match.
78 ; Matched M[0] = 1 -> G_INSERT_VECTOR_ELT should use %left.
79 ; DstLane (G_INSERT_VECTOR_ELT) : 1, because M[1] != 1.
80 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[1] = 3 - 2 = 1
82 ; CHECK-LABEL: name: v2s32_match_left_3
83 ; CHECK: liveins: $d0, $d1
84 ; CHECK: %left:_(<2 x s32>) = COPY $d0
85 ; CHECK: %right:_(<2 x s32>) = COPY $d1
86 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
87 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](s64)
88 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
89 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](s64)
90 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
91 ; CHECK: RET_ReallyLR implicit $d0
92 %left:_(<2 x s32>) = COPY $d0
93 %right:_(<2 x s32>) = COPY $d1
94 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(0, 3)
95 $d0 = COPY %shuf(<2 x s32>)
96 RET_ReallyLR implicit $d0
101 name: v2s32_match_right_3
103 tracksRegLiveness: true
108 ; 2 elts -> need 1 match.
110 ; Matched M[1] = 1 + 2 -> G_INSERT_VECTOR_ELT should use %right.
111 ; DstLane (G_INSERT_VECTOR_ELT) : 0, because M[0] != 2.
112 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[0] = 1
114 ; CHECK-LABEL: name: v2s32_match_right_3
115 ; CHECK: liveins: $d0, $d1
116 ; CHECK: %left:_(<2 x s32>) = COPY $d0
117 ; CHECK: %right:_(<2 x s32>) = COPY $d1
118 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
119 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](s64)
120 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
121 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](s64)
122 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
123 ; CHECK: RET_ReallyLR implicit $d0
124 %left:_(<2 x s32>) = COPY $d0
125 %right:_(<2 x s32>) = COPY $d1
126 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(1, 3)
127 $d0 = COPY %shuf(<2 x s32>)
128 RET_ReallyLR implicit $d0
132 name: v2s32_match_right_2
134 tracksRegLiveness: true
139 ; 2 elts -> need 1 match.
141 ; Matched M[0] = 0 + 2 -> G_INSERT_VECTOR_ELT should use %right.
142 ; DstLane (G_INSERT_VECTOR_ELT) : 1, because M[1] != 3.
143 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[1] = 0
145 ; CHECK-LABEL: name: v2s32_match_right_2
146 ; CHECK: liveins: $d0, $d1
147 ; CHECK: %left:_(<2 x s32>) = COPY $d0
148 ; CHECK: %right:_(<2 x s32>) = COPY $d1
149 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
150 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](s64)
151 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
152 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](s64)
153 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
154 ; CHECK: RET_ReallyLR implicit $d0
155 %left:_(<2 x s32>) = COPY $d0
156 %right:_(<2 x s32>) = COPY $d1
157 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 0)
158 $d0 = COPY %shuf(<2 x s32>)
159 RET_ReallyLR implicit $d0
163 name: dont_combine_too_many_matches_right
165 tracksRegLiveness: true
170 ; 2 elts -> need 1 match.
172 ; Matched M[0] = 0 + 2, M[1] = 1 + 2 -> too many matches.
174 ; CHECK-LABEL: name: dont_combine_too_many_matches_right
175 ; CHECK: liveins: $d0, $d1
176 ; CHECK: %left:_(<2 x s32>) = COPY $d0
177 ; CHECK: %right:_(<2 x s32>) = COPY $d1
178 ; CHECK: %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 3)
179 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
180 ; CHECK: RET_ReallyLR implicit $d0
181 %left:_(<2 x s32>) = COPY $d0
182 %right:_(<2 x s32>) = COPY $d1
183 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 3)
184 $d0 = COPY %shuf(<2 x s32>)
185 RET_ReallyLR implicit $d0
191 tracksRegLiveness: true
196 ; Matched the correct amount on the left and right.
197 ; Use left as a tiebreaker.
199 ; Matched M[1] = 1 -> G_INSERT_VECTOR_ELT should use %left.
200 ; DstLane (G_INSERT_VECTOR_ELT) : 0, because M[0] != 0.
201 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[0] = 2 - 2 = 0
203 ; CHECK-LABEL: name: tiebreaker
204 ; CHECK: liveins: $d0, $d1
205 ; CHECK: %left:_(<2 x s32>) = COPY $d0
206 ; CHECK: %right:_(<2 x s32>) = COPY $d1
207 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
208 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](s64)
209 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
210 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](s64)
211 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
212 ; CHECK: RET_ReallyLR implicit $d0
213 %left:_(<2 x s32>) = COPY $d0
214 %right:_(<2 x s32>) = COPY $d1
215 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 1)
216 $d0 = COPY %shuf(<2 x s32>)
217 RET_ReallyLR implicit $d0
221 name: tiebreaker_undef
223 tracksRegLiveness: true
228 ; Undef counts as a match for left and right.
230 ; Matched M[1] = -1 -> G_INSERT_VECTOR_ELT should use %left.
231 ; DstLane (G_INSERT_VECTOR_ELT) : 0, because M[0] != 0.
232 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[0] = 2 - 2 = 0
234 ; CHECK-LABEL: name: tiebreaker_undef
235 ; CHECK: liveins: $d0, $d1
236 ; CHECK: %left:_(<2 x s32>) = COPY $d0
237 ; CHECK: %right:_(<2 x s32>) = COPY $d1
238 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
239 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](s64)
240 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
241 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](s64)
242 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
243 ; CHECK: RET_ReallyLR implicit $d0
244 %left:_(<2 x s32>) = COPY $d0
245 %right:_(<2 x s32>) = COPY $d1
246 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, -1)
247 $d0 = COPY %shuf(<2 x s32>)
248 RET_ReallyLR implicit $d0
252 name: match_left_undef
254 tracksRegLiveness: true
259 ; Undef counts as a match for left and right.
261 ; Matched M[1] = -1 -> G_INSERT_VECTOR_ELT should use %left.
262 ; DstLane (G_INSERT_VECTOR_ELT) : 0, because M[0] != 0.
263 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[0] = 3 - 2 = 1
265 ; CHECK-LABEL: name: match_left_undef
266 ; CHECK: liveins: $d0, $d1
267 ; CHECK: %left:_(<2 x s32>) = COPY $d0
268 ; CHECK: %right:_(<2 x s32>) = COPY $d1
269 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
270 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](s64)
271 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
272 ; CHECK: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](s64)
273 ; CHECK: $d0 = COPY %shuf(<2 x s32>)
274 ; CHECK: RET_ReallyLR implicit $d0
275 %left:_(<2 x s32>) = COPY $d0
276 %right:_(<2 x s32>) = COPY $d1
277 %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(3, -1)
278 $d0 = COPY %shuf(<2 x s32>)
279 RET_ReallyLR implicit $d0
283 name: match_right_undef
285 tracksRegLiveness: true
290 ; Matched M[0] = 0 + 4, undef, undef => 3 matches on the right.
292 ; DstLane (G_INSERT_VECTOR_ELT) : 3, because M[3] != 7.
293 ; SrcLane (G_EXTRACT_VECTOR_ELT) : M[3] = 2
295 ; CHECK-LABEL: name: match_right_undef
296 ; CHECK: liveins: $q0, $q1
297 ; CHECK: %left:_(<4 x s32>) = COPY $q0
298 ; CHECK: %right:_(<4 x s32>) = COPY $q1
299 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
300 ; CHECK: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<4 x s32>), [[C]](s64)
301 ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
302 ; CHECK: %shuf:_(<4 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](s64)
303 ; CHECK: $q0 = COPY %shuf(<4 x s32>)
304 ; CHECK: RET_ReallyLR implicit $q0
305 %left:_(<4 x s32>) = COPY $q0
306 %right:_(<4 x s32>) = COPY $q1
307 %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %left(<4 x s32>), %right, shufflemask(4, -1, -1, 2)
308 $q0 = COPY %shuf(<4 x s32>)
309 RET_ReallyLR implicit $q0