280 lines · plain
1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py2#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 %s6 7---8name: remove_and_with_one_bit9legalized: true10tracksRegLiveness: true11body: |12 bb.0:13 liveins: $w0, $w114 ; G_ICMP produces a single bit. The mask is 1.15 ; cmp = 000...0?16 ; mask = 000...0117 ; cmp & mask = 000...0?18 ; Remove the G_AND.19 ; CHECK-LABEL: name: remove_and_with_one_bit20 ; CHECK: liveins: $w0, $w121 ; CHECK-NEXT: {{ $}}22 ; CHECK-NEXT: %x:_(s32) = COPY $w023 ; CHECK-NEXT: %y:_(s32) = COPY $w124 ; CHECK-NEXT: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y25 ; CHECK-NEXT: $w0 = COPY %cmp(s32)26 ; CHECK-NEXT: RET_ReallyLR implicit $w027 %x:_(s32) = COPY $w028 %y:_(s32) = COPY $w129 %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y30 %mask:_(s32) = G_CONSTANT i32 131 %and:_(s32) = G_AND %cmp(s32), %mask32 $w0 = COPY %and(s32)33 RET_ReallyLR implicit $w034 35...36---37name: remove_and_all_ones_mask38legalized: true39tracksRegLiveness: true40body: |41 bb.0:42 liveins: $w0, $w1, $w243 ; -1 is all ones. Therefore z & -1 = z. Remove the G_AND.44 ; CHECK-LABEL: name: remove_and_all_ones_mask45 ; CHECK: liveins: $w0, $w1, $w246 ; CHECK-NEXT: {{ $}}47 ; CHECK-NEXT: %x:_(s32) = COPY $w048 ; CHECK-NEXT: %y:_(s32) = COPY $w149 ; CHECK-NEXT: %z:_(s32) = COPY $w250 ; CHECK-NEXT: $w0 = COPY %z(s32)51 ; CHECK-NEXT: RET_ReallyLR implicit $w052 %x:_(s32) = COPY $w053 %y:_(s32) = COPY $w154 %z:_(s32) = COPY $w255 %mask:_(s32) = G_CONSTANT i32 -156 %and:_(s32) = G_AND %z(s32), %mask57 $w0 = COPY %and(s32)58 RET_ReallyLR implicit $w059 60...61---62name: remove_and_all_ones_zext63legalized: true64tracksRegLiveness: true65body: |66 bb.0:67 liveins: $w0, $w1, $w268 ; %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 this70 ; value.71 ; Therefore, zext(z) & 4294967295 == z. Remove the G_AND.72 ; CHECK-LABEL: name: remove_and_all_ones_zext73 ; CHECK: liveins: $w0, $w1, $w274 ; CHECK-NEXT: {{ $}}75 ; CHECK-NEXT: %x:_(s32) = COPY $w076 ; CHECK-NEXT: %y:_(s32) = COPY $w177 ; CHECK-NEXT: %z:_(s32) = COPY $w278 ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %z(s32)79 ; CHECK-NEXT: $x0 = COPY %ext(s64)80 ; CHECK-NEXT: RET_ReallyLR implicit $x081 %x:_(s32) = COPY $w082 %y:_(s32) = COPY $w183 %z:_(s32) = COPY $w284 %ext:_(s64) = G_ZEXT %z85 %mask:_(s64) = G_CONSTANT i64 429496729586 %and:_(s64) = G_AND %ext(s64), %mask87 $x0 = COPY %and(s64)88 RET_ReallyLR implicit $x089 90...91---92name: remove_and_all_ones_anyext93legalized: true94tracksRegLiveness: true95body: |96 bb.0:97 liveins: $w0, $w1, $w298 ; This is the same as the zext case.99 ; CHECK-LABEL: name: remove_and_all_ones_anyext100 ; CHECK: liveins: $w0, $w1, $w2101 ; CHECK-NEXT: {{ $}}102 ; CHECK-NEXT: %x:_(s32) = COPY $w0103 ; CHECK-NEXT: %y:_(s32) = COPY $w1104 ; CHECK-NEXT: %z:_(s32) = COPY $w2105 ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %z(s32)106 ; CHECK-NEXT: $x0 = COPY %ext(s64)107 ; CHECK-NEXT: RET_ReallyLR implicit $x0108 %x:_(s32) = COPY $w0109 %y:_(s32) = COPY $w1110 %z:_(s32) = COPY $w2111 %ext:_(s64) = G_ZEXT %z112 %mask:_(s64) = G_CONSTANT i64 4294967295113 %and:_(s64) = G_AND %ext(s64), %mask114 $x0 = COPY %and(s64)115 RET_ReallyLR implicit $x0116 117...118---119name: dont_remove_all_ones_sext120legalized: true121tracksRegLiveness: true122body: |123 bb.0:124 liveins: $w0, $w1, $w2125 ; We don't know if the sign bit is set on %z. So, the value in %ext may have126 ; higher bits set than 4294967295.127 ; CHECK-LABEL: name: dont_remove_all_ones_sext128 ; CHECK: liveins: $w0, $w1, $w2129 ; CHECK-NEXT: {{ $}}130 ; CHECK-NEXT: %x:_(s32) = COPY $w0131 ; CHECK-NEXT: %y:_(s32) = COPY $w1132 ; CHECK-NEXT: %z:_(s32) = COPY $w2133 ; CHECK-NEXT: %ext:_(s64) = G_SEXT %z(s32)134 ; CHECK-NEXT: %mask:_(s64) = G_CONSTANT i64 4294967295135 ; CHECK-NEXT: %and:_(s64) = G_AND %ext, %mask136 ; CHECK-NEXT: $x0 = COPY %and(s64)137 ; CHECK-NEXT: RET_ReallyLR implicit $x0138 %x:_(s32) = COPY $w0139 %y:_(s32) = COPY $w1140 %z:_(s32) = COPY $w2141 %ext:_(s64) = G_SEXT %z142 %mask:_(s64) = G_CONSTANT i64 4294967295143 %and:_(s64) = G_AND %ext(s64), %mask144 $x0 = COPY %and(s64)145 RET_ReallyLR implicit $x0146 147...148---149name: remove_and_positive_constant_sext150legalized: true151tracksRegLiveness: true152body: |153 bb.0:154 liveins: $w0, $w1, $w2155 ; We know the sign bit is not set on %z. Therefore,156 ; z = ext = 42 = 000...0101010157 ; mask = 0000...0111111158 ; So z & mask == z159 ; CHECK-LABEL: name: remove_and_positive_constant_sext160 ; CHECK: liveins: $w0, $w1, $w2161 ; CHECK-NEXT: {{ $}}162 ; CHECK-NEXT: %x:_(s32) = COPY $w0163 ; CHECK-NEXT: %y:_(s32) = COPY $w1164 ; CHECK-NEXT: %z:_(s32) = G_CONSTANT i32 42165 ; CHECK-NEXT: %ext:_(s64) = G_SEXT %z(s32)166 ; CHECK-NEXT: $x0 = COPY %ext(s64)167 ; CHECK-NEXT: RET_ReallyLR implicit $x0168 %x:_(s32) = COPY $w0169 %y:_(s32) = COPY $w1170 %z:_(s32) = G_CONSTANT i32 42171 %ext:_(s64) = G_SEXT %z172 %mask:_(s64) = G_CONSTANT i64 63173 %and:_(s64) = G_AND %ext(s64), %mask174 $x0 = COPY %and(s64)175 RET_ReallyLR implicit $x0176 177...178---179name: not_a_mask180legalized: true181tracksRegLiveness: true182body: |183 bb.0:184 liveins: $w0, $w1185 ; 6 is not a mask, so we should still have the G_AND.186 ; CHECK-LABEL: name: not_a_mask187 ; CHECK: liveins: $w0, $w1188 ; CHECK-NEXT: {{ $}}189 ; CHECK-NEXT: %x:_(s32) = COPY $w0190 ; CHECK-NEXT: %y:_(s32) = COPY $w1191 ; CHECK-NEXT: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y192 ; CHECK-NEXT: %mask:_(s32) = G_CONSTANT i32 6193 ; CHECK-NEXT: %and:_(s32) = G_AND %cmp, %mask194 ; CHECK-NEXT: $w0 = COPY %and(s32)195 ; CHECK-NEXT: RET_ReallyLR implicit $w0196 %x:_(s32) = COPY $w0197 %y:_(s32) = COPY $w1198 %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y199 %mask:_(s32) = G_CONSTANT i32 6200 %and:_(s32) = G_AND %cmp(s32), %mask201 $w0 = COPY %and(s32)202 RET_ReallyLR implicit $w0203 204...205---206name: unknown_val207legalized: true208tracksRegLiveness: true209body: |210 bb.0:211 liveins: $w0, $w1, $w2212 ; We don't know what's in $w2, so we can't remove the G_AND without a mask213 ; that fills every bit in the type.214 ; CHECK-LABEL: name: unknown_val215 ; CHECK: liveins: $w0, $w1, $w2216 ; CHECK-NEXT: {{ $}}217 ; CHECK-NEXT: %x:_(s32) = COPY $w0218 ; CHECK-NEXT: %y:_(s32) = COPY $w1219 ; CHECK-NEXT: %z:_(s32) = COPY $w2220 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 32221 ; CHECK-NEXT: %and:_(s32) = G_AND %z, %one222 ; CHECK-NEXT: $w0 = COPY %and(s32)223 ; CHECK-NEXT: RET_ReallyLR implicit $w0224 %x:_(s32) = COPY $w0225 %y:_(s32) = COPY $w1226 %z:_(s32) = COPY $w2227 %one:_(s32) = G_CONSTANT i32 32228 %and:_(s32) = G_AND %z(s32), %one229 $w0 = COPY %and(s32)230 RET_ReallyLR implicit $w0231...232---233name: remove_and_assert_zext234legalized: true235tracksRegLiveness: true236body: |237 bb.0:238 liveins: $w0239 ; G_ASSERT_ZEXT communicates that only the bottom 8 bits of %x can be set.240 ; So, the G_AND can be removed.241 242 ; CHECK-LABEL: name: remove_and_assert_zext243 ; CHECK: liveins: $w0244 ; CHECK-NEXT: {{ $}}245 ; CHECK-NEXT: %x:_(s32) = COPY $w0246 ; CHECK-NEXT: %assert_zext:_(s32) = G_ASSERT_ZEXT %x, 8247 ; CHECK-NEXT: $w0 = COPY %assert_zext(s32)248 ; CHECK-NEXT: RET_ReallyLR implicit $w0249 %x:_(s32) = COPY $w0250 %assert_zext:_(s32) = G_ASSERT_ZEXT %x(s32), 8251 %mask:_(s32) = G_CONSTANT i32 255252 %and:_(s32) = G_AND %assert_zext(s32), %mask253 $w0 = COPY %and(s32)254 RET_ReallyLR implicit $w0255...256---257name: dont_remove_and_assert_zext_wrong_mask258legalized: true259tracksRegLiveness: true260body: |261 bb.0:262 liveins: $w0263 ; The mask here is for 8 bits, not 16.264 265 ; CHECK-LABEL: name: dont_remove_and_assert_zext_wrong_mask266 ; CHECK: liveins: $w0267 ; CHECK-NEXT: {{ $}}268 ; CHECK-NEXT: %x:_(s32) = COPY $w0269 ; CHECK-NEXT: %assert_zext:_(s32) = G_ASSERT_ZEXT %x, 16270 ; CHECK-NEXT: %mask:_(s32) = G_CONSTANT i32 255271 ; CHECK-NEXT: %and:_(s32) = G_AND %assert_zext, %mask272 ; CHECK-NEXT: $w0 = COPY %and(s32)273 ; CHECK-NEXT: RET_ReallyLR implicit $w0274 %x:_(s32) = COPY $w0275 %assert_zext:_(s32) = G_ASSERT_ZEXT %x(s32), 16276 %mask:_(s32) = G_CONSTANT i32 255277 %and:_(s32) = G_AND %assert_zext(s32), %mask278 $w0 = COPY %and(s32)279 RET_ReallyLR implicit $w0280