Skip to content

Commit 1f31ecc

Browse files
committed
WIP
1 parent f0dbcfe commit 1f31ecc

File tree

9 files changed

+74
-15
lines changed

9 files changed

+74
-15
lines changed

llvm/lib/Target/ARM/ARMBaseInstrInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ static inline bool isIndirectCall(const MachineInstr &MI) {
683683
case ARM::BX_CALL:
684684
case ARM::BMOVPCRX_CALL:
685685
case ARM::TCRETURNri:
686+
case ARM::TCRETURNrinotr12:
686687
case ARM::TAILJMPr:
687688
case ARM::TAILJMPr4:
688689
case ARM::tBLXr:

llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,7 +2197,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
21972197
}
21982198

21992199
case ARM::TCRETURNdi:
2200-
case ARM::TCRETURNri: {
2200+
case ARM::TCRETURNri:
2201+
case ARM::TCRETURNrinotr12: {
22012202
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
22022203
if (MBBI->getOpcode() == ARM::SEH_EpilogEnd)
22032204
MBBI--;
@@ -2241,7 +2242,7 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
22412242
// Add the default predicate in Thumb mode.
22422243
if (STI->isThumb())
22432244
MIB.add(predOps(ARMCC::AL));
2244-
} else if (RetOpcode == ARM::TCRETURNri) {
2245+
} else if (RetOpcode == ARM::TCRETURNri || RetOpcode == ARM::TCRETURNrinotr12) {
22452246
unsigned Opcode =
22462247
STI->isThumb() ? ARM::tTAILJMPr
22472248
: (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);

llvm/lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ static int getArgumentStackToRestore(MachineFunction &MF,
257257
if (MBB.end() != MBBI) {
258258
unsigned RetOpcode = MBBI->getOpcode();
259259
IsTailCallReturn = RetOpcode == ARM::TCRETURNdi ||
260-
RetOpcode == ARM::TCRETURNri;
260+
RetOpcode == ARM::TCRETURNri ||
261+
RetOpcode == ARM::TCRETURNrinotr12;
261262
}
262263
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
263264

@@ -486,6 +487,7 @@ static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI,
486487

487488
case ARM::tBX_RET:
488489
case ARM::TCRETURNri:
490+
case ARM::TCRETURNrinotr12:
489491
MIB = BuildMI(MF, DL, TII.get(ARM::SEH_Nop_Ret))
490492
.addImm(/*Wide=*/0)
491493
.setMIFlags(Flags);
@@ -1615,7 +1617,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
16151617
if (MBB.end() != MI) {
16161618
DL = MI->getDebugLoc();
16171619
unsigned RetOpcode = MI->getOpcode();
1618-
isTailCall = (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri);
1620+
isTailCall = (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri || RetOpcode == ARM::TCRETURNrinotr12);
16191621
isInterrupt =
16201622
RetOpcode == ARM::SUBS_PC_LR || RetOpcode == ARM::t2SUBS_PC_LR;
16211623
isTrap =

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
//===----------------------------------------------------------------------===//
1413
// ARM specific DAG Nodes.
1514
//
16-
1715
// Type profiles.
1816
def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
1917
SDTCisVT<1, i32> ]>;
@@ -2677,6 +2675,9 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in {
26772675
def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, i32imm:$SPDiff), IIC_Br, []>,
26782676
Sched<[WriteBr]>;
26792677

2678+
def TCRETURNrinotr12 : PseudoInst<(outs), (ins tcGPRnotr12:$dst, i32imm:$SPDiff), IIC_Br, []>,
2679+
Sched<[WriteBr]>;
2680+
26802681
def TAILJMPd : ARMPseudoExpand<(outs), (ins arm_br_target:$dst),
26812682
4, IIC_Br, [],
26822683
(Bcc arm_br_target:$dst, (ops 14, zero_reg))>,
@@ -6081,8 +6082,14 @@ def : ARMPat<(ARMWrapperJT tjumptable:$dst),
60816082
// TODO: add,sub,and, 3-instr forms?
60826083

60836084
// Tail calls. These patterns also apply to Thumb mode.
6085+
// Regular indirect tail call
60846086
def : Pat<(ARMtcret tcGPR:$dst, (i32 timm:$SPDiff)),
6085-
(TCRETURNri tcGPR:$dst, timm:$SPDiff)>;
6087+
(TCRETURNri tcGPR:$dst, timm:$SPDiff)>,
6088+
Requires<[TailCall]>;
6089+
// Indirect tail call when PACBTI is enabled
6090+
def : Pat<(ARMtcret tcGPRnotr12:$dst, (i32 timm:$SPDiff)),
6091+
(TCRETURNrinotr12 tcGPRnotr12:$dst, timm:$SPDiff)>,
6092+
Requires<[TailCallNotR12]>;
60866093
def : Pat<(ARMtcret (i32 tglobaladdr:$dst), (i32 timm:$SPDiff)),
60876094
(TCRETURNdi texternalsym:$dst, (i32 timm:$SPDiff))>;
60886095
def : Pat<(ARMtcret (i32 texternalsym:$dst), (i32 timm:$SPDiff)),

llvm/lib/Target/ARM/ARMPredicates.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ def DontGenExecuteOnly : Predicate<"!Subtarget->genExecuteOnly()">;
228228
def GenT1ExecuteOnly : Predicate<"Subtarget->genExecuteOnly() && "
229229
"Subtarget->isThumb1Only() && "
230230
"!Subtarget->hasV8MBaselineOps()">;
231+
let RecomputePerFunction = 1 in {
232+
def TailCallNotR12 : Predicate<[{ MF->getInfo<ARMFunctionInfo>()->shouldSignReturnAddress() }]>;
233+
def TailCall : Predicate<[{ !MF->getInfo<ARMFunctionInfo>()->shouldSignReturnAddress() }]>;
234+
}
231235

232236
// Armv8.5-A extensions
233237
def HasSB : Predicate<"Subtarget->hasSB()">,

llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,6 @@ ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI) {
156156
"Subclass not added?");
157157
assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
158158
"Subclass not added?");
159-
assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnoip_and_tcGPRRegClassID)) &&
160-
"Subclass not added?");
161-
assert(RBGPR.covers(*TRI.getRegClass(
162-
ARM::tGPREven_and_GPRnoip_and_tcGPRRegClassID)) &&
163-
"Subclass not added?");
164159
assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPROdd_and_tcGPRRegClassID)) &&
165160
"Subclass not added?");
166161
assert(getMaximumSize(RBGPR.getID()) == 32 &&
@@ -188,16 +183,16 @@ ARMRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
188183
case GPRnoip_and_GPRnopcRegClassID:
189184
case rGPRRegClassID:
190185
case GPRspRegClassID:
191-
case GPRnoip_and_tcGPRRegClassID:
192186
case tcGPRRegClassID:
187+
case tcGPRnotr12RegClassID:
193188
case tGPRRegClassID:
194189
case tGPREvenRegClassID:
195190
case tGPROddRegClassID:
196191
case tGPR_and_tGPREvenRegClassID:
197192
case tGPR_and_tGPROddRegClassID:
198193
case tGPREven_and_tcGPRRegClassID:
199-
case tGPREven_and_GPRnoip_and_tcGPRRegClassID:
200194
case tGPROdd_and_tcGPRRegClassID:
195+
case tGPREven_and_tcGPRnotr12RegClassID:
201196
return getRegBank(ARM::GPRRegBankID);
202197
case HPRRegClassID:
203198
case SPR_8RegClassID:

llvm/lib/Target/ARM/ARMRegisterInfo.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,16 @@ def tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R12)> {
373373
}];
374374
}
375375

376+
// Some pointer authentication instructions require the use of R12. When return
377+
// address signing is enabled, authentication of the caller's return address
378+
// must be performed before a tail call is made. Therefore, indirect tail call
379+
// jump cannot be from R12.
380+
// FIXME: All PACBTI instruction currently implemented in the compiler
381+
// implicitly use R12. When instructions that allow PAC to be placed in a
382+
// specific register are implemented the restriction needs to be updated t
383+
// make sure that PACBTI signature and indirect tail call both use a different register.
384+
def tcGPRnotr12 : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3)>;
385+
376386
def tGPROdd : RegisterClass<"ARM", [i32], 32, (add R1, R3, R5, R7, R9, R11)> {
377387
let AltOrders = [(and tGPROdd, tGPR)];
378388
let AltOrderSelect = [{

llvm/lib/Target/ARM/Thumb1FrameLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,9 @@ static void popRegsFromStack(MachineBasicBlock &MBB,
10511051
if (Reg == ARM::LR) {
10521052
if (!MBB.succ_empty() ||
10531053
MI->getOpcode() == ARM::TCRETURNdi ||
1054-
MI->getOpcode() == ARM::TCRETURNri)
1054+
MI->getOpcode() == ARM::TCRETURNri ||
1055+
MI->getOpcode() == ARM::TCRETURNrinotr12
1056+
)
10551057
// LR may only be popped into PC, as part of return sequence.
10561058
// If this isn't the return sequence, we'll need emitPopSpecialFixUp
10571059
// to restore LR the hard way.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+pacbti< %s | FileCheck %s
2+
3+
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
4+
target triple = "thumbv8.1m.main-m.main-unknown"
5+
6+
; When PACBTI is enabled, indirect tail-calls must not use R12 that is used
7+
; to store authentication code.
8+
9+
define void @pacbti_disabled(ptr %p) "sign-return-address"="none" {
10+
entry:
11+
tail call void %p()
12+
; CHECK: bx {{r0|r1|r2|r3|r12}}
13+
ret void
14+
}
15+
16+
define void @pacbti_enabled(ptr %p) "sign-return-address"="all" {
17+
entry:
18+
tail call void %p()
19+
; CHECK: bx {{r0|r1|r2|r3}}
20+
ret void
21+
}
22+
23+
define void @pacbti_disabled_force_r12(ptr %p) "sign-return-address"="none" {
24+
entry:
25+
%p_r12 = tail call ptr asm "", "={r12},{r12},~{lr}"(ptr %p)
26+
tail call void %p_r12()
27+
; CHECK: bx r12
28+
ret void
29+
}
30+
31+
define void @pacbti_enabled_force_r12(ptr %p) "sign-return-address"="all" {
32+
entry:
33+
%p_r12 = tail call ptr asm "", "={r12},{r12},~{lr}"(ptr %p)
34+
tail call void %p_r12()
35+
; CHECK: bx {{r0|r1|r2|r3}}
36+
ret void
37+
}

0 commit comments

Comments
 (0)