[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