[llvm] 51d33af - [RegisterCoalescer] Fix crash on early clobbered subreg operands.
Daniil Fukalov via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 5 22:42:52 PDT 2022
Author: Daniil Fukalov
Date: 2022-09-06T08:42:37+03:00
New Revision: 51d33afcbe0a81bb8508d5685f38dc9fdb2b60c9
URL: https://github.com/llvm/llvm-project/commit/51d33afcbe0a81bb8508d5685f38dc9fdb2b60c9
DIFF: https://github.com/llvm/llvm-project/commit/51d33afcbe0a81bb8508d5685f38dc9fdb2b60c9.diff
LOG: [RegisterCoalescer] Fix crash on early clobbered subreg operands.
The issue was with processing two subregs of the same reg are used in the same
instruction (e.g. inline asm): "def early-clobber" and other just "def".
Register coalescer ran in bad recursion if the early clobbered subreg is second
in the following sequence of COPYs.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D127136
Added:
llvm/test/CodeGen/AMDGPU/coalescer-early-clobber-subreg.mir
Modified:
llvm/lib/CodeGen/RegisterCoalescer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 21b0ae63184c7..d3716b0d95dfa 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -2743,8 +2743,10 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
}
V.OtherVNI = OtherVNI;
Val &OtherV = Other.Vals[OtherVNI->id];
- // Keep this value, check for conflicts when analyzing OtherVNI.
- if (!OtherV.isAnalyzed())
+ // Keep this value, check for conflicts when analyzing OtherVNI. Avoid
+ // revisiting OtherVNI->id in JoinVals::computeAssignment() below before it
+ // is assigned.
+ if (!OtherV.isAnalyzed() || Other.Assignments[OtherVNI->id] == -1)
return CR_Keep;
// Both sides have been analyzed now.
// Allow overlapping PHI values. Any real interference would show up in a
diff --git a/llvm/test/CodeGen/AMDGPU/coalescer-early-clobber-subreg.mir b/llvm/test/CodeGen/AMDGPU/coalescer-early-clobber-subreg.mir
new file mode 100644
index 0000000000000..a25f22f5f4b67
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/coalescer-early-clobber-subreg.mir
@@ -0,0 +1,95 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -march=amdgcn -verify-machineinstrs -run-pass=simple-register-coalescing -o - %s | FileCheck %s
+
+# Test used to crash with message:
+# JoinVals::computeAssignment(unsigned int, (anonymous namespace)::JoinVals &): Assertion `Assignments[ValNo] != -1 && "Bad recursion?"' failed.
+
+# The issue was with processing two operands are parts of the same reg and are
+# used in the same instruction (e.g. inline asm): first is "def early-clobber",
+# while the other is just "def".
+# Register coalescer ran in bad recursion if the early clobbered subreg is
+# second in the following sequence of COPYs.
+
+---
+name: foo1
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0_vgpr1
+
+ ; CHECK-LABEL: name: foo1
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def undef %2.sub0, 1835019 /* regdef-ec:VGPR_32 */, def undef early-clobber %2.sub1
+ ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ ; CHECK-NEXT: S_ENDPGM 0
+ INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def %0:vgpr_32, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %1:vgpr_32
+ undef %2.sub0:vreg_64 = COPY killed %0
+ %2.sub1:vreg_64 = COPY killed %1
+ FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ S_ENDPGM 0
+
+...
+
+---
+name: foo2
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0_vgpr1
+
+ ; CHECK-LABEL: name: foo2
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def undef early-clobber %2.sub1, 1835018 /* regdef:VGPR_32 */, def undef %2.sub0
+ ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ ; CHECK-NEXT: S_ENDPGM 0
+ INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %1:vgpr_32, 1835018 /* regdef:VGPR_32 */, def %0:vgpr_32
+ undef %2.sub0:vreg_64 = COPY killed %0
+ %2.sub1:vreg_64 = COPY killed %1
+ FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ S_ENDPGM 0
+
+...
+
+---
+name: foo3
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0_vgpr1
+
+ ; CHECK-LABEL: name: foo3
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def undef %2.sub0, 1835019 /* regdef-ec:VGPR_32 */, def undef early-clobber %2.sub1
+ ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ ; CHECK-NEXT: S_ENDPGM 0
+ INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def %1:vgpr_32, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %0:vgpr_32
+ undef %2.sub0:vreg_64 = COPY killed %1
+ %2.sub1:vreg_64 = COPY killed %0
+ FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ S_ENDPGM 0
+
+...
+
+---
+name: foo4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0_vgpr1
+
+ ; CHECK-LABEL: name: foo4
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def undef early-clobber %2.sub1, 1835018 /* regdef:VGPR_32 */, def undef %2.sub0
+ ; CHECK-NEXT: FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ ; CHECK-NEXT: S_ENDPGM 0
+ INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def early-clobber %0:vgpr_32, 1835018 /* regdef:VGPR_32 */, def %1:vgpr_32
+ undef %2.sub0:vreg_64 = COPY killed %1
+ %2.sub1:vreg_64 = COPY killed %0
+ FLAT_STORE_DWORDX2 killed $vgpr0_vgpr1, killed %2, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
+ S_ENDPGM 0
+
+...
More information about the llvm-commits
mailing list