Skip to content

Commit e80d8e1

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

File tree

8 files changed

+275
-5
lines changed

8 files changed

+275
-5
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

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

llvm/lib/Target/RISCV/RISCV.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ void initializeRISCVDeadRegisterDefinitionsPass(PassRegistry &);
3434
FunctionPass *createRISCVIndirectBranchTrackingPass();
3535
void initializeRISCVIndirectBranchTrackingPass(PassRegistry &);
3636

37+
FunctionPass *createRISCVLandingPadSetupPass();
38+
void initializeRISCVLandingPadSetupPass(PassRegistry &);
39+
3740
FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM,
3841
CodeGenOptLevel OptLevel);
3942

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: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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 this pass only supports 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+
uint32_t Label = 0;
56+
if (PreferredLandingPadLabel.getNumOccurrences() > 0) {
57+
if (!isUInt<20>(PreferredLandingPadLabel))
58+
report_fatal_error("riscv-landing-pad-label=<val>, <val> needs to fit in "
59+
"unsigned 20-bits");
60+
Label = PreferredLandingPadLabel;
61+
}
62+
63+
// Zicfilp does not check X7 if landing pad label is zero.
64+
if (Label == 0)
65+
return false;
66+
67+
bool Changed = false;
68+
for (MachineBasicBlock &MBB : MF)
69+
for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
70+
if (MI.getOpcode() != RISCV::PseudoBRINDNonX7 &&
71+
MI.getOpcode() != RISCV::PseudoCALLIndirectNonX7 &&
72+
MI.getOpcode() != RISCV::PseudoTAILIndirectNonX7)
73+
continue;
74+
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::LUI), RISCV::X7)
75+
.addImm(Label);
76+
MachineInstrBuilder(MF, &MI).addUse(RISCV::X7, RegState::ImplicitKill);
77+
Changed = true;
78+
}
79+
80+
return Changed;
81+
}
82+
83+
INITIALIZE_PASS(RISCVLandingPadSetup, DEBUG_TYPE, PASS_NAME, false, false)
84+
85+
char RISCVLandingPadSetup::ID = 0;
86+
87+
FunctionPass *llvm::createRISCVLandingPadSetupPass() {
88+
return new RISCVLandingPadSetup();
89+
}

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ void RISCVPassConfig::addPreRegAlloc() {
554554

555555
addPass(createRISCVInsertReadWriteCSRPass());
556556
addPass(createRISCVInsertWriteVXRMPass());
557+
addPass(createRISCVLandingPadSetupPass());
557558

558559
// Run RISCVInsertVSETVLI after PHI elimination. On O1 and above do it after
559560
// register coalescing so needVSETVLIPHI doesn't need to look through COPYs.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
; CHECK-NEXT: RISC-V Pre-RA pseudo instruction expansion pass
4242
; CHECK-NEXT: RISC-V Insert Read/Write CSR Pass
4343
; CHECK-NEXT: RISC-V Insert Write VXRM Pass
44+
; CHECK-NEXT: RISC-V Landing Pad Setup
4445
; CHECK-NEXT: Init Undef Pass
4546
; CHECK-NEXT: Eliminate PHI nodes for register allocation
4647
; 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
@@ -116,6 +116,7 @@
116116
; CHECK-NEXT: RISC-V Merge Base Offset
117117
; CHECK-NEXT: RISC-V Insert Read/Write CSR Pass
118118
; CHECK-NEXT: RISC-V Insert Write VXRM Pass
119+
; CHECK-NEXT: RISC-V Landing Pad Setup
119120
; CHECK-NEXT: Detect Dead Lanes
120121
; CHECK-NEXT: Init Undef Pass
121122
; CHECK-NEXT: Process Implicit Definitions

llvm/test/CodeGen/RISCV/lpad.ll

Lines changed: 178 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
22
; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV32
33
; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV64
4+
; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp \
5+
; RUN: -riscv-landing-pad-label=1 < %s | FileCheck %s --check-prefixes=FIXED-ONE,FIXED-ONE-RV32
6+
; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp \
7+
; RUN: -riscv-landing-pad-label=1 < %s | FileCheck %s --check-prefixes=FIXED-ONE,FIXED-ONE-RV64
48

59
; Check indirectbr.
610
@__const.indirctbr.addr = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@indirctbr, %labelA), ptr blockaddress(@indirctbr, %labelB)], align 8
@@ -15,13 +19,13 @@ define void @indirctbr(i32 %i, ptr %p) {
1519
; RV32-NEXT: lw a0, 0(a0)
1620
; RV32-NEXT: jr a0
1721
; RV32-NEXT: .p2align 2
18-
; RV32-NEXT: .Ltmp0: # Block address taken
22+
; RV32-NEXT: .Ltmp3: # Block address taken
1923
; RV32-NEXT: .LBB0_1: # %labelA
2024
; RV32-NEXT: lpad 0
2125
; RV32-NEXT: li a0, 1
2226
; RV32-NEXT: sw a0, 0(a1)
2327
; RV32-NEXT: .p2align 2
24-
; RV32-NEXT: .Ltmp1: # Block address taken
28+
; RV32-NEXT: .Ltmp4: # Block address taken
2529
; RV32-NEXT: .LBB0_2: # %labelB
2630
; RV32-NEXT: lpad 0
2731
; RV32-NEXT: li a0, 2
@@ -39,18 +43,67 @@ define void @indirctbr(i32 %i, ptr %p) {
3943
; RV64-NEXT: ld a0, 0(a0)
4044
; RV64-NEXT: jr a0
4145
; RV64-NEXT: .p2align 2
42-
; RV64-NEXT: .Ltmp0: # Block address taken
46+
; RV64-NEXT: .Ltmp3: # Block address taken
4347
; RV64-NEXT: .LBB0_1: # %labelA
4448
; RV64-NEXT: lpad 0
4549
; RV64-NEXT: li a0, 1
4650
; RV64-NEXT: sw a0, 0(a1)
4751
; RV64-NEXT: .p2align 2
48-
; RV64-NEXT: .Ltmp1: # Block address taken
52+
; RV64-NEXT: .Ltmp4: # Block address taken
4953
; RV64-NEXT: .LBB0_2: # %labelB
5054
; RV64-NEXT: lpad 0
5155
; RV64-NEXT: li a0, 2
5256
; RV64-NEXT: sw a0, 0(a1)
5357
; RV64-NEXT: ret
58+
;
59+
; FIXED-ONE-RV32-LABEL: indirctbr:
60+
; FIXED-ONE-RV32: # %bb.0: # %entry
61+
; FIXED-ONE-RV32-NEXT: lpad 1
62+
; FIXED-ONE-RV32-NEXT: slli a0, a0, 2
63+
; FIXED-ONE-RV32-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
64+
; FIXED-ONE-RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
65+
; FIXED-ONE-RV32-NEXT: add a0, a2, a0
66+
; FIXED-ONE-RV32-NEXT: lw a0, 0(a0)
67+
; FIXED-ONE-RV32-NEXT: lui t2, 1
68+
; FIXED-ONE-RV32-NEXT: jr a0
69+
; FIXED-ONE-RV32-NEXT: .p2align 2
70+
; FIXED-ONE-RV32-NEXT: .Ltmp3: # Block address taken
71+
; FIXED-ONE-RV32-NEXT: .LBB0_1: # %labelA
72+
; FIXED-ONE-RV32-NEXT: lpad 1
73+
; FIXED-ONE-RV32-NEXT: li a0, 1
74+
; FIXED-ONE-RV32-NEXT: sw a0, 0(a1)
75+
; FIXED-ONE-RV32-NEXT: .p2align 2
76+
; FIXED-ONE-RV32-NEXT: .Ltmp4: # Block address taken
77+
; FIXED-ONE-RV32-NEXT: .LBB0_2: # %labelB
78+
; FIXED-ONE-RV32-NEXT: lpad 1
79+
; FIXED-ONE-RV32-NEXT: li a0, 2
80+
; FIXED-ONE-RV32-NEXT: sw a0, 0(a1)
81+
; FIXED-ONE-RV32-NEXT: ret
82+
;
83+
; FIXED-ONE-RV64-LABEL: indirctbr:
84+
; FIXED-ONE-RV64: # %bb.0: # %entry
85+
; FIXED-ONE-RV64-NEXT: lpad 1
86+
; FIXED-ONE-RV64-NEXT: sext.w a0, a0
87+
; FIXED-ONE-RV64-NEXT: slli a0, a0, 3
88+
; FIXED-ONE-RV64-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
89+
; FIXED-ONE-RV64-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
90+
; FIXED-ONE-RV64-NEXT: add a0, a2, a0
91+
; FIXED-ONE-RV64-NEXT: ld a0, 0(a0)
92+
; FIXED-ONE-RV64-NEXT: lui t2, 1
93+
; FIXED-ONE-RV64-NEXT: jr a0
94+
; FIXED-ONE-RV64-NEXT: .p2align 2
95+
; FIXED-ONE-RV64-NEXT: .Ltmp3: # Block address taken
96+
; FIXED-ONE-RV64-NEXT: .LBB0_1: # %labelA
97+
; FIXED-ONE-RV64-NEXT: lpad 1
98+
; FIXED-ONE-RV64-NEXT: li a0, 1
99+
; FIXED-ONE-RV64-NEXT: sw a0, 0(a1)
100+
; FIXED-ONE-RV64-NEXT: .p2align 2
101+
; FIXED-ONE-RV64-NEXT: .Ltmp4: # Block address taken
102+
; FIXED-ONE-RV64-NEXT: .LBB0_2: # %labelB
103+
; FIXED-ONE-RV64-NEXT: lpad 1
104+
; FIXED-ONE-RV64-NEXT: li a0, 2
105+
; FIXED-ONE-RV64-NEXT: sw a0, 0(a1)
106+
; FIXED-ONE-RV64-NEXT: ret
54107
entry:
55108
%arrayidx = getelementptr inbounds [2 x ptr], ptr @__const.indirctbr.addr, i64 0, i32 %i
56109
%0 = load ptr, ptr %arrayidx
@@ -65,12 +118,120 @@ labelB: ; preds = %labelA, %entry
65118
ret void
66119
}
67120

121+
; Check indirect call.
122+
define void @call(ptr %0) {
123+
; CHECK-LABEL: call:
124+
; CHECK: # %bb.0:
125+
; CHECK-NEXT: lpad 0
126+
; CHECK-NEXT: jr a0
127+
;
128+
; FIXED-ONE-LABEL: call:
129+
; FIXED-ONE: # %bb.0:
130+
; FIXED-ONE-NEXT: lpad 1
131+
; FIXED-ONE-NEXT: lui t2, 1
132+
; FIXED-ONE-NEXT: jr a0
133+
tail call void %0()
134+
ret void
135+
}
136+
137+
; Check invoke.
138+
declare dso_local i32 @__gxx_personality_v0(...)
139+
define void @invoke(ptr %f) personality ptr @__gxx_personality_v0 {
140+
; RV32-LABEL: invoke:
141+
; RV32: # %bb.0: # %entry
142+
; RV32-NEXT: lpad 0
143+
; RV32-NEXT: addi sp, sp, -16
144+
; RV32-NEXT: .cfi_def_cfa_offset 16
145+
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
146+
; RV32-NEXT: .cfi_offset ra, -4
147+
; RV32-NEXT: .Ltmp0:
148+
; RV32-NEXT: jalr a0
149+
; RV32-NEXT: .Ltmp1:
150+
; RV32-NEXT: .LBB2_1: # %try.cont
151+
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
152+
; RV32-NEXT: addi sp, sp, 16
153+
; RV32-NEXT: ret
154+
; RV32-NEXT: .LBB2_2: # %lpad
155+
; RV32-NEXT: .Ltmp2:
156+
; RV32-NEXT: j .LBB2_1
157+
;
158+
; RV64-LABEL: invoke:
159+
; RV64: # %bb.0: # %entry
160+
; RV64-NEXT: lpad 0
161+
; RV64-NEXT: addi sp, sp, -16
162+
; RV64-NEXT: .cfi_def_cfa_offset 16
163+
; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
164+
; RV64-NEXT: .cfi_offset ra, -8
165+
; RV64-NEXT: .Ltmp0:
166+
; RV64-NEXT: jalr a0
167+
; RV64-NEXT: .Ltmp1:
168+
; RV64-NEXT: .LBB2_1: # %try.cont
169+
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
170+
; RV64-NEXT: addi sp, sp, 16
171+
; RV64-NEXT: ret
172+
; RV64-NEXT: .LBB2_2: # %lpad
173+
; RV64-NEXT: .Ltmp2:
174+
; RV64-NEXT: j .LBB2_1
175+
;
176+
; FIXED-ONE-RV32-LABEL: invoke:
177+
; FIXED-ONE-RV32: # %bb.0: # %entry
178+
; FIXED-ONE-RV32-NEXT: lpad 1
179+
; FIXED-ONE-RV32-NEXT: addi sp, sp, -16
180+
; FIXED-ONE-RV32-NEXT: .cfi_def_cfa_offset 16
181+
; FIXED-ONE-RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
182+
; FIXED-ONE-RV32-NEXT: .cfi_offset ra, -4
183+
; FIXED-ONE-RV32-NEXT: .Ltmp0:
184+
; FIXED-ONE-RV32-NEXT: lui t2, 1
185+
; FIXED-ONE-RV32-NEXT: jalr a0
186+
; FIXED-ONE-RV32-NEXT: .Ltmp1:
187+
; FIXED-ONE-RV32-NEXT: .LBB2_1: # %try.cont
188+
; FIXED-ONE-RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
189+
; FIXED-ONE-RV32-NEXT: addi sp, sp, 16
190+
; FIXED-ONE-RV32-NEXT: ret
191+
; FIXED-ONE-RV32-NEXT: .LBB2_2: # %lpad
192+
; FIXED-ONE-RV32-NEXT: .Ltmp2:
193+
; FIXED-ONE-RV32-NEXT: j .LBB2_1
194+
;
195+
; FIXED-ONE-RV64-LABEL: invoke:
196+
; FIXED-ONE-RV64: # %bb.0: # %entry
197+
; FIXED-ONE-RV64-NEXT: lpad 1
198+
; FIXED-ONE-RV64-NEXT: addi sp, sp, -16
199+
; FIXED-ONE-RV64-NEXT: .cfi_def_cfa_offset 16
200+
; FIXED-ONE-RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
201+
; FIXED-ONE-RV64-NEXT: .cfi_offset ra, -8
202+
; FIXED-ONE-RV64-NEXT: .Ltmp0:
203+
; FIXED-ONE-RV64-NEXT: lui t2, 1
204+
; FIXED-ONE-RV64-NEXT: jalr a0
205+
; FIXED-ONE-RV64-NEXT: .Ltmp1:
206+
; FIXED-ONE-RV64-NEXT: .LBB2_1: # %try.cont
207+
; FIXED-ONE-RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
208+
; FIXED-ONE-RV64-NEXT: addi sp, sp, 16
209+
; FIXED-ONE-RV64-NEXT: ret
210+
; FIXED-ONE-RV64-NEXT: .LBB2_2: # %lpad
211+
; FIXED-ONE-RV64-NEXT: .Ltmp2:
212+
; FIXED-ONE-RV64-NEXT: j .LBB2_1
213+
entry:
214+
invoke void %f() to label %try.cont unwind label %lpad
215+
216+
lpad:
217+
%0 = landingpad { ptr, i32 } cleanup
218+
br label %try.cont
219+
220+
try.cont:
221+
ret void
222+
}
223+
68224
; Check external linkage function.
69225
define void @external() {
70226
; CHECK-LABEL: external:
71227
; CHECK: # %bb.0:
72228
; CHECK-NEXT: lpad 0
73229
; CHECK-NEXT: ret
230+
;
231+
; FIXED-ONE-LABEL: external:
232+
; FIXED-ONE: # %bb.0:
233+
; FIXED-ONE-NEXT: lpad 1
234+
; FIXED-ONE-NEXT: ret
74235
ret void
75236
}
76237

@@ -79,6 +240,10 @@ define internal void @internal() {
79240
; CHECK-LABEL: internal:
80241
; CHECK: # %bb.0:
81242
; CHECK-NEXT: ret
243+
;
244+
; FIXED-ONE-LABEL: internal:
245+
; FIXED-ONE: # %bb.0:
246+
; FIXED-ONE-NEXT: ret
82247
ret void
83248
}
84249

@@ -89,6 +254,11 @@ define internal void @internal2() {
89254
; CHECK: # %bb.0:
90255
; CHECK-NEXT: lpad 0
91256
; CHECK-NEXT: ret
257+
;
258+
; FIXED-ONE-LABEL: internal2:
259+
; FIXED-ONE: # %bb.0:
260+
; FIXED-ONE-NEXT: lpad 1
261+
; FIXED-ONE-NEXT: ret
92262
ret void
93263
}
94264

@@ -97,5 +267,9 @@ define void @interrupt() "interrupt"="user" {
97267
; CHECK-LABEL: interrupt:
98268
; CHECK: # %bb.0:
99269
; CHECK-NEXT: mret
270+
;
271+
; FIXED-ONE-LABEL: interrupt:
272+
; FIXED-ONE: # %bb.0:
273+
; FIXED-ONE-NEXT: mret
100274
ret void
101275
}

0 commit comments

Comments
 (0)