[llvm-branch-commits] [llvm] PowerPC: Fix FMA reassociation crash on an undef multiply operand (PR #216602)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Aug 16 13:28:42 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/216602
Make sure getVRegDef succeeded.
Found by AI while working on something else.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
>From 0f23ed767b54ec7253d7cf9d48cc3824a8710233 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 16 Aug 2026 21:52:56 +0200
Subject: [PATCH] PowerPC: Fix FMA reassociation crash on an undef multiply
operand
Make sure getVRegDef succeeded.
Found by AI while working on something else.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
llvm/lib/CodeGen/TargetRegisterInfo.cpp | 2 +-
llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 2 +-
.../CodeGen/PowerPC/fma-reassoc-undef-mul.mir | 73 +++++++++++++++++++
3 files changed, 75 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/PowerPC/fma-reassoc-undef-mul.mir
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index 351fae37ab891..3b29b0863dd6c 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -631,7 +631,7 @@ Register TargetRegisterInfo::lookThruSingleUseCopyChain(
while (true) {
const MachineInstr *MI = MRI->getVRegDef(SrcReg);
// Found the real definition, return it if it has a single use.
- if (!MI->isCopyLike())
+ if (!MI || !MI->isCopyLike())
return MRI->hasOneNonDBGUse(SrcReg) ? SrcReg : Register();
Register CopySrcReg;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index f415a9776da94..85301285a8237 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -461,7 +461,7 @@ bool PPCInstrInfo::getFMAPatterns(MachineInstr &Root,
MULInstrL = MRI->getVRegDef(MULRegL);
MULInstrR = MRI->getVRegDef(MULRegR);
- return true;
+ return MULInstrL && MULInstrR;
}
return false;
};
diff --git a/llvm/test/CodeGen/PowerPC/fma-reassoc-undef-mul.mir b/llvm/test/CodeGen/PowerPC/fma-reassoc-undef-mul.mir
new file mode 100644
index 0000000000000..e01acc1f07297
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/fma-reassoc-undef-mul.mir
@@ -0,0 +1,73 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -ppc-fma-rp-factor=0.0 -O3 -run-pass=machine-combiner -o - %s | FileCheck %s
+
+# FMA reassociation must not crash when a multiply operand is an undef register
+# with no def. Both multiply operands are checked, so cover each one.
+---
+name: fma_undef_mul_lhs
+tracksRegLiveness: true
+constants:
+ - id: 0
+ value: float f0x2D9299FF
+ alignment: 4
+body: |
+ bb.0:
+ liveins: $f1, $f2, $f3, $f4, $x2
+ ; CHECK-LABEL: name: fma_undef_mul_lhs
+ ; CHECK: liveins: $f1, $f2, $f3, $f4, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:vssrc = COPY $f4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vssrc = COPY $f3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vssrc = COPY $f2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vssrc = COPY $f1
+ ; CHECK-NEXT: [[XSSUBSP:%[0-9]+]]:vssrc = nsz contract reassoc nofpexcept XSSUBSP [[COPY1]], [[COPY]]
+ ; CHECK-NEXT: [[ADDIStocHA8_:%[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
+ ; CHECK-NEXT: [[DFLOADf32_:%[0-9]+]]:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed [[ADDIStocHA8_]] :: (load (s32) from constant-pool)
+ ; CHECK-NEXT: [[XSMADDASP:%[0-9]+]]:vssrc = nsz contract reassoc nofpexcept XSMADDASP killed [[XSSUBSP]], undef %8:vssrc, killed [[DFLOADf32_]]
+ ; CHECK-NEXT: $f1 = COPY [[XSMADDASP]]
+ ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1
+ %3:vssrc = COPY $f4
+ %2:vssrc = COPY $f3
+ %1:vssrc = COPY $f2
+ %0:vssrc = COPY $f1
+ %5:vssrc = nsz contract reassoc nofpexcept XSSUBSP %2, %3
+ %6:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
+ %7:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed %6 :: (load (s32) from constant-pool)
+ %8:vssrc = nsz contract reassoc nofpexcept XSMADDASP killed %5, undef %4:vssrc, killed %7
+ $f1 = COPY %8
+ BLR8 implicit $lr8, implicit $rm, implicit $f1
+...
+---
+name: fma_undef_mul_rhs
+tracksRegLiveness: true
+constants:
+ - id: 0
+ value: float f0x2D9299FF
+ alignment: 4
+body: |
+ bb.0:
+ liveins: $f1, $f2, $f3, $f4, $x2
+ ; CHECK-LABEL: name: fma_undef_mul_rhs
+ ; CHECK: liveins: $f1, $f2, $f3, $f4, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:vssrc = COPY $f4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vssrc = COPY $f3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vssrc = COPY $f2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vssrc = COPY $f1
+ ; CHECK-NEXT: [[XSSUBSP:%[0-9]+]]:vssrc = nsz contract reassoc nofpexcept XSSUBSP [[COPY1]], [[COPY]]
+ ; CHECK-NEXT: [[ADDIStocHA8_:%[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
+ ; CHECK-NEXT: [[DFLOADf32_:%[0-9]+]]:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed [[ADDIStocHA8_]] :: (load (s32) from constant-pool)
+ ; CHECK-NEXT: [[XSMADDASP:%[0-9]+]]:vssrc = nsz contract reassoc nofpexcept XSMADDASP killed [[XSSUBSP]], killed [[DFLOADf32_]], undef %8:vssrc
+ ; CHECK-NEXT: $f1 = COPY [[XSMADDASP]]
+ ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1
+ %3:vssrc = COPY $f4
+ %2:vssrc = COPY $f3
+ %1:vssrc = COPY $f2
+ %0:vssrc = COPY $f1
+ %5:vssrc = nsz contract reassoc nofpexcept XSSUBSP %2, %3
+ %6:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
+ %7:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed %6 :: (load (s32) from constant-pool)
+ %8:vssrc = nsz contract reassoc nofpexcept XSMADDASP killed %5, killed %7, undef %4:vssrc
+ $f1 = COPY %8
+ BLR8 implicit $lr8, implicit $rm, implicit $f1
+...
More information about the llvm-branch-commits
mailing list