Skip to content

Commit 16fa8b0

Browse files
committed
Reland "[ARM] push LR before __gnu_mcount_nc"
This relands r369147 with fixes to unit tests. https://reviews.llvm.org/D65019 llvm-svn: 369173
1 parent 57ec292 commit 16fa8b0

File tree

11 files changed

+141
-5
lines changed

11 files changed

+141
-5
lines changed

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
322322
if (Triple.getOS() == llvm::Triple::Linux ||
323323
Triple.getOS() == llvm::Triple::UnknownOS)
324324
this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
325-
? "\01__gnu_mcount_nc"
325+
? "llvm.arm.gnu.eabi.mcount"
326326
: "\01mcount";
327327

328328
SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");

clang/test/Frontend/gnu-mcount.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ int f() {
6666
// CHECK-ARM64-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="__mcount"{{.*}} }
6767
// CHECK-ARM64-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
6868
// CHECK-ARM-EABI-MEABI-GNU-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
69-
// CHECK-ARM-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
69+
// CHECK-ARM-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="llvm.arm.gnu.eabi.mcount"{{.*}} }
7070
// CHECK-ARM-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
7171
// CHECK-ARM-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
7272
// CHECK-ARM64-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }

llvm/include/llvm/IR/IntrinsicsARM.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,4 +778,9 @@ def int_arm_neon_udot : Neon_Dot_Intrinsic;
778778
def int_arm_neon_sdot : Neon_Dot_Intrinsic;
779779

780780

781+
// GNU eabi mcount
782+
def int_arm_gnu_eabi_mcount : Intrinsic<[],
783+
[],
784+
[IntrReadMem, IntrWriteMem]>;
785+
781786
} // end TargetPrefix

llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,37 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
19161916

19171917
case ARM::CMP_SWAP_64:
19181918
return ExpandCMP_SWAP_64(MBB, MBBI, NextMBBI);
1919+
1920+
case ARM::tBL_PUSHLR:
1921+
case ARM::BL_PUSHLR: {
1922+
const bool Thumb = Opcode == ARM::tBL_PUSHLR;
1923+
Register Reg = MI.getOperand(0).getReg();
1924+
assert(Reg == ARM::LR && "expect LR register!");
1925+
MachineInstrBuilder MIB;
1926+
if (Thumb) {
1927+
// push {lr}
1928+
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPUSH))
1929+
.add(predOps(ARMCC::AL))
1930+
.addReg(Reg);
1931+
1932+
// bl __gnu_mcount_nc
1933+
MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tBL));
1934+
} else {
1935+
// stmdb sp!, {lr}
1936+
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::STMDB_UPD))
1937+
.addReg(ARM::SP, RegState::Define)
1938+
.addReg(ARM::SP)
1939+
.add(predOps(ARMCC::AL))
1940+
.addReg(Reg);
1941+
1942+
// bl __gnu_mcount_nc
1943+
MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::BL));
1944+
}
1945+
MIB.cloneMemRefs(MI);
1946+
for (unsigned i = 1; i < MI.getNumOperands(); ++i) MIB.add(MI.getOperand(i));
1947+
MI.eraseFromParent();
1948+
return true;
1949+
}
19191950
}
19201951
}
19211952

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
10171017
setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
10181018
setOperationAction(ISD::SRL, MVT::i64, Custom);
10191019
setOperationAction(ISD::SRA, MVT::i64, Custom);
1020+
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
10201021
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
10211022

10221023
// MVE lowers 64 bit shifts to lsll and lsrl
@@ -3544,6 +3545,48 @@ SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
35443545
Op.getOperand(0));
35453546
}
35463547

3548+
SDValue ARMTargetLowering::LowerINTRINSIC_VOID(
3549+
SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const {
3550+
unsigned IntNo =
3551+
cast<ConstantSDNode>(
3552+
Op.getOperand(Op.getOperand(0).getValueType() == MVT::Other))
3553+
->getZExtValue();
3554+
switch (IntNo) {
3555+
default:
3556+
return SDValue(); // Don't custom lower most intrinsics.
3557+
case Intrinsic::arm_gnu_eabi_mcount: {
3558+
MachineFunction &MF = DAG.getMachineFunction();
3559+
EVT PtrVT = getPointerTy(DAG.getDataLayout());
3560+
SDLoc dl(Op);
3561+
SDValue Chain = Op.getOperand(0);
3562+
// call "\01__gnu_mcount_nc"
3563+
const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
3564+
const uint32_t *Mask =
3565+
ARI->getCallPreservedMask(DAG.getMachineFunction(), CallingConv::C);
3566+
assert(Mask && "Missing call preserved mask for calling convention");
3567+
// Mark LR an implicit live-in.
3568+
unsigned Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
3569+
SDValue ReturnAddress =
3570+
DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT);
3571+
std::vector<EVT> ResultTys = {MVT::Other, MVT::Glue};
3572+
SDValue Callee =
3573+
DAG.getTargetExternalSymbol("\01__gnu_mcount_nc", PtrVT, 0);
3574+
SDValue RegisterMask = DAG.getRegisterMask(Mask);
3575+
if (Subtarget->isThumb())
3576+
return SDValue(
3577+
DAG.getMachineNode(
3578+
ARM::tBL_PUSHLR, dl, ResultTys,
3579+
{ReturnAddress, DAG.getTargetConstant(ARMCC::AL, dl, PtrVT),
3580+
DAG.getRegister(0, PtrVT), Callee, RegisterMask, Chain}),
3581+
0);
3582+
return SDValue(
3583+
DAG.getMachineNode(ARM::BL_PUSHLR, dl, ResultTys,
3584+
{ReturnAddress, Callee, RegisterMask, Chain}),
3585+
0);
3586+
}
3587+
}
3588+
}
3589+
35473590
SDValue
35483591
ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
35493592
const ARMSubtarget *Subtarget) const {
@@ -8835,6 +8878,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
88358878
case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
88368879
case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
88378880
case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
8881+
case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG, Subtarget);
88388882
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
88398883
Subtarget);
88408884
case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG, Subtarget);

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ class VectorType;
667667
SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
668668
SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
669669
SDValue LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
670+
SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG,
671+
const ARMSubtarget *Subtarget) const;
670672
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
671673
const ARMSubtarget *Subtarget) const;
672674
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,6 +2370,12 @@ let isCall = 1,
23702370
def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins arm_bl_target:$func),
23712371
8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>,
23722372
Requires<[IsARM]>, Sched<[WriteBr]>;
2373+
2374+
// push lr before the call
2375+
def BL_PUSHLR : ARMPseudoInst<(outs), (ins GPRlr:$ra, arm_bl_target:$func),
2376+
4, IIC_Br,
2377+
[]>,
2378+
Requires<[IsARM]>, Sched<[WriteBr]>;
23732379
}
23742380

23752381
let isBranch = 1, isTerminator = 1 in {

llvm/lib/Target/ARM/ARMInstrThumb.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,13 @@ let isCall = 1,
565565
4, IIC_Br,
566566
[(ARMcall_nolink tGPR:$func)]>,
567567
Requires<[IsThumb, IsThumb1Only]>, Sched<[WriteBr]>;
568+
569+
// Also used for Thumb2
570+
// push lr before the call
571+
def tBL_PUSHLR : tPseudoInst<(outs), (ins GPRlr:$ra, pred:$p, thumb_bl_target:$func),
572+
4, IIC_Br,
573+
[]>,
574+
Requires<[IsThumb]>, Sched<[WriteBr]>;
568575
}
569576

570577
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {

llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static void insertCall(Function &CurFn, StringRef Func,
2424

2525
if (Func == "mcount" ||
2626
Func == ".mcount" ||
27-
Func == "\01__gnu_mcount_nc" ||
27+
Func == "llvm.arm.gnu.eabi.mcount" ||
2828
Func == "\01_mcount" ||
2929
Func == "\01mcount" ||
3030
Func == "__mcount" ||
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: llc -mtriple=armv7a-linux-gnueabihf -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK-ARM
2+
; RUN: llc -mtriple=armv7a-linux-gnueabihf -verify-machineinstrs -fast-isel %s -o - | FileCheck %s --check-prefix=CHECK-ARM-FAST-ISEL
3+
; RUN: llc -mtriple=armv7a-linux-gnueabihf -verify-machineinstrs -global-isel -global-isel-abort=2 %s -o - | FileCheck %s --check-prefix=CHECK-ARM-GLOBAL-ISEL
4+
; RUN: llc -mtriple=thumbv7a-linux-gnueabihf -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK-THUMB
5+
; RUN: llc -mtriple=thumbv7a-linux-gnueabihf -verify-machineinstrs -fast-isel %s -o - | FileCheck %s --check-prefix=CHECK-THUMB-FAST-ISEL
6+
; RUN: llc -mtriple=thumbv7a-linux-gnueabihf -verify-machineinstrs -global-isel -global-isel-abort=2 %s -o - | FileCheck %s --check-prefix=CHECK-THUMB-GLOBAL-ISEL
7+
8+
define dso_local void @callee() #0 {
9+
; CHECK-ARM: stmdb sp!, {lr}
10+
; CHECK-ARM-NEXT: bl __gnu_mcount_nc
11+
; CHECK-ARM-FAST-ISEL: stmdb sp!, {lr}
12+
; CHECK-ARM-FAST-ISEL-NEXT: bl __gnu_mcount_nc
13+
; CHECK-ARM-GLOBAL-ISEL: stmdb sp!, {lr}
14+
; CHECK-ARM-GLOBAL-ISEL-NEXT: bl __gnu_mcount_nc
15+
; CHECK-THUMB: push {lr}
16+
; CHECK-THUMB-NEXT: bl __gnu_mcount_nc
17+
; CHECK-THUMB-FAST-ISEL: push {lr}
18+
; CHECK-THUMB-FAST-ISEL-NEXT: bl __gnu_mcount_nc
19+
; CHECK-THUMB-GLOBAL-ISEL: push {lr}
20+
; CHECK-THUMB-GLOBAL-ISEL-NEXT: bl __gnu_mcount_nc
21+
ret void
22+
}
23+
24+
define dso_local void @caller() #0 {
25+
; CHECK-ARM: stmdb sp!, {lr}
26+
; CHECK-ARM-NEXT: bl __gnu_mcount_nc
27+
; CHECK-ARM-FAST-ISEL: stmdb sp!, {lr}
28+
; CHECK-ARM-FAST-ISEL-NEXT: bl __gnu_mcount_nc
29+
; CHECK-ARM-GLOBAL-ISEL: stmdb sp!, {lr}
30+
; CHECK-ARM-GLOBAL-ISEL-NEXT: bl __gnu_mcount_nc
31+
; CHECK-THUMB: push {lr}
32+
; CHECK-THUMB-NEXT: bl __gnu_mcount_nc
33+
; CHECK-THUMB-FAST-ISEL: push {lr}
34+
; CHECK-THUMB-FAST-ISEL-NEXT: bl __gnu_mcount_nc
35+
; CHECK-THUMB-GLOBAL-ISEL: push {lr}
36+
; CHECK-THUMB-GLOBAL-ISEL-NEXT: bl __gnu_mcount_nc
37+
call void @callee()
38+
ret void
39+
}
40+
41+
attributes #0 = { nofree nounwind "instrument-function-entry-inlined"="llvm.arm.gnu.eabi.mcount" }

llvm/test/Transforms/EntryExitInstrumenter/mcount.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ define void @f1() #1 { entry: ret void }
5454

5555
define void @f2() #2 { entry: ret void }
5656
; CHECK-LABEL: define void @f2
57-
; CHECK: call void @"\01__gnu_mcount_nc"
57+
; CHECK: call void @llvm.arm.gnu.eabi.mcount
5858

5959
define void @f3() #3 { entry: ret void }
6060
; CHECK-LABEL: define void @f3
@@ -105,7 +105,7 @@ define i8* @tailcaller2() #8 {
105105

106106
attributes #0 = { "instrument-function-entry-inlined"="mcount" "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" }
107107
attributes #1 = { "instrument-function-entry-inlined"=".mcount" }
108-
attributes #2 = { "instrument-function-entry-inlined"="\01__gnu_mcount_nc" }
108+
attributes #2 = { "instrument-function-entry-inlined"="llvm.arm.gnu.eabi.mcount" }
109109
attributes #3 = { "instrument-function-entry-inlined"="\01_mcount" }
110110
attributes #4 = { "instrument-function-entry-inlined"="\01mcount" }
111111
attributes #5 = { "instrument-function-entry-inlined"="__mcount" }

0 commit comments

Comments
 (0)