[llvm] 34a5055 - ARM: Don't duplicate the LR def when expanding call pseudos (#225062)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 02:04:48 PDT 2026
Author: Matt Arsenault
Date: 2026-09-22T11:04:42+02:00
New Revision: 34a505568ca0cf7c7f90c88964548856309b86c4
URL: https://github.com/llvm/llvm-project/commit/34a505568ca0cf7c7f90c88964548856309b86c4
DIFF: https://github.com/llvm/llvm-project/commit/34a505568ca0cf7c7f90c88964548856309b86c4.diff
LOG: ARM: Don't duplicate the LR def when expanding call pseudos (#225062)
Several pseudo expansions in ARMExpandPseudoInsts built a real call and then
copied the pseudo's operands onto the new instruction. Each of these call opcodes
declares LR as an implicit-def, but the original instruction already had that. The original
def may have been marked as dead, so the result would be a redundant operand with an
inconsistent dead flag. This avoids a failure in a future verifier check.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
Added:
Modified:
llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index c55c87ec79ef3..91fd2129a5d0b 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -2437,15 +2437,20 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
ClearRegs); // save+clear FP regs with ClearRegs
CMSEClearGPRegs(MBB, MBBI, DL, ClearRegs, JumpReg);
- const MachineInstrBuilder NewCall =
- BuildMI(MBB, MBBI, DL, TII->get(ARM::tBLXNSr))
- .add(predOps(ARMCC::AL))
- .addReg(JumpReg, RegState::Kill);
+ // Be careful not to duplicate the LR def that already exists on the
+ // pseudoinstruction.
+ MachineFunction &MF = *MBB.getParent();
+ MachineInstr *NewCall = MF.CreateMachineInstr(TII->get(ARM::tBLXNSr), DL,
+ /*NoImplicit=*/true);
+ MBB.insert(MBBI, NewCall);
+ MachineInstrBuilder(MF, NewCall)
+ .add(predOps(ARMCC::AL))
+ .addReg(JumpReg, RegState::Kill);
for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
NewCall->addOperand(MO);
if (MI.isCandidateForAdditionalCallInfo())
- MI.getMF()->moveAdditionalCallInfo(&MI, NewCall.getInstr());
+ MI.getMF()->moveAdditionalCallInfo(&MI, NewCall);
CMSERestoreFPRegs(MBB, MBBI, DL, OriginalClearRegs); // restore FP registers
@@ -2664,22 +2669,30 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MIB.addImm(0);
MIB.add(predOps(ARMCC::AL));
- MIB =
- BuildMI(MBB, MBBI, MI.getDebugLoc(),
- TII->get(Thumb ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF)));
+ // The pesudo already has an LR def, avoid introducing a duplicated copy
+ // from the original operand list.
+ unsigned CallOpc = Thumb ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF);
+ MachineInstr *Call = MF->CreateMachineInstr(
+ TII->get(CallOpc), MI.getDebugLoc(), /*NoImplicit=*/true);
+ MBB.insert(MBBI, Call);
+ MIB = MachineInstrBuilder(*MF, Call);
if (Thumb)
MIB.add(predOps(ARMCC::AL));
MIB.addReg(Reg, RegState::Kill);
} else {
- MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
- TII->get(Thumb ? ARM::tBL : ARM::BL));
+ unsigned CallOpc = Thumb ? ARM::tBL : ARM::BL;
+ MachineInstr *Call = MF->CreateMachineInstr(
+ TII->get(CallOpc), MI.getDebugLoc(), /*NoImplicit=*/true);
+ MBB.insert(MBBI, Call);
+ MIB = MachineInstrBuilder(*MF, Call);
if (Thumb)
MIB.add(predOps(ARMCC::AL));
MIB.addExternalSymbol("__aeabi_read_tp", 0);
}
MIB.cloneMemRefs(MI);
- MIB.copyImplicitOps(MI);
+ for (const MachineOperand &MO : MI.operands())
+ MIB.add(MO);
// Update the call info.
if (MI.isCandidateForAdditionalCallInfo())
MF->moveAdditionalCallInfo(&MI, &*MIB);
@@ -3249,15 +3262,13 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
const bool Thumb = Opcode == ARM::tBL_PUSHLR;
Register Reg = MI.getOperand(0).getReg();
assert(Reg == ARM::LR && "expect LR register!");
- MachineInstrBuilder MIB;
+ MachineFunction &MF = *MBB.getParent();
+ unsigned CallOpc = Thumb ? ARM::tBL : ARM::BL;
if (Thumb) {
// push {lr}
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPUSH))
.add(predOps(ARMCC::AL))
.addReg(Reg);
-
- // bl __gnu_mcount_nc
- MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tBL));
} else {
// stmdb sp!, {lr}
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::STMDB_UPD))
@@ -3265,10 +3276,15 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
.addReg(ARM::SP)
.add(predOps(ARMCC::AL))
.addReg(Reg);
-
- // bl __gnu_mcount_nc
- MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::BL));
}
+
+ // bl __gnu_mcount_nc. Be careful not to duplicate the LR-def the original
+ // instruction already has.
+ MachineInstr *Call =
+ MF.CreateMachineInstr(TII->get(CallOpc), MI.getDebugLoc(),
+ /*NoImplicit=*/true);
+ MBB.insert(MBBI, Call);
+ MachineInstrBuilder MIB(MF, Call);
MIB.cloneMemRefs(MI);
for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
MIB.add(MO);
diff --git a/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir b/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir
index 9bc335c2ab09a..ef32fe9b1b91d 100644
--- a/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir
+++ b/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir
@@ -104,7 +104,7 @@ body: |
# CHECK-NEXT: $r11 = tMOVr $r0, 14 /* CC::al */, $noreg
# CHECK-NEXT: $r12 = tMOVr $r0, 14 /* CC::al */, $noreg
# CHECK-NEXT: t2MSR_M 3072, $r0, 14 /* CC::al */, $noreg, implicit-def $cpsr
-# CHECK-NEXT: tBLXNSr 14 /* CC::al */, $noreg, killed $r0, csr_aapcs, implicit-def $lr, implicit $sp, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $s0
+# CHECK-NEXT: tBLXNSr 14 /* CC::al */, $noreg, killed $r0, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $s0
# CHECK-NEXT: $r12 = VMOVRS $s0, 14 /* CC::al */, $noreg
# CHECK-NEXT: VLLDM $sp, 14 /* CC::al */, $noreg, 0, implicit-def $vpr, implicit-def $fpscr, implicit-def $fpscr_nzcv, implicit-def $d0, implicit-def $d1, implicit-def $d2, implicit-def $d3, implicit-def $d4, implicit-def $d5, implicit-def $d6, implicit-def $d7, implicit-def $d8, implicit-def $d9, implicit-def $d10, implicit-def $d11, implicit-def $d12, implicit-def $d13, implicit-def $d14, implicit-def $d15
# CHECK-NEXT: $s0 = VMOVSR $r12, 14 /* CC::al */, $noreg
More information about the llvm-commits
mailing list