[llvm] AArch64: Fix MIPeepholeOpt null dereference on undef source operands (PR #218291)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 23 14:35:42 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

Fix unchecked getUniqueVRegDef calls. This is also an SSA pass, and has
no reason to use getUniqueVRegDef over getVRegDef, so also make that
change.

Co-Authored-By: Claude <noreply@<!-- -->anthropic.com> (Claude Opus 4.8)

---
Full diff: https://github.com/llvm/llvm-project/pull/218291.diff


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp (+6-4) 
- (added) llvm/test/CodeGen/AArch64/mipeephole-undef-operand.mir (+57) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp b/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
index a292aee81e615..f6fdc63970408 100644
--- a/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
@@ -512,8 +512,10 @@ bool AArch64MIPeepholeOptImpl::visitADDSSUBS(OpcodePair PosOpcs,
           return std::nullopt;
         // Check conditional uses last since it is expensive for scanning
         // proceeding instructions
-        MachineInstr &SrcMI = *MRI->getUniqueVRegDef(MI.getOperand(1).getReg());
-        std::optional<UsedNZCV> NZCVUsed = examineCFlagsUse(SrcMI, MI, *TRI);
+        MachineInstr *SrcMI = MRI->getVRegDef(MI.getOperand(1).getReg());
+        if (!SrcMI)
+          return std::nullopt;
+        std::optional<UsedNZCV> NZCVUsed = examineCFlagsUse(*SrcMI, MI, *TRI);
         if (!NZCVUsed || NZCVUsed->C || NZCVUsed->V)
           return std::nullopt;
         return OP;
@@ -763,8 +765,8 @@ bool AArch64MIPeepholeOptImpl::visitINSvi64lane(MachineInstr &MI) {
   //  %6:fpr128 = IMPLICIT_DEF
   //  %5:fpr128 = INSERT_SUBREG %6:fpr128(tied-def 0), killed %1:fpr64, %subreg.dsub
   //  %7:fpr128 = INSvi64lane %5:fpr128(tied-def 0), 1, killed %3:fpr128, 0
-  MachineInstr *Low64MI = MRI->getUniqueVRegDef(MI.getOperand(1).getReg());
-  if (Low64MI->getOpcode() != AArch64::INSERT_SUBREG)
+  MachineInstr *Low64MI = MRI->getVRegDef(MI.getOperand(1).getReg());
+  if (!Low64MI || Low64MI->getOpcode() != AArch64::INSERT_SUBREG)
     return false;
   Low64MI = MRI->getUniqueVRegDef(Low64MI->getOperand(2).getReg());
   if (!Low64MI || !is64bitDefwithZeroHigh64bit(Low64MI, MRI, TII))
diff --git a/llvm/test/CodeGen/AArch64/mipeephole-undef-operand.mir b/llvm/test/CodeGen/AArch64/mipeephole-undef-operand.mir
new file mode 100644
index 0000000000000..d68ced796aa1e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/mipeephole-undef-operand.mir
@@ -0,0 +1,57 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=aarch64 -run-pass=aarch64-mi-peephole-opt -o - %s | FileCheck %s
+
+# Make sure AArch64MIPeepholeOpt does not crash on undef operands
+# without a def.
+
+---
+name:            insvi64lane_undef
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $q1
+
+    ; CHECK-LABEL: name: insvi64lane_undef
+    ; CHECK: liveins: $q1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q1
+    ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane undef %2:fpr128, 1, [[COPY]], 1
+    ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]]
+    ; CHECK-NEXT: RET_ReallyLR implicit $q0
+    %1:fpr128 = COPY $q1
+    %2:fpr128 = INSvi64lane undef %0:fpr128, 1, %1, 1
+    $q0 = COPY %2
+    RET_ReallyLR implicit $q0
+...
+---
+name:            subsxrr_undef
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: subsxrr_undef
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 1052673
+  ; CHECK-NEXT:   [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr undef %2:gpr64, killed [[MOVi64imm]], implicit-def $nzcv
+  ; CHECK-NEXT:   Bcc 1, %bb.2, implicit $nzcv
+  ; CHECK-NEXT:   B %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   RET_ReallyLR
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   RET_ReallyLR
+  bb.0:
+    successors: %bb.1, %bb.2
+
+    %1:gpr64 = MOVi64imm 1052673
+    %2:gpr64 = SUBSXrr undef %0:gpr64, killed %1, implicit-def $nzcv
+    Bcc 1, %bb.2, implicit $nzcv
+    B %bb.1
+
+  bb.1:
+    RET_ReallyLR
+
+  bb.2:
+    RET_ReallyLR
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/218291


More information about the llvm-commits mailing list