[llvm] f91b6a0 - PowerPC: Fix VSX swap removal crash on an undef register (#216714)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 12:56:04 PDT 2026
Author: Matt Arsenault
Date: 2026-09-08T21:55:59+02:00
New Revision: f91b6a0319fd900cb6e665fc8f8dcc5c1a801e4c
URL: https://github.com/llvm/llvm-project/commit/f91b6a0319fd900cb6e665fc8f8dcc5c1a801e4c
DIFF: https://github.com/llvm/llvm-project/commit/f91b6a0319fd900cb6e665fc8f8dcc5c1a801e4c.diff
LOG: PowerPC: Fix VSX swap removal crash on an undef register (#216714)
formWebs walks each vector-register use and unions its equivalence class
with that of its defining instruction, which it requires to be present
in the swap map. A use of an undef register has no defining instruction, so
the web formation crashed. Treat it like a physical-register mention so the
web is conservatively rejected.
Found by AI while working on something else.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
Added:
llvm/test/CodeGen/PowerPC/vsx-swap-removal-undef.mir
Modified:
llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp b/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
index 85a90992816e5..49b9ccf4460cd 100644
--- a/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
+++ b/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
@@ -79,6 +79,7 @@ struct PPCVSXSwapEntry {
unsigned int SpecialHandling : 3;
unsigned int WebRejected : 1;
unsigned int WillRemove : 1;
+ unsigned int HasUnanalyzableDef : 1;
};
enum SHValues {
@@ -611,7 +612,12 @@ void PPCVSXSwapRemoval::formWebs() {
if (!MO.isUse())
continue;
- MachineInstr* DefMI = MRI->getVRegDef(Reg);
+ MachineInstr *DefMI = MRI->getVRegDef(Reg);
+ if (!DefMI) {
+ SwapVector[EntryIdx].HasUnanalyzableDef = 1;
+ continue;
+ }
+
assert(SwapMap.contains(DefMI) &&
"Inconsistency: def of vector reg not found in swap map!");
int DefIdx = SwapMap[DefMI];
@@ -647,14 +653,14 @@ void PPCVSXSwapRemoval::recordUnoptimizableWebs() {
// permuted region.
if (SwapVector[EntryIdx].MentionsPhysVR ||
SwapVector[EntryIdx].MentionsPartialVR ||
+ SwapVector[EntryIdx].HasUnanalyzableDef ||
!(SwapVector[EntryIdx].IsSwappable || SwapVector[EntryIdx].IsSwap)) {
SwapVector[Repr].WebRejected = 1;
- LLVM_DEBUG(
- dbgs() << format("Web %d rejected for physreg, partial reg, or not "
- "swap[pable]\n",
- Repr));
+ LLVM_DEBUG(dbgs() << format("Web %d rejected for physreg, partial reg, "
+ "unanalyzable def, or not swap[pable]\n",
+ Repr));
LLVM_DEBUG(dbgs() << " in " << EntryIdx << ": ");
LLVM_DEBUG(SwapVector[EntryIdx].VSEMI->dump());
LLVM_DEBUG(dbgs() << "\n");
@@ -1007,6 +1013,8 @@ LLVM_DUMP_METHOD void PPCVSXSwapRemoval::dumpSwapVector() {
dbgs() << "physreg ";
if (SwapVector[EntryIdx].MentionsPartialVR)
dbgs() << "partialreg ";
+ if (SwapVector[EntryIdx].HasUnanalyzableDef)
+ dbgs() << "unanalyzabledef ";
if (SwapVector[EntryIdx].IsSwappable) {
dbgs() << "swappable ";
diff --git a/llvm/test/CodeGen/PowerPC/vsx-swap-removal-undef.mir b/llvm/test/CodeGen/PowerPC/vsx-swap-removal-undef.mir
new file mode 100644
index 0000000000000..22ee618e808be
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/vsx-swap-removal-undef.mir
@@ -0,0 +1,21 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -run-pass=ppc-vsx-swaps -o - %s | FileCheck %s
+
+# VSX swap removal must not crash when a vector operand is an undef register
+# with no defining instruction.
+---
+name: vsxswap_undef
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $v3
+ ; CHECK-LABEL: name: vsxswap_undef
+ ; CHECK: liveins: $v3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[VADDUWM:%[0-9]+]]:vrrc = VADDUWM undef %1:vrrc, $v3
+ ; CHECK-NEXT: $v2 = COPY [[VADDUWM]]
+ ; CHECK-NEXT: BLR implicit $lr, implicit $rm, implicit $v2
+ %1:vrrc = VADDUWM undef %0:vrrc, $v3
+ $v2 = COPY %1
+ BLR implicit $lr, implicit $rm, implicit $v2
+...
More information about the llvm-commits
mailing list