1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2# RUN: llc -mtriple=amdgcn -verify-machineinstrs -run-pass=register-coalescer -o - %s | FileCheck %s 3 4# Test used to crash with message: 5# JoinVals::computeAssignment(unsigned int, (anonymous namespace)::JoinVals &): Assertion `Assignments[ValNo] != -1 && "Bad recursion?"' failed. 6 7# The issue was with processing two operands are parts of the same reg and are 8# used in the same instruction (e.g. inline asm): first is "def early-clobber", 9# while the other is just "def". 10# Register coalescer ran in bad recursion if the early clobbered subreg is 11# second in the following sequence of COPYs. 12 13--- 14name: foo1 15tracksRegLiveness: true 16body: | 17 bb.0: 18 liveins: $vgpr0_vgpr1 19 20 ; CHECK-LABEL: name: foo1 21 ; CHECK: liveins: $vgpr0_vgpr1 22 ; CHECK-NEXT: {{ $}} 23 ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VS_32 */, def undef %2.sub0, 1835019 /* regdef-ec:VS_32 */, def undef early-clobber %2.sub1 24 ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 25 ; CHECK-NEXT: S_ENDPGM 0 26 INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def %0:vgpr_32, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %1:vgpr_32 27 undef %2.sub0:vreg_64 = COPY killed %0 28 %2.sub1:vreg_64 = COPY killed %1 29 FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 30 S_ENDPGM 0 31 32... 33 34--- 35name: foo2 36tracksRegLiveness: true 37body: | 38 bb.0: 39 liveins: $vgpr0_vgpr1 40 41 ; CHECK-LABEL: name: foo2 42 ; CHECK: liveins: $vgpr0_vgpr1 43 ; CHECK-NEXT: {{ $}} 44 ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VS_32 */, def undef early-clobber %2.sub1, 1835018 /* regdef:VS_32 */, def undef %2.sub0 45 ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 46 ; CHECK-NEXT: S_ENDPGM 0 47 INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %1:vgpr_32, 1835018 /* regdef:VGPR_32 */, def %0:vgpr_32 48 undef %2.sub0:vreg_64 = COPY killed %0 49 %2.sub1:vreg_64 = COPY killed %1 50 FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 51 S_ENDPGM 0 52 53... 54 55--- 56name: foo3 57tracksRegLiveness: true 58body: | 59 bb.0: 60 liveins: $vgpr0_vgpr1 61 62 ; CHECK-LABEL: name: foo3 63 ; CHECK: liveins: $vgpr0_vgpr1 64 ; CHECK-NEXT: {{ $}} 65 ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VS_32 */, def undef %2.sub0, 1835019 /* regdef-ec:VS_32 */, def undef early-clobber %2.sub1 66 ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 67 ; CHECK-NEXT: S_ENDPGM 0 68 INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def %1:vgpr_32, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %0:vgpr_32 69 undef %2.sub0:vreg_64 = COPY killed %1 70 %2.sub1:vreg_64 = COPY killed %0 71 FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 72 S_ENDPGM 0 73 74... 75 76--- 77name: foo4 78tracksRegLiveness: true 79body: | 80 bb.0: 81 liveins: $vgpr0_vgpr1 82 83 ; CHECK-LABEL: name: foo4 84 ; CHECK: liveins: $vgpr0_vgpr1 85 ; CHECK-NEXT: {{ $}} 86 ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VS_32 */, def undef early-clobber %2.sub1, 1835018 /* regdef:VS_32 */, def undef %2.sub0 87 ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 88 ; CHECK-NEXT: S_ENDPGM 0 89 INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %0:vgpr_32, 1835018 /* regdef:VGPR_32 */, def %1:vgpr_32 90 undef %2.sub0:vreg_64 = COPY killed %1 91 %2.sub1:vreg_64 = COPY killed %0 92 FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64)) 93 S_ENDPGM 0 94 95... 96