|
| 1 | +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py |
| 2 | +# RUN: llc %s -start-before simple-register-coalescing -mtriple=arm-apple-ios -stop-after machine-scheduler -o - -arm-enable-subreg-liveness -verify-machineinstrs | FileCheck %s |
| 3 | + |
| 4 | +# Check that when we merge live-ranges that imply offseting |
| 5 | +# the definition of a subregister by some other subreg index, |
| 6 | +# we take that new index into account while updating the subrange. |
| 7 | +# |
| 8 | +# For this specific test case, the coalescer is going to get rid |
| 9 | +# of `%5.dsub_1:dtriple = COPY %4.dsub_3` by aligning |
| 10 | +# %5.dsub_1:<3 x s64> with %4.dsub_3:<4 x s64>. |
| 11 | +# This is done by moving to a bigger register class <5 x s64> |
| 12 | +# and offseting %5 definitions with a new subregidx: |
| 13 | +# NewVar: <5 x s64> dsub_0 dsub_1 dsub_2 dsub_3 dsub_4 |
| 14 | +# %4: <4 x s64> dsub_0 dsub_1 dsub_2 dsub_3 |
| 15 | +# %5: <3 x s64> <==offset===> dsub_0 dsub_1 dsub_2 |
| 16 | +# |
| 17 | +# In other %5.dsub_0 needs to be mapped to NewVar.dsub_2, %5.dsub_1 |
| 18 | +# to NewVar.dsub_3 and so on. So essentially we are offseting %5 by |
| 19 | +# dsub_2. |
| 20 | +# |
| 21 | +# When updating the live-ranges, the register coalescer actually |
| 22 | +# has not rewritten the original code, so we need to fake the |
| 23 | +# rewrite to do that update. |
| 24 | +# This used to be wrong and this test was failling with a machine |
| 25 | +# verifier error: No live segment at def. |
| 26 | +# |
| 27 | +# The test case runs through the coalescer *and* the scheduler, just |
| 28 | +# to force the live intervals to be carried around so that the verifier |
| 29 | +# gets a chance to verify those. If we were to just run the coalescer, |
| 30 | +# the live intervals would be dropped before running the verifier since |
| 31 | +# no other pass would need that analysis around. |
| 32 | +# |
| 33 | +# Note: The test case looks slightly more complicated than just the |
| 34 | +# offseting part. That's because the bug needs three things to |
| 35 | +# trigger: |
| 36 | +# 1. Overlapping subreg lanes: here, dsub0 == <ssub0, ssub1> |
| 37 | +# 2. Tuple registers with a possibility to coalesce the subreg index: |
| 38 | +# here, what we explain with %5.dsub_1 == %4.dsub_3 |
| 39 | +# 3. Subreg liveness enabled. |
| 40 | +# #1 is required to trigger the splitting of subranges that implies |
| 41 | +# looking at the IR to decide what is alive and what is not. |
| 42 | +# #2 is what produces the IR to be out-of-synce with what the reg coalescer |
| 43 | +# maintains for the live-ranges information. |
| 44 | +# #3 is, well, the problem has to do with subranges updates! |
| 45 | +# |
| 46 | +# In the end, the expected result is to have all the variables |
| 47 | +# being coalesced in one big (qqqq) variable. |
| 48 | +--- |
| 49 | +name: main |
| 50 | +alignment: 1 |
| 51 | +tracksRegLiveness: true |
| 52 | +frameInfo: |
| 53 | + maxAlignment: 1 |
| 54 | +machineFunctionInfo: {} |
| 55 | +body: | |
| 56 | + bb.0: |
| 57 | + liveins: $d2, $s1, $d4 |
| 58 | +
|
| 59 | +
|
| 60 | + ; CHECK-LABEL: name: main |
| 61 | + ; CHECK: liveins: $d2, $s1, $d4 |
| 62 | + ; CHECK: undef %4.dsub_0:qqqqpr_with_ssub_4 = COPY $d4 |
| 63 | + ; CHECK: %4.ssub_4:qqqqpr_with_ssub_4 = COPY $s1 |
| 64 | + ; CHECK: %4.dsub_1:qqqqpr_with_ssub_4 = COPY $d2 |
| 65 | + ; CHECK: %4.dsub_3:qqqqpr_with_ssub_4 = COPY %4.dsub_1 |
| 66 | + ; CHECK: KILL implicit-def %4.dsub_2, implicit %4.qqsub_0 |
| 67 | + ; CHECK: %4.dsub_4:qqqqpr_with_ssub_4 = COPY %4.dsub_1 |
| 68 | + ; CHECK: tBX_RET 14, $noreg, implicit %4.ssub_4_ssub_5_ssub_6_ssub_7_ssub_8_ssub_9 |
| 69 | + %3:dpr_vfp2 = COPY $d4 |
| 70 | + undef %0.ssub_0:dpr_vfp2 = COPY $s1 |
| 71 | + %1:dpr_vfp2 = COPY $d2 |
| 72 | + undef %4.dsub_0:dquad = COPY %3 |
| 73 | + %4.dsub_1:dquad = COPY %1 |
| 74 | + %4.dsub_2:dquad = COPY %0 |
| 75 | + %4.dsub_3:dquad = COPY %1 |
| 76 | + KILL implicit-def undef %5.dsub_0:dtriple, implicit %4 |
| 77 | + %5.dsub_1:dtriple = COPY %4.dsub_3 |
| 78 | + %5.dsub_2:dtriple = COPY %1 |
| 79 | + tBX_RET 14, $noreg, implicit %5 |
| 80 | +
|
| 81 | +... |
0 commit comments