[llvm] [AArch64] Constraint SUBS register classes after if-converting CMPBR (PR #219884)
David Tellenbach via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 30 22:34:08 PDT 2026
https://github.com/dtellenbach created https://github.com/llvm/llvm-project/pull/219884
When generating SUBS to un-fuse the Armv9.6 Compare-and-Branch immediate variants CBWPri and CBXPri during if-conversion, we missed to constraint the register classes, leading to a verifier crash.
>From 8a5a06deac79826d37f3779edbc43097dbd7b2cc Mon Sep 17 00:00:00 2001
From: David Tellenbach <dtellenbach at apple.com>
Date: Sun, 30 Aug 2026 22:28:02 -0700
Subject: [PATCH] [AArch64] Constraint SUBS register classes after
if-converting CMPBR
When generating SUBS to un-fuse the Armv9.6 Compare-and-Branch immediate
variants CBWPri and CBXPri during if-conversion, we missed to constraint
the register classes, leading to a verifier crash.
---
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 8 +-
.../CodeGen/AArch64/cmpbr-early-ifcvt.mir | 104 ++++++++++++++++++
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 43aab1400e81f..2994f9ad2c8f2 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -1187,15 +1187,19 @@ void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB,
break;
}
- if (IsImm)
+ if (IsImm) {
+ MRI.constrainRegClass(Cond[3].getReg(), getRegClass(get(SubsOpc), 1));
BuildMI(MBB, I, DL, get(SubsOpc), SubsDestReg)
.addReg(Cond[3].getReg())
.addImm(Cond[4].getImm())
.addImm(0);
- else
+ } else {
+ MRI.constrainRegClass(Cond[3].getReg(), getRegClass(get(SubsOpc), 1));
+ MRI.constrainRegClass(Cond[4].getReg(), getRegClass(get(SubsOpc), 2));
BuildMI(MBB, I, DL, get(SubsOpc), SubsDestReg)
.addReg(Cond[3].getReg())
.addReg(Cond[4].getReg());
+ }
} break;
case 7: { // cb[b,h]
// We must insert a cmp, that is a subs, but also zero- or sign-extensions
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir b/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
index a173780935ae6..3b4d23b01120e 100644
--- a/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
+++ b/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
@@ -114,6 +114,110 @@ body: |
RET_ReallyLR implicit $x0
...
---
+name: cb_triangle_w_imm
+alignment: 4
+tracksRegLiveness: true
+noPhis: false
+isSSA: true
+noVRegs: false
+hasFakeUses: false
+registers:
+ - { id: 0, class: gpr32 }
+ - { id: 1, class: gpr32 }
+ - { id: 2, class: gpr32 }
+ - { id: 3, class: gpr32 }
+ - { id: 4, class: gpr32 }
+liveins:
+ - { reg: '$w0', virtual-reg: '%0' }
+ - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+ maxAlignment: 1
+ maxCallFrameSize: 0
+machineFunctionInfo: {}
+body: |
+ ; CHECK-LABEL: name: cb_triangle_w_imm
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+ ; CHECK-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: $wzr = SUBSWri [[COPY]], 10, 0, implicit-def $nzcv
+ ; CHECK-NEXT: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[COPY1]], [[ADDWrr]], 10, implicit $nzcv
+ ; CHECK-NEXT: [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+ ; CHECK-NEXT: $w0 = COPY [[ADDWrr1]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $w0, $w1
+
+ %0:gpr32 = COPY $w0
+ %1:gpr32 = COPY $w1
+ CBWPri 10, %0, 10, %bb.2
+
+ bb.1:
+ successors: %bb.2
+ %2:gpr32 = ADDWrr %0, %1
+
+ bb.2:
+ %3:gpr32 = PHI %1, %bb.0, %2, %bb.1
+ %4:gpr32 = ADDWrr killed %3, %0
+ $w0 = COPY %4
+ RET_ReallyLR implicit $w0
+...
+---
+name: cb_triangle_x_imm
+alignment: 4
+tracksRegLiveness: true
+noPhis: false
+isSSA: true
+noVRegs: false
+hasFakeUses: false
+registers:
+ - { id: 0, class: gpr64 }
+ - { id: 1, class: gpr64 }
+ - { id: 2, class: gpr64 }
+ - { id: 3, class: gpr64 }
+ - { id: 4, class: gpr64 }
+liveins:
+ - { reg: '$x0', virtual-reg: '%0' }
+ - { reg: '$x1', virtual-reg: '%1' }
+frameInfo:
+ maxAlignment: 1
+ maxCallFrameSize: 0
+machineFunctionInfo: {}
+body: |
+ ; CHECK-LABEL: name: cb_triangle_x_imm
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
+ ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: $xzr = SUBSXri [[COPY]], 10, 0, implicit-def $nzcv
+ ; CHECK-NEXT: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[COPY1]], [[ADDXrr]], 10, implicit $nzcv
+ ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr killed [[CSELXr]], [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[ADDXrr1]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $x0, $x1
+
+ %0:gpr64 = COPY $x0
+ %1:gpr64 = COPY $x1
+ CBXPri 10, %0, 10, %bb.2
+
+ bb.1:
+ successors: %bb.2
+ %2:gpr64 = ADDXrr %0, %1
+
+ bb.2:
+ %3:gpr64 = PHI %1, %bb.0, %2, %bb.1
+ %4:gpr64 = ADDXrr killed %3, %0
+ $x0 = COPY %4
+ RET_ReallyLR implicit $x0
+...
+---
name: cbb_diamond_no_ext
alignment: 4
tracksRegLiveness: true
More information about the llvm-commits
mailing list