diff options
Diffstat (limited to 'llvm/test/CodeGen/ARM')
| -rw-r--r-- | llvm/test/CodeGen/ARM/regcoal-invalid-subrange-update.mir | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/ARM/regcoal-invalid-subrange-update.mir b/llvm/test/CodeGen/ARM/regcoal-invalid-subrange-update.mir new file mode 100644 index 00000000000..ef1bfa652ec --- /dev/null +++ b/llvm/test/CodeGen/ARM/regcoal-invalid-subrange-update.mir @@ -0,0 +1,81 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# 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 + +# Check that when we merge live-ranges that imply offseting +# the definition of a subregister by some other subreg index, +# we take that new index into account while updating the subrange. +# +# For this specific test case, the coalescer is going to get rid +# of `%5.dsub_1:dtriple = COPY %4.dsub_3` by aligning +# %5.dsub_1:<3 x s64> with %4.dsub_3:<4 x s64>. +# This is done by moving to a bigger register class <5 x s64> +# and offseting %5 definitions with a new subregidx: +# NewVar: <5 x s64> dsub_0 dsub_1 dsub_2 dsub_3 dsub_4 +# %4: <4 x s64> dsub_0 dsub_1 dsub_2 dsub_3 +# %5: <3 x s64> <==offset===> dsub_0 dsub_1 dsub_2 +# +# In other %5.dsub_0 needs to be mapped to NewVar.dsub_2, %5.dsub_1 +# to NewVar.dsub_3 and so on. So essentially we are offseting %5 by +# dsub_2. +# +# When updating the live-ranges, the register coalescer actually +# has not rewritten the original code, so we need to fake the +# rewrite to do that update. +# This used to be wrong and this test was failling with a machine +# verifier error: No live segment at def. +# +# The test case runs through the coalescer *and* the scheduler, just +# to force the live intervals to be carried around so that the verifier +# gets a chance to verify those. If we were to just run the coalescer, +# the live intervals would be dropped before running the verifier since +# no other pass would need that analysis around. +# +# Note: The test case looks slightly more complicated than just the +# offseting part. That's because the bug needs three things to +# trigger: +# 1. Overlapping subreg lanes: here, dsub0 == <ssub0, ssub1> +# 2. Tuple registers with a possibility to coalesce the subreg index: +# here, what we explain with %5.dsub_1 == %4.dsub_3 +# 3. Subreg liveness enabled. +# #1 is required to trigger the splitting of subranges that implies +# looking at the IR to decide what is alive and what is not. +# #2 is what produces the IR to be out-of-synce with what the reg coalescer +# maintains for the live-ranges information. +# #3 is, well, the problem has to do with subranges updates! +# +# In the end, the expected result is to have all the variables +# being coalesced in one big (qqqq) variable. +--- +name: main +alignment: 1 +tracksRegLiveness: true +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0: + liveins: $d2, $s1, $d4 + + + ; CHECK-LABEL: name: main + ; CHECK: liveins: $d2, $s1, $d4 + ; CHECK: undef %4.dsub_0:qqqqpr_with_ssub_4 = COPY $d4 + ; CHECK: %4.ssub_4:qqqqpr_with_ssub_4 = COPY $s1 + ; CHECK: %4.dsub_1:qqqqpr_with_ssub_4 = COPY $d2 + ; CHECK: %4.dsub_3:qqqqpr_with_ssub_4 = COPY %4.dsub_1 + ; CHECK: KILL implicit-def %4.dsub_2, implicit %4.qqsub_0 + ; CHECK: %4.dsub_4:qqqqpr_with_ssub_4 = COPY %4.dsub_1 + ; CHECK: tBX_RET 14, $noreg, implicit %4.ssub_4_ssub_5_ssub_6_ssub_7_ssub_8_ssub_9 + %3:dpr_vfp2 = COPY $d4 + undef %0.ssub_0:dpr_vfp2 = COPY $s1 + %1:dpr_vfp2 = COPY $d2 + undef %4.dsub_0:dquad = COPY %3 + %4.dsub_1:dquad = COPY %1 + %4.dsub_2:dquad = COPY %0 + %4.dsub_3:dquad = COPY %1 + KILL implicit-def undef %5.dsub_0:dtriple, implicit %4 + %5.dsub_1:dtriple = COPY %4.dsub_3 + %5.dsub_2:dtriple = COPY %1 + tBX_RET 14, $noreg, implicit %5 + +... |

