Skip to content

Commit

Permalink
[RISCV] Insert simple landing pad before indirect jumps for Zicfilp.
Browse files Browse the repository at this point in the history
This is cherry-picked from upstream pr #91860.

This patch is based on #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
  • Loading branch information
Yeting Kuo committed Jul 18, 2024
1 parent 1974e9d commit ab0b249
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 5 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ add_llvm_target(RISCVCodeGen
RISCVInstrInfo.cpp
RISCVISelDAGToDAG.cpp
RISCVISelLowering.cpp
RISCVLandingPadSetup.cpp
RISCVMachineFunctionInfo.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ void initializeRISCVDeadRegisterDefinitionsPass(PassRegistry &);
FunctionPass *createRISCVIndirectBranchTrackingPass();
void initializeRISCVIndirectBranchTrackingPass(PassRegistry &);

FunctionPass *createRISCVLandingPadSetupPass();
void initializeRISCVLandingPadSetupPass(PassRegistry &);

FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM,
CodeGenOptLevel OptLevel);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

using namespace llvm;

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

Expand Down
85 changes: 85 additions & 0 deletions llvm/lib/Target/RISCV/RISCVLandingPadSetup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===------------ RISCVLandingPadSetup.cpp ---------------------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is a RISC-V pass to setup landing pad labels for indirect jumps.
// Currently it is only supported fixed labels.
//
//===----------------------------------------------------------------------===//

#include "RISCV.h"
#include "RISCVInstrInfo.h"
#include "RISCVSubtarget.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/InitializePasses.h"

using namespace llvm;

#define DEBUG_TYPE "riscv-lpad-setup"
#define PASS_NAME "RISC-V Landing Pad Setup"

extern cl::opt<uint32_t> PreferredLandingPadLabel;

namespace {

class RISCVLandingPadSetup : public MachineFunctionPass {
public:
static char ID;

RISCVLandingPadSetup() : MachineFunctionPass(ID) {}

bool runOnMachineFunction(MachineFunction &F) override;

StringRef getPassName() const override { return PASS_NAME; }

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
MachineFunctionPass::getAnalysisUsage(AU);
}
};

} // end anonymous namespace

bool RISCVLandingPadSetup::runOnMachineFunction(MachineFunction &MF) {
const auto &STI = MF.getSubtarget<RISCVSubtarget>();
const RISCVInstrInfo &TII = *STI.getInstrInfo();

if (!STI.hasStdExtZicfilp())
return false;

bool Changed = false;
for (MachineBasicBlock &MBB : MF)
for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
if (MI.getOpcode() != RISCV::PseudoBRINDNonX7 &&
MI.getOpcode() != RISCV::PseudoCALLIndirectNonX7 &&
MI.getOpcode() != RISCV::PseudoTAILIndirectNonX7)
continue;
uint32_t Label = 0;
if (PreferredLandingPadLabel.getNumOccurrences() > 0) {
if (!isUInt<20>(PreferredLandingPadLabel))
report_fatal_error(
"riscv-landing-pad-label=<val>, <val> needs to fit in "
"unsigned 20-bits");
Label = PreferredLandingPadLabel;
}
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::LUI), RISCV::X7)
.addImm(Label);
MachineInstrBuilder(MF, &MI).addUse(RISCV::X7, RegState::ImplicitKill);
Changed = true;
}

return Changed;
}

INITIALIZE_PASS(RISCVLandingPadSetup, DEBUG_TYPE, PASS_NAME, false, false)

char RISCVLandingPadSetup::ID = 0;

FunctionPass *llvm::createRISCVLandingPadSetupPass() {
return new RISCVLandingPadSetup();
}
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ void RISCVPassConfig::addPreRegAlloc() {

addPass(createRISCVInsertReadWriteCSRPass());
addPass(createRISCVInsertWriteVXRMPass());
addPass(createRISCVLandingPadSetupPass());

// Run RISCVInsertVSETVLI after PHI elimination. On O1 and above do it after
// register coalescing so needVSETVLIPHI doesn't need to look through COPYs.
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/RISCV/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
; CHECK-NEXT: RISC-V Pre-RA pseudo instruction expansion pass
; CHECK-NEXT: RISC-V Insert Read/Write CSR Pass
; CHECK-NEXT: RISC-V Insert Write VXRM Pass
; CHECK-NEXT: RISC-V Landing Pad Setup
; CHECK-NEXT: Init Undef Pass
; CHECK-NEXT: Eliminate PHI nodes for register allocation
; CHECK-NEXT: Two-Address instruction pass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/RISCV/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
; CHECK-NEXT: RISC-V Merge Base Offset
; CHECK-NEXT: RISC-V Insert Read/Write CSR Pass
; CHECK-NEXT: RISC-V Insert Write VXRM Pass
; CHECK-NEXT: RISC-V Landing Pad Setup
; CHECK-NEXT: Detect Dead Lanes
; CHECK-NEXT: Init Undef Pass
; CHECK-NEXT: Process Implicit Definitions
Expand Down
72 changes: 68 additions & 4 deletions llvm/test/CodeGen/RISCV/lpad.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ define void @indirctbr(i32 %i, ptr %p) {
; RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
; RV32-NEXT: add a0, a2, a0
; RV32-NEXT: lw a0, 0(a0)
; RV32-NEXT: lui t2, 0
; RV32-NEXT: jr a0
; RV32-NEXT: .p2align 2
; RV32-NEXT: .Ltmp0: # Block address taken
; RV32-NEXT: .Ltmp3: # Block address taken
; RV32-NEXT: .LBB0_1: # %labelA
; RV32-NEXT: lpad 0
; RV32-NEXT: li a0, 1
; RV32-NEXT: sw a0, 0(a1)
; RV32-NEXT: .p2align 2
; RV32-NEXT: .Ltmp1: # Block address taken
; RV32-NEXT: .Ltmp4: # Block address taken
; RV32-NEXT: .LBB0_2: # %labelB
; RV32-NEXT: lpad 0
; RV32-NEXT: li a0, 2
Expand All @@ -37,15 +38,16 @@ define void @indirctbr(i32 %i, ptr %p) {
; RV64-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
; RV64-NEXT: add a0, a2, a0
; RV64-NEXT: ld a0, 0(a0)
; RV64-NEXT: lui t2, 0
; RV64-NEXT: jr a0
; RV64-NEXT: .p2align 2
; RV64-NEXT: .Ltmp0: # Block address taken
; RV64-NEXT: .Ltmp3: # Block address taken
; RV64-NEXT: .LBB0_1: # %labelA
; RV64-NEXT: lpad 0
; RV64-NEXT: li a0, 1
; RV64-NEXT: sw a0, 0(a1)
; RV64-NEXT: .p2align 2
; RV64-NEXT: .Ltmp1: # Block address taken
; RV64-NEXT: .Ltmp4: # Block address taken
; RV64-NEXT: .LBB0_2: # %labelB
; RV64-NEXT: lpad 0
; RV64-NEXT: li a0, 2
Expand All @@ -65,6 +67,68 @@ labelB: ; preds = %labelA, %entry
ret void
}

; Check indirect call.
define void @call(ptr %0) {
; CHECK-LABEL: call:
; CHECK: # %bb.0:
; CHECK-NEXT: lpad 0
; CHECK-NEXT: lui t2, 0
; CHECK-NEXT: jr a0
tail call void %0()
ret void
}

; Check invoke.
declare dso_local i32 @__gxx_personality_v0(...)
define void @invoke(ptr %f) personality ptr @__gxx_personality_v0 {
; RV32-LABEL: invoke:
; RV32: # %bb.0: # %entry
; RV32-NEXT: lpad 0
; RV32-NEXT: addi sp, sp, -16
; RV32-NEXT: .cfi_def_cfa_offset 16
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32-NEXT: .cfi_offset ra, -4
; RV32-NEXT: .Ltmp0:
; RV32-NEXT: lui t2, 0
; RV32-NEXT: jalr a0
; RV32-NEXT: .Ltmp1:
; RV32-NEXT: .LBB2_1: # %try.cont
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-NEXT: addi sp, sp, 16
; RV32-NEXT: ret
; RV32-NEXT: .LBB2_2: # %lpad
; RV32-NEXT: .Ltmp2:
; RV32-NEXT: j .LBB2_1
;
; RV64-LABEL: invoke:
; RV64: # %bb.0: # %entry
; RV64-NEXT: lpad 0
; RV64-NEXT: addi sp, sp, -16
; RV64-NEXT: .cfi_def_cfa_offset 16
; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64-NEXT: .cfi_offset ra, -8
; RV64-NEXT: .Ltmp0:
; RV64-NEXT: lui t2, 0
; RV64-NEXT: jalr a0
; RV64-NEXT: .Ltmp1:
; RV64-NEXT: .LBB2_1: # %try.cont
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 16
; RV64-NEXT: ret
; RV64-NEXT: .LBB2_2: # %lpad
; RV64-NEXT: .Ltmp2:
; RV64-NEXT: j .LBB2_1
entry:
invoke void %f() to label %try.cont unwind label %lpad

lpad:
%0 = landingpad { ptr, i32 } cleanup
br label %try.cont

try.cont:
ret void
}

; Check external linkage function.
define void @external() {
; CHECK-LABEL: external:
Expand Down

0 comments on commit ab0b249

Please sign in to comment.