1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2# RUN: llc %s -start-before register-coalescer -mtriple=arm-apple-ios -stop-after machine-scheduler -o - -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--- 49name: main 50alignment: 1 51tracksRegLiveness: true 52frameInfo: 53 maxAlignment: 1 54machineFunctionInfo: {} 55body: | 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 /* CC::al */, $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... 82