[llvm] eb5ec4f - AArch64: Fix assert on fold of undef operand (#218600)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 03:54:00 PDT 2026


Author: Matt Arsenault
Date: 2026-08-26T12:53:54+02:00
New Revision: eb5ec4f9a5e5ae9bddc6945228ed80ba09c1a83c

URL: https://github.com/llvm/llvm-project/commit/eb5ec4f9a5e5ae9bddc6945228ed80ba09c1a83c
DIFF: https://github.com/llvm/llvm-project/commit/eb5ec4f9a5e5ae9bddc6945228ed80ba09c1a83c.diff

LOG: AArch64: Fix assert on fold of undef operand (#218600)

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

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
    llvm/test/CodeGen/AArch64/optimize-cond-branch-undef.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 522b263df5de1..9867164af2e41 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -10102,9 +10102,9 @@ bool AArch64InstrInfo::optimizeCondBranch(MachineInstr &MI) const {
       return false;
     if (!MRI->hasOneNonDBGUse(CopyVReg))
       return false;
-    if (!MRI->hasOneDef(CopyVReg))
-      return false;
     DefMI = MRI->getVRegDef(CopyVReg);
+    if (!DefMI)
+      return false;
   }
 
   switch (DefMI->getOpcode()) {
@@ -10131,7 +10131,8 @@ bool AArch64InstrInfo::optimizeCondBranch(MachineInstr &MI) const {
     if (!NewReg.isVirtual())
       return false;
 
-    assert(!MRI->def_empty(NewReg) && "Register must be defined.");
+    if (!MRI->getVRegDef(NewReg))
+      return false;
 
     MachineBasicBlock &RefToMBB = *MBB;
     MachineBasicBlock *TBB = MI.getOperand(1).getMBB();

diff  --git a/llvm/test/CodeGen/AArch64/optimize-cond-branch-undef.mir b/llvm/test/CodeGen/AArch64/optimize-cond-branch-undef.mir
index 7a4d9b98ca1a1..40cc6b826faf8 100644
--- a/llvm/test/CodeGen/AArch64/optimize-cond-branch-undef.mir
+++ b/llvm/test/CodeGen/AArch64/optimize-cond-branch-undef.mir
@@ -30,3 +30,107 @@ body: |
   bb.2:
     RET_ReallyLR
 ...
+
+---
+name: cbz_and_undef_source
+tracksRegLiveness: true
+body: |
+  ; CHECK-LABEL: name: cbz_and_undef_source
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[ANDWri:%[0-9]+]]:gpr32sp = ANDWri undef %1:gpr32, 0
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32 = COPY [[ANDWri]]
+  ; CHECK-NEXT:   CBZW [[COPY]], %bb.2
+  ; 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
+
+    %0:gpr32sp = ANDWri undef %1:gpr32, 0
+    %2:gpr32 = COPY %0
+    CBZW %2, %bb.2
+    B %bb.1
+
+  bb.1:
+    RET_ReallyLR
+
+  bb.2:
+    RET_ReallyLR
+...
+
+# The branch condition is a COPY of an undef register.
+---
+name: cbz_copy_of_undef
+tracksRegLiveness: true
+body: |
+  ; CHECK-LABEL: name: cbz_copy_of_undef
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32 = COPY undef %1:gpr32
+  ; CHECK-NEXT:   CBZW [[COPY]], %bb.2
+  ; 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
+
+    %0:gpr32 = COPY undef %1:gpr32
+    CBZW %0, %bb.2
+    B %bb.1
+
+  bb.1:
+    RET_ReallyLR
+
+  bb.2:
+    RET_ReallyLR
+...
+
+# A defined AND source is still folded into a TBZ through the copy
+# chain: the undef guard must not block the ordinary case.
+---
+name: tbz_and_defined_source
+tracksRegLiveness: true
+body: |
+  ; CHECK-LABEL: name: tbz_and_defined_source
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+  ; CHECK-NEXT:   [[ANDWri:%[0-9]+]]:gpr32sp = ANDWri [[COPY]], 0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY [[ANDWri]]
+  ; CHECK-NEXT:   TBZW [[COPY]], 0, %bb.2
+  ; 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
+    liveins: $w0
+
+    %3:gpr32 = COPY $w0
+    %0:gpr32sp = ANDWri %3, 0
+    %2:gpr32 = COPY %0
+    CBZW %2, %bb.2
+    B %bb.1
+
+  bb.1:
+    RET_ReallyLR
+
+  bb.2:
+    RET_ReallyLR
+...


        


More information about the llvm-commits mailing list