• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2#
3# Check that we can fold (x & mask) -> x when (x & mask) is known to equal x.
4#
5# RUN: llc -mtriple aarch64 -run-pass=aarch64-postlegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
6
7---
8name:            remove_and_with_one_bit
9legalized:       true
10tracksRegLiveness: true
11body:             |
12  bb.0:
13    liveins: $w0, $w1
14    ; G_ICMP produces a single bit. The mask is 1.
15    ;
16    ; cmp = 000...0?
17    ; mask = 000...01
18    ; cmp & mask = 000...0?
19    ;
20    ; Remove the G_AND.
21    ;
22    ; CHECK-LABEL: name: remove_and_with_one_bit
23    ; CHECK: liveins: $w0, $w1
24    ; CHECK: %x:_(s32) = COPY $w0
25    ; CHECK: %y:_(s32) = COPY $w1
26    ; CHECK: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y
27    ; CHECK: $w0 = COPY %cmp(s32)
28    ; CHECK: RET_ReallyLR implicit $w0
29    %x:_(s32) = COPY $w0
30    %y:_(s32) = COPY $w1
31    %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y
32    %mask:_(s32) = G_CONSTANT i32 1
33    %and:_(s32) = G_AND %cmp(s32), %mask
34    $w0 = COPY %and(s32)
35    RET_ReallyLR implicit $w0
36
37...
38---
39name:            remove_and_all_ones_mask
40legalized:       true
41tracksRegLiveness: true
42body:             |
43  bb.0:
44    liveins: $w0, $w1, $w2
45    ; -1 is all ones. Therefore z & -1 = z. Remove the G_AND.
46    ;
47    ; CHECK-LABEL: name: remove_and_all_ones_mask
48    ; CHECK: liveins: $w0, $w1, $w2
49    ; CHECK: %z:_(s32) = COPY $w2
50    ; CHECK: $w0 = COPY %z(s32)
51    ; CHECK: RET_ReallyLR implicit $w0
52    %x:_(s32) = COPY $w0
53    %y:_(s32) = COPY $w1
54    %z:_(s32) = COPY $w2
55    %mask:_(s32) = G_CONSTANT i32 -1
56    %and:_(s32) = G_AND %z(s32), %mask
57    $w0 = COPY %and(s32)
58    RET_ReallyLR implicit $w0
59
60...
61---
62name:            remove_and_all_ones_zext
63legalized:       true
64tracksRegLiveness: true
65body:             |
66  bb.0:
67    liveins: $w0, $w1, $w2
68    ; %z is a s32, so it can be at most the all-ones value on 32 bits.
69    ; In decimal this is 4294967295. Any zero-extension of %z is at most this
70    ; value.
71    ;
72    ; Therefore, zext(z) & 4294967295 == z. Remove the G_AND.
73    ;
74    ; CHECK-LABEL: name: remove_and_all_ones_zext
75    ; CHECK: liveins: $w0, $w1, $w2
76    ; CHECK: %z:_(s32) = COPY $w2
77    ; CHECK: %ext:_(s64) = G_ZEXT %z(s32)
78    ; CHECK: $x0 = COPY %ext(s64)
79    ; CHECK: RET_ReallyLR implicit $x0
80    %x:_(s32) = COPY $w0
81    %y:_(s32) = COPY $w1
82    %z:_(s32) = COPY $w2
83    %ext:_(s64) = G_ZEXT %z
84    %mask:_(s64) = G_CONSTANT i64 4294967295
85    %and:_(s64) = G_AND %ext(s64), %mask
86    $x0 = COPY %and(s64)
87    RET_ReallyLR implicit $x0
88
89...
90---
91name:            remove_and_all_ones_anyext
92legalized:       true
93tracksRegLiveness: true
94body:             |
95  bb.0:
96    liveins: $w0, $w1, $w2
97    ; This is the same as the zext case.
98    ;
99    ; CHECK-LABEL: name: remove_and_all_ones_anyext
100    ; CHECK: liveins: $w0, $w1, $w2
101    ; CHECK: %z:_(s32) = COPY $w2
102    ; CHECK: %ext:_(s64) = G_ZEXT %z(s32)
103    ; CHECK: $x0 = COPY %ext(s64)
104    ; CHECK: RET_ReallyLR implicit $x0
105    %x:_(s32) = COPY $w0
106    %y:_(s32) = COPY $w1
107    %z:_(s32) = COPY $w2
108    %ext:_(s64) = G_ZEXT %z
109    %mask:_(s64) = G_CONSTANT i64 4294967295
110    %and:_(s64) = G_AND %ext(s64), %mask
111    $x0 = COPY %and(s64)
112    RET_ReallyLR implicit $x0
113
114...
115---
116name:            dont_remove_all_ones_sext
117legalized:       true
118tracksRegLiveness: true
119body:             |
120  bb.0:
121    liveins: $w0, $w1, $w2
122    ; We don't know if the sign bit is set on %z. So, the value in %ext may have
123    ; higher bits set than 4294967295.
124    ;
125    ; CHECK-LABEL: name: dont_remove_all_ones_sext
126    ; CHECK: liveins: $w0, $w1, $w2
127    ; CHECK: %z:_(s32) = COPY $w2
128    ; CHECK: %ext:_(s64) = G_SEXT %z(s32)
129    ; CHECK: %mask:_(s64) = G_CONSTANT i64 4294967295
130    ; CHECK: %and:_(s64) = G_AND %ext, %mask
131    ; CHECK: $x0 = COPY %and(s64)
132    ; CHECK: RET_ReallyLR implicit $x0
133    %x:_(s32) = COPY $w0
134    %y:_(s32) = COPY $w1
135    %z:_(s32) = COPY $w2
136    %ext:_(s64) = G_SEXT %z
137    %mask:_(s64) = G_CONSTANT i64 4294967295
138    %and:_(s64) = G_AND %ext(s64), %mask
139    $x0 = COPY %and(s64)
140    RET_ReallyLR implicit $x0
141
142...
143---
144name:            remove_and_positive_constant_sext
145legalized:       true
146tracksRegLiveness: true
147body:             |
148  bb.0:
149    liveins: $w0, $w1, $w2
150    ; We know the sign bit is not set on %z. Therefore,
151    ;
152    ; z = ext = 42 = 000...0101010
153    ; mask = 0000...0111111
154    ;
155    ; So z & mask == z
156    ; CHECK-LABEL: name: remove_and_positive_constant_sext
157    ; CHECK: liveins: $w0, $w1, $w2
158    ; CHECK: %z:_(s32) = G_CONSTANT i32 42
159    ; CHECK: %ext:_(s64) = G_SEXT %z(s32)
160    ; CHECK: $x0 = COPY %ext(s64)
161    ; CHECK: RET_ReallyLR implicit $x0
162    %x:_(s32) = COPY $w0
163    %y:_(s32) = COPY $w1
164    %z:_(s32) = G_CONSTANT i32 42
165    %ext:_(s64) = G_SEXT %z
166    %mask:_(s64) = G_CONSTANT i64 63
167    %and:_(s64) = G_AND %ext(s64), %mask
168    $x0 = COPY %and(s64)
169    RET_ReallyLR implicit $x0
170
171...
172---
173name:            not_a_mask
174legalized:       true
175tracksRegLiveness: true
176body:             |
177  bb.0:
178    liveins: $w0, $w1
179    ; 6 is not a mask, so we should still have the G_AND.
180    ;
181    ; CHECK-LABEL: name: not_a_mask
182    ; CHECK: liveins: $w0, $w1
183    ; CHECK: %x:_(s32) = COPY $w0
184    ; CHECK: %y:_(s32) = COPY $w1
185    ; CHECK: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y
186    ; CHECK: %mask:_(s32) = G_CONSTANT i32 6
187    ; CHECK: %and:_(s32) = G_AND %cmp, %mask
188    ; CHECK: $w0 = COPY %and(s32)
189    ; CHECK: RET_ReallyLR implicit $w0
190    %x:_(s32) = COPY $w0
191    %y:_(s32) = COPY $w1
192    %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y
193    %mask:_(s32) = G_CONSTANT i32 6
194    %and:_(s32) = G_AND %cmp(s32), %mask
195    $w0 = COPY %and(s32)
196    RET_ReallyLR implicit $w0
197
198...
199---
200name:            unknown_val
201legalized:       true
202tracksRegLiveness: true
203body:             |
204  bb.0:
205    liveins: $w0, $w1, $w2
206    ; We don't know what's in $w2, so we can't remove the G_AND without a mask
207    ; that fills every bit in the type.
208    ;
209    ; CHECK-LABEL: name: unknown_val
210    ; CHECK: liveins: $w0, $w1, $w2
211    ; CHECK: %z:_(s32) = COPY $w2
212    ; CHECK: %one:_(s32) = G_CONSTANT i32 32
213    ; CHECK: %and:_(s32) = G_AND %z, %one
214    ; CHECK: $w0 = COPY %and(s32)
215    ; CHECK: RET_ReallyLR implicit $w0
216    %x:_(s32) = COPY $w0
217    %y:_(s32) = COPY $w1
218    %z:_(s32) = COPY $w2
219    %one:_(s32) = G_CONSTANT i32 32
220    %and:_(s32) = G_AND %z(s32), %one
221    $w0 = COPY %and(s32)
222    RET_ReallyLR implicit $w0
223...
224