Skip to content

Commit f205566

Browse files
Reland "[llvm][AArch64] Copy all operands when expanding BLR_BTI bundle (#78267)" (#78719)
This reverts commit 955417a. The problem with the previous version was that the bundle instruction had arguments like "target arg1 arg2". When it's expanded we produced a BL or BLR which can only accept one argument, the target of the branch. Now I realise why expandCALL_RVMARKER has to copy them in mutiple steps. The operands for the called function need to be changed to implicit arguments of the branch instruction. * Copy the branch target. * Copy all register operands, marking them as implicit. * Copy any other operands without modifying them. Prior to any attempt to fix #77915: BL @_setjmp, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def dead $lr, implicit $sp, implicit-def $sp Which is dropping the use of the arguments for the called function. My first fix attempt produced: BL @_setjmp, $x0, $w1, <regmask $fp ...>, implicit-def $lr, implicit $sp, implicit-def dead $lr, implicit $sp, implicit-def $sp It copied the arguments but as explicit arguments to the BL which only expects 1, failing verification. With this new change we produce: BL @_setjmp, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1, implicit-def dead $lr, implicit $sp, implicit-def $sp Note specifically the added "implicit $x0, implicit $w1". So BL only has 1 explicit argument, but the arguments to the function are still used.
1 parent 134fcc6 commit f205566

File tree

3 files changed

+45
-24
lines changed

3 files changed

+45
-24
lines changed

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,8 +843,24 @@ bool AArch64ExpandPseudo::expandCALL_BTI(MachineBasicBlock &MBB,
843843
MachineInstr *Call =
844844
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
845845
Call->addOperand(CallTarget);
846+
847+
// 1 because we already added the branch target above.
848+
unsigned RegMaskStartIdx = 1;
849+
// The branch is BL <target>, so we cannot attach the arguments of the called
850+
// function to it. Those must be added as implicitly used by the branch.
851+
while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
852+
auto MOP = MI.getOperand(RegMaskStartIdx);
853+
assert(MOP.isReg() && "can only add register operands");
854+
Call->addOperand(MachineOperand::CreateReg(
855+
MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
856+
/*isDead=*/false, /*isUndef=*/MOP.isUndef()));
857+
RegMaskStartIdx++;
858+
}
859+
for (const MachineOperand &MO :
860+
llvm::drop_begin(MI.operands(), RegMaskStartIdx))
861+
Call->addOperand(MO);
862+
846863
Call->setCFIType(*MBB.getParent(), MI.getCFIType());
847-
Call->copyImplicitOps(*MBB.getParent(), MI);
848864

849865
MachineInstr *BTI =
850866
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::HINT))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass=aarch64-expand-pseudo -o - %s | FileCheck %s
2+
3+
# When expanding a BLR_BTI, we should copy all the operands to the branch in the
4+
# bundle. Otherwise we could end up using a register after the BL which was
5+
# clobbered by the function that was called, or overwriting an argument to that
6+
# function before we take the branch.
7+
#
8+
# The arguments to the call must become implicit arguments, because the branch
9+
# only expects to get 1 explicit operand which is the branch target.
10+
11+
# CHECK: BUNDLE implicit-def $lr, implicit-def $w30, implicit-def $sp, implicit-def $wsp, implicit $sp, implicit $x0, implicit $w1 {
12+
# CHECK: BL @_setjmp, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1, implicit-def dead $lr, implicit $sp, implicit-def $sp
13+
# CHECK: HINT 36
14+
# CHECK: }
15+
16+
--- |
17+
define void @a() {
18+
ret void
19+
}
20+
21+
declare void @_setjmp(...)
22+
...
23+
---
24+
name: a
25+
body: |
26+
bb.0:
27+
BLR_BTI @_setjmp, $x0, $w1, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
28+
...

llvm/test/CodeGen/AArch64/blr-bti-preserves-regmask.mir

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)