Skip to content

Commit 51349fb

Browse files
committed
[GISel] Tests for op(trunc(x), trunc(y)) fold
1 parent cd45bb2 commit 51349fb

File tree

1 file changed

+339
-0
lines changed

1 file changed

+339
-0
lines changed
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -o - -mtriple=aarch64-unknown-unknown -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s | FileCheck %s
3+
4+
# Truncs with a single use get folded.
5+
6+
# and(trunc(x), trunc(y)) -> trunc(and(x, y))
7+
---
8+
name: and_trunc
9+
body: |
10+
bb.0:
11+
liveins: $w0, $w1
12+
; CHECK-LABEL: name: and_trunc
13+
; CHECK: liveins: $w0, $w1
14+
; CHECK-NEXT: {{ $}}
15+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
16+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
17+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
18+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
19+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s16) = G_AND [[TRUNC]], [[TRUNC1]]
20+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s16)
21+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
22+
%0:_(s32) = COPY $w0
23+
%1:_(s32) = COPY $w1
24+
%2:_(s16) = G_TRUNC %0
25+
%3:_(s16) = G_TRUNC %1
26+
%4:_(s16) = G_AND %2, %3
27+
%5:_(s32) = G_ANYEXT %4
28+
$w0 = COPY %5
29+
...
30+
---
31+
name: and_trunc_vector
32+
body: |
33+
bb.0:
34+
liveins: $q0, $q1
35+
; CHECK-LABEL: name: and_trunc_vector
36+
; CHECK: liveins: $q0, $q1
37+
; CHECK-NEXT: {{ $}}
38+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
39+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
40+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY]](<4 x s32>)
41+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY1]](<4 x s32>)
42+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<4 x s16>) = G_AND [[TRUNC]], [[TRUNC1]]
43+
; CHECK-NEXT: $x0 = COPY [[AND]](<4 x s16>)
44+
%0:_(<4 x s32>) = COPY $q0
45+
%1:_(<4 x s32>) = COPY $q1
46+
%2:_(<4 x s16>) = G_TRUNC %0
47+
%3:_(<4 x s16>) = G_TRUNC %1
48+
%4:_(<4 x s16>) = G_AND %2, %3
49+
$x0 = COPY %4
50+
...
51+
52+
# or(trunc(x), trunc(y)) -> trunc(or(x, y))
53+
---
54+
name: or_trunc
55+
body: |
56+
bb.0:
57+
liveins: $w0, $w1
58+
; CHECK-LABEL: name: or_trunc
59+
; CHECK: liveins: $w0, $w1
60+
; CHECK-NEXT: {{ $}}
61+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
62+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
63+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
64+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
65+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s16) = G_OR [[TRUNC]], [[TRUNC1]]
66+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[OR]](s16)
67+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
68+
%0:_(s32) = COPY $w0
69+
%1:_(s32) = COPY $w1
70+
%2:_(s16) = G_TRUNC %0
71+
%3:_(s16) = G_TRUNC %1
72+
%4:_(s16) = G_OR %2, %3
73+
%5:_(s32) = G_ANYEXT %4
74+
$w0 = COPY %5
75+
...
76+
---
77+
name: or_trunc_vector
78+
body: |
79+
bb.0:
80+
liveins: $q0, $q1
81+
; CHECK-LABEL: name: or_trunc_vector
82+
; CHECK: liveins: $q0, $q1
83+
; CHECK-NEXT: {{ $}}
84+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
85+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
86+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY]](<4 x s32>)
87+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY1]](<4 x s32>)
88+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(<4 x s16>) = G_OR [[TRUNC]], [[TRUNC1]]
89+
; CHECK-NEXT: $x0 = COPY [[OR]](<4 x s16>)
90+
%0:_(<4 x s32>) = COPY $q0
91+
%1:_(<4 x s32>) = COPY $q1
92+
%2:_(<4 x s16>) = G_TRUNC %0
93+
%3:_(<4 x s16>) = G_TRUNC %1
94+
%4:_(<4 x s16>) = G_OR %2, %3
95+
$x0 = COPY %4
96+
...
97+
98+
# xor(trunc(x), trunc(y)) -> trunc(xor(x, y))
99+
---
100+
name: xor_trunc
101+
body: |
102+
bb.0:
103+
liveins: $w0, $w1
104+
; CHECK-LABEL: name: xor_trunc
105+
; CHECK: liveins: $w0, $w1
106+
; CHECK-NEXT: {{ $}}
107+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
108+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
109+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
110+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
111+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s16) = G_XOR [[TRUNC]], [[TRUNC1]]
112+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[XOR]](s16)
113+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
114+
%0:_(s32) = COPY $w0
115+
%1:_(s32) = COPY $w1
116+
%2:_(s16) = G_TRUNC %0
117+
%3:_(s16) = G_TRUNC %1
118+
%4:_(s16) = G_XOR %2, %3
119+
%5:_(s32) = G_ANYEXT %4
120+
$w0 = COPY %5
121+
...
122+
---
123+
name: xor_trunc_vector
124+
body: |
125+
bb.0:
126+
liveins: $q0, $q1
127+
; CHECK-LABEL: name: xor_trunc_vector
128+
; CHECK: liveins: $q0, $q1
129+
; CHECK-NEXT: {{ $}}
130+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
131+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
132+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY]](<4 x s32>)
133+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY1]](<4 x s32>)
134+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<4 x s16>) = G_XOR [[TRUNC]], [[TRUNC1]]
135+
; CHECK-NEXT: $x0 = COPY [[XOR]](<4 x s16>)
136+
%0:_(<4 x s32>) = COPY $q0
137+
%1:_(<4 x s32>) = COPY $q1
138+
%2:_(<4 x s16>) = G_TRUNC %0
139+
%3:_(<4 x s16>) = G_TRUNC %1
140+
%4:_(<4 x s16>) = G_XOR %2, %3
141+
$x0 = COPY %4
142+
...
143+
144+
# Truncs with multiple uses do not get folded.
145+
---
146+
name: or_trunc_multiuse_1
147+
body: |
148+
bb.0:
149+
liveins: $w0, $w1, $x2
150+
; CHECK-LABEL: name: or_trunc_multiuse_1
151+
; CHECK: liveins: $w0, $w1, $x2
152+
; CHECK-NEXT: {{ $}}
153+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
154+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
155+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2
156+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
157+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
158+
; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[COPY2]](p0) :: (store (s16))
159+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s16) = G_OR [[TRUNC]], [[TRUNC1]]
160+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[OR]](s16)
161+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
162+
%0:_(s32) = COPY $w0
163+
%1:_(s32) = COPY $w1
164+
%5:_(p0) = COPY $x2
165+
%2:_(s16) = G_TRUNC %0
166+
%3:_(s16) = G_TRUNC %1
167+
G_STORE %2, %5 :: (store (s16))
168+
%4:_(s16) = G_OR %2, %3
169+
%6:_(s32) = G_ANYEXT %4
170+
$w0 = COPY %6
171+
...
172+
---
173+
name: and_trunc_multiuse_2
174+
body: |
175+
bb.0:
176+
liveins: $w0, $w1, $x2
177+
; CHECK-LABEL: name: and_trunc_multiuse_2
178+
; CHECK: liveins: $w0, $w1, $x2
179+
; CHECK-NEXT: {{ $}}
180+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
181+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
182+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2
183+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
184+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
185+
; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[COPY2]](p0) :: (store (s16))
186+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s16) = G_AND [[TRUNC]], [[TRUNC1]]
187+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s16)
188+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
189+
%0:_(s32) = COPY $w0
190+
%1:_(s32) = COPY $w1
191+
%5:_(p0) = COPY $x2
192+
%2:_(s16) = G_TRUNC %0
193+
%3:_(s16) = G_TRUNC %1
194+
G_STORE %2, %5 :: (store (s16))
195+
%4:_(s16) = G_AND %2, %3
196+
%6:_(s32) = G_ANYEXT %4
197+
$w0 = COPY %6
198+
...
199+
---
200+
name: xor_trunc_vector_multiuse
201+
body: |
202+
bb.0:
203+
liveins: $w0, $w1, $x2
204+
; CHECK-LABEL: name: xor_trunc_vector_multiuse
205+
; CHECK: liveins: $w0, $w1, $x2
206+
; CHECK-NEXT: {{ $}}
207+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
208+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
209+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2
210+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY]](<4 x s32>)
211+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY1]](<4 x s32>)
212+
; CHECK-NEXT: G_STORE [[TRUNC]](<4 x s16>), [[COPY2]](p0) :: (store (<4 x s16>))
213+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<4 x s16>) = G_XOR [[TRUNC]], [[TRUNC1]]
214+
; CHECK-NEXT: $x0 = COPY [[XOR]](<4 x s16>)
215+
%0:_(<4 x s32>) = COPY $q0
216+
%1:_(<4 x s32>) = COPY $q1
217+
%5:_(p0) = COPY $x2
218+
%2:_(<4 x s16>) = G_TRUNC %0
219+
%3:_(<4 x s16>) = G_TRUNC %1
220+
G_STORE %2, %5 :: (store (<4 x s16>))
221+
%4:_(<4 x s16>) = G_XOR %2, %3
222+
$x0 = COPY %4
223+
...
224+
225+
# Freezes should get pushed through truncs.
226+
227+
# This optimizes the pattern where `select(cond, T, 0)` gets converted to
228+
# `and(cond, freeze(T))`.
229+
230+
# and(freeze(trunc(x)), trunc(y)) -> trunc(and(freeze(x), y))
231+
---
232+
name: and_trunc_freeze
233+
body: |
234+
bb.0:
235+
liveins: $w0, $w1
236+
; CHECK-LABEL: name: and_trunc_freeze
237+
; CHECK: liveins: $w0, $w1
238+
; CHECK-NEXT: {{ $}}
239+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
240+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
241+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
242+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
243+
; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s16) = G_FREEZE [[TRUNC]]
244+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s16) = G_AND [[FREEZE]], [[TRUNC1]]
245+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s16)
246+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
247+
%0:_(s32) = COPY $w0
248+
%1:_(s32) = COPY $w1
249+
%2:_(s16) = G_TRUNC %0
250+
%3:_(s16) = G_TRUNC %1
251+
%6:_(s16) = G_FREEZE %2
252+
%4:_(s16) = G_AND %6, %3
253+
%5:_(s32) = G_ANYEXT %4
254+
$w0 = COPY %5
255+
...
256+
257+
# and(freeze(trunc(x)), freeze(trunc(y))) -> trunc(and(freeze(x), freeze(y)))
258+
---
259+
name: and_trunc_freeze_both
260+
body: |
261+
bb.0:
262+
liveins: $w0, $w1
263+
; CHECK-LABEL: name: and_trunc_freeze_both
264+
; CHECK: liveins: $w0, $w1
265+
; CHECK-NEXT: {{ $}}
266+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
267+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
268+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
269+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
270+
; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s16) = G_FREEZE [[TRUNC]]
271+
; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s16) = G_FREEZE [[TRUNC1]]
272+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s16) = G_AND [[FREEZE]], [[FREEZE1]]
273+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s16)
274+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
275+
%0:_(s32) = COPY $w0
276+
%1:_(s32) = COPY $w1
277+
%2:_(s16) = G_TRUNC %0
278+
%3:_(s16) = G_TRUNC %1
279+
%6:_(s16) = G_FREEZE %2
280+
%7:_(s16) = G_FREEZE %3
281+
%4:_(s16) = G_AND %6, %7
282+
%5:_(s32) = G_ANYEXT %4
283+
$w0 = COPY %5
284+
...
285+
286+
# The freeze fold is less important for G_OR and G_XOR, however it can still
287+
# trigger.
288+
---
289+
name: or_trunc_freeze
290+
body: |
291+
bb.0:
292+
liveins: $w0, $w1
293+
; CHECK-LABEL: name: or_trunc_freeze
294+
; CHECK: liveins: $w0, $w1
295+
; CHECK-NEXT: {{ $}}
296+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
297+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
298+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
299+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
300+
; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s16) = G_FREEZE [[TRUNC]]
301+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s16) = G_OR [[FREEZE]], [[TRUNC1]]
302+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[OR]](s16)
303+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
304+
%0:_(s32) = COPY $w0
305+
%1:_(s32) = COPY $w1
306+
%2:_(s16) = G_TRUNC %0
307+
%3:_(s16) = G_TRUNC %1
308+
%6:_(s16) = G_FREEZE %2
309+
%4:_(s16) = G_OR %6, %3
310+
%5:_(s32) = G_ANYEXT %4
311+
$w0 = COPY %5
312+
...
313+
---
314+
name: xor_trunc_freeze_both
315+
body: |
316+
bb.0:
317+
liveins: $w0, $w1
318+
; CHECK-LABEL: name: xor_trunc_freeze_both
319+
; CHECK: liveins: $w0, $w1
320+
; CHECK-NEXT: {{ $}}
321+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
322+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
323+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
324+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
325+
; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s16) = G_FREEZE [[TRUNC]]
326+
; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s16) = G_FREEZE [[TRUNC1]]
327+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s16) = G_XOR [[FREEZE]], [[FREEZE1]]
328+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[XOR]](s16)
329+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
330+
%0:_(s32) = COPY $w0
331+
%1:_(s32) = COPY $w1
332+
%2:_(s16) = G_TRUNC %0
333+
%3:_(s16) = G_TRUNC %1
334+
%6:_(s16) = G_FREEZE %2
335+
%7:_(s16) = G_FREEZE %3
336+
%4:_(s16) = G_XOR %6, %7
337+
%5:_(s32) = G_ANYEXT %4
338+
$w0 = COPY %5
339+
...

0 commit comments

Comments
 (0)