422 lines · plain
1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py2# RUN: llc -mtriple aarch64-unknown-unknown -run-pass=instruction-select -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s3#4# Check folding a G_SHL into a G_BRCOND which has been matched as a TB(N)Z.5...6---7name: fold_shl8alignment: 49legalized: true10regBankSelected: true11body: |12 ; CHECK-LABEL: name: fold_shl13 ; CHECK: bb.0:14 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)15 ; CHECK-NEXT: liveins: $x016 ; CHECK-NEXT: {{ $}}17 ; CHECK-NEXT: %copy:gpr64all = COPY $x018 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %copy.sub_3219 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]20 ; CHECK-NEXT: TBNZW [[COPY1]], 2, %bb.121 ; CHECK-NEXT: B %bb.022 ; CHECK-NEXT: {{ $}}23 ; CHECK-NEXT: bb.1:24 ; CHECK-NEXT: RET_ReallyLR25 bb.0:26 successors: %bb.0, %bb.127 liveins: $x028 %copy:gpr(s64) = COPY $x029 %bit:gpr(s64) = G_CONSTANT i64 830 %zero:gpr(s64) = G_CONSTANT i64 031 32 ; tbnz (shl x, 1), 3 == tbnz x, 233 %fold_cst:gpr(s64) = G_CONSTANT i64 134 %fold_me:gpr(s64) = G_SHL %copy, %fold_cst35 36 %and:gpr(s64) = G_AND %fold_me, %bit37 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero38 G_BRCOND %cmp, %bb.139 G_BR %bb.040 bb.1:41 RET_ReallyLR42...43---44name: dont_fold_shl_145alignment: 446legalized: true47regBankSelected: true48body: |49 ; CHECK-LABEL: name: dont_fold_shl_150 ; CHECK: bb.0:51 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)52 ; CHECK-NEXT: liveins: $x053 ; CHECK-NEXT: {{ $}}54 ; CHECK-NEXT: %copy:gpr64 = COPY $x055 ; CHECK-NEXT: %fold_me:gpr64 = UBFMXri %copy, 59, 5856 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %fold_me.sub_3257 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]58 ; CHECK-NEXT: TBNZW [[COPY1]], 3, %bb.159 ; CHECK-NEXT: B %bb.060 ; CHECK-NEXT: {{ $}}61 ; CHECK-NEXT: bb.1:62 ; CHECK-NEXT: RET_ReallyLR63 bb.0:64 successors: %bb.0, %bb.165 liveins: $x066 %copy:gpr(s64) = COPY $x067 %bit:gpr(s64) = G_CONSTANT i64 868 %zero:gpr(s64) = G_CONSTANT i64 069 70 ; 5 > 3, so we cannot do the transformation as above.71 %fold_cst:gpr(s64) = G_CONSTANT i64 572 %fold_me:gpr(s64) = G_SHL %copy, %fold_cst73 74 %and:gpr(s64) = G_AND %fold_me, %bit75 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero76 G_BRCOND %cmp, %bb.177 G_BR %bb.078 bb.1:79 RET_ReallyLR80...81---82name: dont_fold_shl_283alignment: 484legalized: true85regBankSelected: true86body: |87 ; CHECK-LABEL: name: dont_fold_shl_288 ; CHECK: bb.0:89 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)90 ; CHECK-NEXT: liveins: $x091 ; CHECK-NEXT: {{ $}}92 ; CHECK-NEXT: %copy:gpr64 = COPY $x093 ; CHECK-NEXT: %fold_cst:gpr64 = MOVi64imm -594 ; CHECK-NEXT: %fold_me:gpr64 = LSLVXr %copy, %fold_cst95 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %fold_me.sub_3296 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]97 ; CHECK-NEXT: TBNZW [[COPY1]], 3, %bb.198 ; CHECK-NEXT: B %bb.099 ; CHECK-NEXT: {{ $}}100 ; CHECK-NEXT: bb.1:101 ; CHECK-NEXT: RET_ReallyLR102 bb.0:103 successors: %bb.0, %bb.1104 liveins: $x0105 %copy:gpr(s64) = COPY $x0106 %bit:gpr(s64) = G_CONSTANT i64 8107 %zero:gpr(s64) = G_CONSTANT i64 0108 109 ; Same case as above, except we wrap around.110 %fold_cst:gpr(s64) = G_CONSTANT i64 -5111 %fold_me:gpr(s64) = G_SHL %copy, %fold_cst112 113 %and:gpr(s64) = G_AND %fold_me, %bit114 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero115 G_BRCOND %cmp, %bb.1116 G_BR %bb.0117 bb.1:118 RET_ReallyLR119 120...121---122name: dont_fold_shl_3123alignment: 4124legalized: true125regBankSelected: true126body: |127 ; CHECK-LABEL: name: dont_fold_shl_3128 ; CHECK: bb.0:129 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)130 ; CHECK-NEXT: liveins: $x0131 ; CHECK-NEXT: {{ $}}132 ; CHECK-NEXT: %copy:gpr64 = COPY $x0133 ; CHECK-NEXT: %shl:gpr64 = UBFMXri %copy, 62, 61134 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %shl.sub_32135 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]136 ; CHECK-NEXT: TBNZW [[COPY1]], 3, %bb.1137 ; CHECK-NEXT: B %bb.0138 ; CHECK-NEXT: {{ $}}139 ; CHECK-NEXT: bb.1:140 ; CHECK-NEXT: %second_use:gpr64sp = ORRXri %shl, 8000141 ; CHECK-NEXT: $x0 = COPY %second_use142 ; CHECK-NEXT: RET_ReallyLR implicit $x0143 bb.0:144 successors: %bb.0, %bb.1145 liveins: $x0146 %copy:gpr(s64) = COPY $x0147 %bit:gpr(s64) = G_CONSTANT i64 8148 %zero:gpr(s64) = G_CONSTANT i64 0149 %fold_cst:gpr(s64) = G_CONSTANT i64 2150 151 ; Don't walk past the G_SHL when it's used more than once.152 %shl:gpr(s64) = G_SHL %copy, %fold_cst153 %and:gpr(s64) = G_AND %shl, %bit154 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero155 G_BRCOND %cmp, %bb.1156 G_BR %bb.0157 158 bb.1:159 %second_use:gpr(s64) = G_OR %shl, %bit160 $x0 = COPY %second_use161 RET_ReallyLR implicit $x0162 163...164---165name: fold_ashr_in_range166alignment: 4167legalized: true168regBankSelected: true169body: |170 ; CHECK-LABEL: name: fold_ashr_in_range171 ; CHECK: bb.0:172 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)173 ; CHECK-NEXT: liveins: $x0174 ; CHECK-NEXT: {{ $}}175 ; CHECK-NEXT: %copy:gpr64all = COPY $x0176 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %copy.sub_32177 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]178 ; CHECK-NEXT: TBNZW [[COPY1]], 4, %bb.1179 ; CHECK-NEXT: B %bb.0180 ; CHECK-NEXT: {{ $}}181 ; CHECK-NEXT: bb.1:182 ; CHECK-NEXT: RET_ReallyLR183 bb.0:184 successors: %bb.0, %bb.1185 liveins: $x0186 %copy:gpr(s64) = COPY $x0187 %bit:gpr(s64) = G_CONSTANT i64 8188 %zero:gpr(s64) = G_CONSTANT i64 0189 190 ; tb(n)z (ashr x, c), b == tbz(x, b + c) when b+c <= the size of the type.191 ; In this case, we should get 1 + 3 = 4 as the bit number.192 %fold_cst:gpr(s64) = G_CONSTANT i64 1193 %fold_me:gpr(s64) = G_ASHR %copy, %fold_cst194 195 %and:gpr(s64) = G_AND %fold_me, %bit196 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero197 G_BRCOND %cmp, %bb.1198 G_BR %bb.0199 bb.1:200 RET_ReallyLR201 202...203---204name: fold_ashr_msb_1205alignment: 4206legalized: true207regBankSelected: true208body: |209 ; CHECK-LABEL: name: fold_ashr_msb_1210 ; CHECK: bb.0:211 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)212 ; CHECK-NEXT: liveins: $x0213 ; CHECK-NEXT: {{ $}}214 ; CHECK-NEXT: %copy:gpr32 = COPY $w0215 ; CHECK-NEXT: TBNZW %copy, 31, %bb.1216 ; CHECK-NEXT: B %bb.0217 ; CHECK-NEXT: {{ $}}218 ; CHECK-NEXT: bb.1:219 ; CHECK-NEXT: RET_ReallyLR220 bb.0:221 successors: %bb.0, %bb.1222 liveins: $x0223 %copy:gpr(s32) = COPY $w0224 %bit:gpr(s32) = G_CONSTANT i32 8225 %zero:gpr(s32) = G_CONSTANT i32 0226 227 ; We should get a TBNZW with a 31 as the bit.228 %fold_cst:gpr(s32) = G_CONSTANT i32 1234229 %fold_me:gpr(s32) = G_ASHR %copy, %fold_cst230 231 %and:gpr(s32) = G_AND %fold_me, %bit232 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero233 G_BRCOND %cmp, %bb.1234 G_BR %bb.0235 bb.1:236 RET_ReallyLR237 238...239---240name: fold_ashr_msb_2241alignment: 4242legalized: true243regBankSelected: true244body: |245 ; CHECK-LABEL: name: fold_ashr_msb_2246 ; CHECK: bb.0:247 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)248 ; CHECK-NEXT: liveins: $x0249 ; CHECK-NEXT: {{ $}}250 ; CHECK-NEXT: %copy:gpr64 = COPY $x0251 ; CHECK-NEXT: TBNZX %copy, 63, %bb.1252 ; CHECK-NEXT: B %bb.0253 ; CHECK-NEXT: {{ $}}254 ; CHECK-NEXT: bb.1:255 ; CHECK-NEXT: RET_ReallyLR256 bb.0:257 successors: %bb.0, %bb.1258 liveins: $x0259 %copy:gpr(s64) = COPY $x0260 %bit:gpr(s64) = G_CONSTANT i64 8261 %zero:gpr(s64) = G_CONSTANT i64 0262 263 ; We should get a TBNZX with a 63 as the bit.264 %fold_cst:gpr(s64) = G_CONSTANT i64 1234265 %fold_me:gpr(s64) = G_ASHR %copy, %fold_cst266 267 %and:gpr(s64) = G_AND %fold_me, %bit268 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero269 G_BRCOND %cmp, %bb.1270 G_BR %bb.0271 bb.1:272 RET_ReallyLR273 274...275---276name: fold_lshr277alignment: 4278legalized: true279regBankSelected: true280body: |281 ; CHECK-LABEL: name: fold_lshr282 ; CHECK: bb.0:283 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)284 ; CHECK-NEXT: liveins: $x0285 ; CHECK-NEXT: {{ $}}286 ; CHECK-NEXT: %copy:gpr32 = COPY $w0287 ; CHECK-NEXT: TBNZW %copy, 4, %bb.1288 ; CHECK-NEXT: B %bb.0289 ; CHECK-NEXT: {{ $}}290 ; CHECK-NEXT: bb.1:291 ; CHECK-NEXT: RET_ReallyLR292 bb.0:293 successors: %bb.0, %bb.1294 liveins: $x0295 %copy:gpr(s32) = COPY $w0296 %bit:gpr(s32) = G_CONSTANT i32 8297 %zero:gpr(s32) = G_CONSTANT i32 0298 299 ; We should get 4 as the test bit.300 %fold_cst:gpr(s32) = G_CONSTANT i32 1301 %fold_me:gpr(s32) = G_LSHR %copy, %fold_cst302 303 %and:gpr(s32) = G_AND %fold_me, %bit304 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero305 G_BRCOND %cmp, %bb.1306 G_BR %bb.0307 bb.1:308 RET_ReallyLR309 310...311---312name: fold_lshr_2313alignment: 4314legalized: true315regBankSelected: true316body: |317 ; CHECK-LABEL: name: fold_lshr_2318 ; CHECK: bb.0:319 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)320 ; CHECK-NEXT: liveins: $x0321 ; CHECK-NEXT: {{ $}}322 ; CHECK-NEXT: %copy:gpr64 = COPY $x0323 ; CHECK-NEXT: TBNZX %copy, 32, %bb.1324 ; CHECK-NEXT: B %bb.0325 ; CHECK-NEXT: {{ $}}326 ; CHECK-NEXT: bb.1:327 ; CHECK-NEXT: RET_ReallyLR328 bb.0:329 successors: %bb.0, %bb.1330 liveins: $x0331 %copy:gpr(s64) = COPY $x0332 %bit:gpr(s64) = G_CONSTANT i64 8333 %zero:gpr(s64) = G_CONSTANT i64 0334 335 ; We're testing a s64.336 ; 3 + 29 = 32, which is less than 63, so we can fold.337 %fold_cst:gpr(s64) = G_CONSTANT i64 29338 %fold_me:gpr(s64) = G_LSHR %copy, %fold_cst339 340 %and:gpr(s64) = G_AND %fold_me, %bit341 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero342 G_BRCOND %cmp, %bb.1343 G_BR %bb.0344 bb.1:345 RET_ReallyLR346 347...348---349name: dont_fold_lshr350alignment: 4351legalized: true352regBankSelected: true353body: |354 ; CHECK-LABEL: name: dont_fold_lshr355 ; CHECK: bb.0:356 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)357 ; CHECK-NEXT: liveins: $x0358 ; CHECK-NEXT: {{ $}}359 ; CHECK-NEXT: %copy:gpr32 = COPY $w0360 ; CHECK-NEXT: %fold_cst:gpr32 = MOVi32imm 29361 ; CHECK-NEXT: %fold_me:gpr32 = LSRVWr %copy, %fold_cst362 ; CHECK-NEXT: TBNZW %fold_me, 3, %bb.1363 ; CHECK-NEXT: B %bb.0364 ; CHECK-NEXT: {{ $}}365 ; CHECK-NEXT: bb.1:366 ; CHECK-NEXT: RET_ReallyLR367 bb.0:368 successors: %bb.0, %bb.1369 liveins: $x0370 %copy:gpr(s32) = COPY $w0371 %bit:gpr(s32) = G_CONSTANT i32 8372 %zero:gpr(s32) = G_CONSTANT i32 0373 374 ; We're testing a s32.375 ; 3 + 29 = 32, which is greater than 31, so we don't fold.376 %fold_cst:gpr(s32) = G_CONSTANT i32 29377 %fold_me:gpr(s32) = G_LSHR %copy, %fold_cst378 379 %and:gpr(s32) = G_AND %fold_me, %bit380 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero381 G_BRCOND %cmp, %bb.1382 G_BR %bb.0383 bb.1:384 RET_ReallyLR385 386...387---388name: lshr_negative389alignment: 4390legalized: true391regBankSelected: true392body: |393 ; CHECK-LABEL: name: lshr_negative394 ; CHECK: bb.0:395 ; CHECK-NEXT: successors: %bb.0(0x40000000), %bb.1(0x40000000)396 ; CHECK-NEXT: liveins: $x0397 ; CHECK-NEXT: {{ $}}398 ; CHECK-NEXT: %copy:gpr32 = COPY $w0399 ; CHECK-NEXT: TBNZW %copy, 2, %bb.1400 ; CHECK-NEXT: B %bb.0401 ; CHECK-NEXT: {{ $}}402 ; CHECK-NEXT: bb.1:403 ; CHECK-NEXT: RET_ReallyLR404 bb.0:405 successors: %bb.0, %bb.1406 liveins: $x0407 %copy:gpr(s32) = COPY $w0408 %bit:gpr(s32) = G_CONSTANT i32 8409 %zero:gpr(s32) = G_CONSTANT i32 0410 411 ; Constant becomes very large and wraps around. Since it's larger than the412 ; bit width, that means the LSHR is poison, so we can still fold.413 %fold_cst:gpr(s32) = G_CONSTANT i32 -1414 %fold_me:gpr(s32) = G_LSHR %copy, %fold_cst415 416 %and:gpr(s32) = G_AND %fold_me, %bit417 %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero418 G_BRCOND %cmp, %bb.1419 G_BR %bb.0420 bb.1:421 RET_ReallyLR422