Skip to content

Commit b77fb28

Browse files
author
Yeting Kuo
committed
[RISCV] Insert simple landing pad before indirect jumps for Zicfilp.
This patch is based on llvm#91855. This patch inserts simple landing pad ([pr])before indirct jumps. And also make option riscv-landing-pad-label influence this feature. [pr]: riscv-non-isa/riscv-elf-psabi-doc#417
1 parent a7b428f commit b77fb28

File tree

8 files changed

+156
-9
lines changed

8 files changed

+156
-9
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ add_llvm_target(RISCVCodeGen
4444
RISCVInstrInfo.cpp
4545
RISCVISelDAGToDAG.cpp
4646
RISCVISelLowering.cpp
47+
RISCVLandingPadSetup.cpp
4748
RISCVMachineFunctionInfo.cpp
4849
RISCVMergeBaseOffset.cpp
4950
RISCVOptWInstrs.cpp

llvm/lib/Target/RISCV/RISCV.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ void initializeRISCVIndirectBranchTrackingPass(PassRegistry &);
3737
FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM,
3838
CodeGenOptLevel OptLevel);
3939

40+
FunctionPass *createRISCVLandingPadSetupPass();
41+
void initializeRISCVLandingPadSetupPass(PassRegistry &);
42+
4043
FunctionPass *createRISCVMakeCompressibleOptPass();
4144
void initializeRISCVMakeCompressibleOptPass(PassRegistry &);
4245

llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
using namespace llvm;
2525

26-
static cl::opt<uint32_t> PreferredLandingPadLabel(
26+
cl::opt<uint32_t> PreferredLandingPadLabel(
2727
"riscv-landing-pad-label", cl::ReallyHidden,
2828
cl::desc("Use preferred fixed label for all labels"));
2929

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//===------------ RISCVLandingPadSetup.cpp ---------------------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This is a RISC-V pass to setup landing pad labels for indirect jumps.
10+
// Currently it is only supported fixed labels.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "RISCV.h"
15+
#include "RISCVInstrInfo.h"
16+
#include "RISCVSubtarget.h"
17+
#include "llvm/CodeGen/MachineFunctionPass.h"
18+
#include "llvm/CodeGen/MachineInstrBuilder.h"
19+
#include "llvm/InitializePasses.h"
20+
21+
using namespace llvm;
22+
23+
#define DEBUG_TYPE "riscv-lpad-setup"
24+
#define PASS_NAME "RISC-V Landing Pad Setup"
25+
26+
extern cl::opt<uint32_t> PreferredLandingPadLabel;
27+
28+
namespace {
29+
30+
class RISCVLandingPadSetup : public MachineFunctionPass {
31+
public:
32+
static char ID;
33+
34+
RISCVLandingPadSetup() : MachineFunctionPass(ID) {}
35+
36+
bool runOnMachineFunction(MachineFunction &F) override;
37+
38+
StringRef getPassName() const override { return PASS_NAME; }
39+
40+
void getAnalysisUsage(AnalysisUsage &AU) const override {
41+
AU.setPreservesCFG();
42+
MachineFunctionPass::getAnalysisUsage(AU);
43+
}
44+
};
45+
46+
} // end anonymous namespace
47+
48+
bool RISCVLandingPadSetup::runOnMachineFunction(MachineFunction &MF) {
49+
const auto &STI = MF.getSubtarget<RISCVSubtarget>();
50+
const RISCVInstrInfo &TII = *STI.getInstrInfo();
51+
52+
if (!STI.hasStdExtZicfilp())
53+
return false;
54+
55+
bool Changed = false;
56+
for (MachineBasicBlock &MBB : MF)
57+
for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
58+
if (!MI.isIndirectBranch() &&
59+
MI.getOpcode() != RISCV::PseudoCALLIndirectNonX7 &&
60+
MI.getOpcode() != RISCV::PseudoTAILIndirectNonX7)
61+
continue;
62+
uint32_t Label = 0;
63+
if (PreferredLandingPadLabel.getNumOccurrences() > 0) {
64+
if (!isUInt<20>(PreferredLandingPadLabel))
65+
report_fatal_error(
66+
"riscv-landing-pad-label=<val>, <val> needs to fit in "
67+
"unsigned 20-bits");
68+
Label = PreferredLandingPadLabel;
69+
}
70+
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::LUI), RISCV::X7)
71+
.addImm(Label);
72+
MachineInstrBuilder(MF, &MI).addUse(RISCV::X7, RegState::ImplicitKill);
73+
Changed = true;
74+
}
75+
76+
return Changed;
77+
}
78+
79+
INITIALIZE_PASS(RISCVLandingPadSetup, DEBUG_TYPE, PASS_NAME, false, false)
80+
81+
char RISCVLandingPadSetup::ID = 0;
82+
83+
FunctionPass *llvm::createRISCVLandingPadSetupPass() {
84+
return new RISCVLandingPadSetup();
85+
}

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ void RISCVPassConfig::addPreRegAlloc() {
545545
addPass(createRISCVInsertReadWriteCSRPass());
546546
addPass(createRISCVInsertWriteVXRMPass());
547547
addPass(createRISCVInsertVSETVLIPass());
548+
addPass(createRISCVLandingPadSetupPass());
548549
}
549550

550551
void RISCVPassConfig::addFastRegAlloc() {

llvm/test/CodeGen/RISCV/O0-pipeline.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
; CHECK-NEXT: RISC-V Insert Read/Write CSR Pass
4444
; CHECK-NEXT: RISC-V Insert Write VXRM Pass
4545
; CHECK-NEXT: RISC-V Insert VSETVLI pass
46+
; CHECK-NEXT: RISC-V Landing Pad Setup
4647
; CHECK-NEXT: Init Undef Pass
4748
; CHECK-NEXT: Eliminate PHI nodes for register allocation
4849
; CHECK-NEXT: Two-Address instruction pass

llvm/test/CodeGen/RISCV/O3-pipeline.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
; CHECK-NEXT: RISC-V Insert Read/Write CSR Pass
119119
; CHECK-NEXT: RISC-V Insert Write VXRM Pass
120120
; CHECK-NEXT: RISC-V Insert VSETVLI pass
121+
; CHECK-NEXT: RISC-V Landing Pad Setup
121122
; CHECK-NEXT: Detect Dead Lanes
122123
; CHECK-NEXT: Init Undef Pass
123124
; CHECK-NEXT: Process Implicit Definitions

llvm/test/CodeGen/RISCV/lpad.ll

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ define void @indirctbr(i32 %i, ptr %p) {
1313
; RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
1414
; RV32-NEXT: add a0, a2, a0
1515
; RV32-NEXT: lw a0, 0(a0)
16+
; RV32-NEXT: lui t2, 0
1617
; RV32-NEXT: jr a0
1718
; RV32-NEXT: .p2align 2
18-
; RV32-NEXT: .Ltmp0: # Block address taken
19+
; RV32-NEXT: .Ltmp3: # Block address taken
1920
; RV32-NEXT: .LBB0_1: # %labelA
2021
; RV32-NEXT: lpad 0
2122
; RV32-NEXT: li a0, 1
2223
; RV32-NEXT: sw a0, 0(a1)
2324
; RV32-NEXT: .p2align 2
24-
; RV32-NEXT: .Ltmp1: # Block address taken
25+
; RV32-NEXT: .Ltmp4: # Block address taken
2526
; RV32-NEXT: .LBB0_2: # %labelB
2627
; RV32-NEXT: lpad 0
2728
; RV32-NEXT: li a0, 2
@@ -37,15 +38,16 @@ define void @indirctbr(i32 %i, ptr %p) {
3738
; RV64-NEXT: slli a0, a0, 3
3839
; RV64-NEXT: add a0, a2, a0
3940
; RV64-NEXT: ld a0, 0(a0)
41+
; RV64-NEXT: lui t2, 0
4042
; RV64-NEXT: jr a0
4143
; RV64-NEXT: .p2align 2
42-
; RV64-NEXT: .Ltmp0: # Block address taken
44+
; RV64-NEXT: .Ltmp3: # Block address taken
4345
; RV64-NEXT: .LBB0_1: # %labelA
4446
; RV64-NEXT: lpad 0
4547
; RV64-NEXT: li a0, 1
4648
; RV64-NEXT: sw a0, 0(a1)
4749
; RV64-NEXT: .p2align 2
48-
; RV64-NEXT: .Ltmp1: # Block address taken
50+
; RV64-NEXT: .Ltmp4: # Block address taken
4951
; RV64-NEXT: .LBB0_2: # %labelB
5052
; RV64-NEXT: lpad 0
5153
; RV64-NEXT: li a0, 2
@@ -65,12 +67,65 @@ labelB: ; preds = %labelA, %entry
6567
ret void
6668
}
6769

68-
; Check external linkage function.
69-
define void @external() {
70-
; CHECK-LABEL: external:
70+
; Check call.
71+
define void @call(ptr %0) {
72+
; CHECK-LABEL: call:
7173
; CHECK: # %bb.0:
7274
; CHECK-NEXT: lpad 0
73-
; CHECK-NEXT: ret
75+
; CHECK-NEXT: lui t2, 0
76+
; CHECK-NEXT: jr a0
77+
tail call void %0()
78+
ret void
79+
}
80+
81+
; Check invoke.
82+
declare dso_local i32 @__gxx_personality_v0(...)
83+
define void @invoke(ptr %f) personality ptr @__gxx_personality_v0 {
84+
; RV32-LABEL: invoke:
85+
; RV32: # %bb.0: # %entry
86+
; RV32-NEXT: lpad 0
87+
; RV32-NEXT: addi sp, sp, -16
88+
; RV32-NEXT: .cfi_def_cfa_offset 16
89+
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
90+
; RV32-NEXT: .cfi_offset ra, -4
91+
; RV32-NEXT: .Ltmp0:
92+
; RV32-NEXT: lui t2, 0
93+
; RV32-NEXT: jalr a0
94+
; RV32-NEXT: .Ltmp1:
95+
; RV32-NEXT: .LBB2_1: # %try.cont
96+
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
97+
; RV32-NEXT: addi sp, sp, 16
98+
; RV32-NEXT: ret
99+
; RV32-NEXT: .LBB2_2: # %lpad
100+
; RV32-NEXT: .Ltmp2:
101+
; RV32-NEXT: j .LBB2_1
102+
;
103+
; RV64-LABEL: invoke:
104+
; RV64: # %bb.0: # %entry
105+
; RV64-NEXT: lpad 0
106+
; RV64-NEXT: addi sp, sp, -16
107+
; RV64-NEXT: .cfi_def_cfa_offset 16
108+
; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
109+
; RV64-NEXT: .cfi_offset ra, -8
110+
; RV64-NEXT: .Ltmp0:
111+
; RV64-NEXT: lui t2, 0
112+
; RV64-NEXT: jalr a0
113+
; RV64-NEXT: .Ltmp1:
114+
; RV64-NEXT: .LBB2_1: # %try.cont
115+
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
116+
; RV64-NEXT: addi sp, sp, 16
117+
; RV64-NEXT: ret
118+
; RV64-NEXT: .LBB2_2: # %lpad
119+
; RV64-NEXT: .Ltmp2:
120+
; RV64-NEXT: j .LBB2_1
121+
entry:
122+
invoke void %f() to label %try.cont unwind label %lpad
123+
124+
lpad:
125+
%0 = landingpad { ptr, i32 } cleanup
126+
br label %try.cont
127+
128+
try.cont:
74129
ret void
75130
}
76131

0 commit comments

Comments
 (0)