[llvm] [RISCV] Insert simple landing pad before indirect jumps for Zicfilp. (PR #91860)
Yeting Kuo via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 5 04:10:48 PDT 2024
https://github.com/yetingk updated https://github.com/llvm/llvm-project/pull/91860
>From ce0d8abb03887dd301b4d1207fb5c1537624247b Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 8 Aug 2023 17:29:45 +0800
Subject: [PATCH 1/2] [RISCV] Insert simple landing pad for taken address
labels.
This patch implements simple landing pad labels [0]. When Zicfilp enabled, this
patch inserts `lpad 0` at the beginning of basic blocks which are possible to be
landed by indirect jumps.
This patch also supports option riscv-landing-pad-label to make users
cpable to set nonzero fixed labels. Using nonzero fixed label force
setting t2 before indirect jumps. It's less portable but more strict than
original implementation.
[0]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/417
---
llvm/lib/Target/RISCV/CMakeLists.txt | 1 +
llvm/lib/Target/RISCV/RISCV.h | 3 +
.../RISCV/RISCVIndirectBranchTracking.cpp | 102 ++++++++++++++++++
llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 1 +
llvm/test/CodeGen/RISCV/O0-pipeline.ll | 1 +
llvm/test/CodeGen/RISCV/O3-pipeline.ll | 1 +
.../test/CodeGen/RISCV/jumptable-swguarded.ll | 1 +
llvm/test/CodeGen/RISCV/lpad.ll | 101 +++++++++++++++++
8 files changed, 211 insertions(+)
create mode 100644 llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
create mode 100644 llvm/test/CodeGen/RISCV/lpad.ll
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index f28a7092e3cec..5146e519c3529 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -36,6 +36,7 @@ add_llvm_target(RISCVCodeGen
RISCVExpandPseudoInsts.cpp
RISCVFrameLowering.cpp
RISCVGatherScatterLowering.cpp
+ RISCVIndirectBranchTracking.cpp
RISCVInsertVSETVLI.cpp
RISCVInsertReadWriteCSR.cpp
RISCVInsertWriteVXRM.cpp
diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 0d2473c7c5de1..80cb395291496 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -31,6 +31,9 @@ void initializeRISCVCodeGenPreparePass(PassRegistry &);
FunctionPass *createRISCVDeadRegisterDefinitionsPass();
void initializeRISCVDeadRegisterDefinitionsPass(PassRegistry &);
+FunctionPass *createRISCVIndirectBranchTrackingPass();
+void initializeRISCVIndirectBranchTrackingPass(PassRegistry &);
+
FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM,
CodeGenOptLevel OptLevel);
diff --git a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
new file mode 100644
index 0000000000000..1b484d486edcb
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
@@ -0,0 +1,102 @@
+//===------ RISCVIndirectBranchTracking.cpp - Enables lpad mechanism ------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// The pass adds LPAD (AUIPC with rs1 = X0) machine instructions at the
+// beginning of each basic block or function that is referenced by an indrect
+// jump/call instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "RISCVInstrInfo.h"
+#include "RISCVSubtarget.h"
+#include "RISCVTargetMachine.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+
+using namespace llvm;
+
+static cl::opt<uint32_t> PreferredLandingPadLabel(
+ "riscv-landing-pad-label", cl::ReallyHidden,
+ cl::desc("Use preferred fixed label for all labels"));
+
+namespace {
+class RISCVIndirectBranchTrackingPass : public MachineFunctionPass {
+public:
+ RISCVIndirectBranchTrackingPass() : MachineFunctionPass(ID) {}
+
+ StringRef getPassName() const override {
+ return "RISC-V Indirect Branch Tracking";
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+ static char ID;
+ const Align LpadAlign = Align(4);
+};
+
+} // end anonymous namespace
+
+char RISCVIndirectBranchTrackingPass::ID = 0;
+
+FunctionPass *llvm::createRISCVIndirectBranchTrackingPass() {
+ return new RISCVIndirectBranchTrackingPass();
+}
+
+static void emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII,
+ uint32_t Label) {
+ auto I = MBB.begin();
+ BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(RISCV::AUIPC), RISCV::X0)
+ .addImm(Label);
+}
+
+bool RISCVIndirectBranchTrackingPass::runOnMachineFunction(
+ MachineFunction &MF) {
+ const auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
+ const RISCVInstrInfo *TII = Subtarget.getInstrInfo();
+ if (!Subtarget.hasStdExtZicfilp())
+ return false;
+
+ uint32_t FixedLabel = 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");
+ FixedLabel = PreferredLandingPadLabel;
+ }
+
+ bool Changed = false;
+ for (MachineBasicBlock &MBB : MF) {
+ if (&MBB == &MF.front()) {
+ Function &F = MF.getFunction();
+ // When trap is taken, landing pad is not needed.
+ if (F.hasFnAttribute("interrupt"))
+ continue;
+
+ if (F.hasAddressTaken() || !F.hasLocalLinkage()) {
+ emitLpad(MBB, TII, FixedLabel);
+ if (MF.getAlignment() < LpadAlign)
+ MF.setAlignment(LpadAlign);
+ Changed = true;
+ }
+ continue;
+ }
+
+ if (MBB.hasAddressTaken()) {
+ emitLpad(MBB, TII, FixedLabel);
+ if (MBB.getAlignment() < LpadAlign)
+ MBB.setAlignment(LpadAlign);
+ Changed = true;
+ }
+ }
+
+ return Changed;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 21fbf47875e68..8b3770aeb5d13 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -520,6 +520,7 @@ void RISCVPassConfig::addPreEmitPass2() {
// ensuring return instruction is detected correctly.
addPass(createRISCVPushPopOptimizationPass());
}
+ addPass(createRISCVIndirectBranchTrackingPass());
addPass(createRISCVExpandPseudoPass());
// Schedule the expansion of AMOs at the last possible moment, avoiding the
diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
index fd2ba49ea8610..c1b081edacc7b 100644
--- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
@@ -69,6 +69,7 @@
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
; CHECK-NEXT: Machine Optimization Remark Emitter
; CHECK-NEXT: Stack Frame Layout Analysis
+; CHECK-NEXT: RISC-V Indirect Branch Tracking
; CHECK-NEXT: RISC-V pseudo instruction expansion pass
; CHECK-NEXT: RISC-V atomic pseudo instruction expansion pass
; CHECK-NEXT: Unpack machine instruction bundles
diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
index d6d0cca6ddae7..fe63cc808dece 100644
--- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
@@ -195,6 +195,7 @@
; CHECK-NEXT: Stack Frame Layout Analysis
; CHECK-NEXT: RISC-V Zcmp move merging pass
; CHECK-NEXT: RISC-V Zcmp Push/Pop optimization pass
+; CHECK-NEXT: RISC-V Indirect Branch Tracking
; CHECK-NEXT: RISC-V pseudo instruction expansion pass
; CHECK-NEXT: RISC-V atomic pseudo instruction expansion pass
; CHECK-NEXT: Unpack machine instruction bundles
diff --git a/llvm/test/CodeGen/RISCV/jumptable-swguarded.ll b/llvm/test/CodeGen/RISCV/jumptable-swguarded.ll
index 9d57ca74cd78a..0e87d8d6f82fe 100644
--- a/llvm/test/CodeGen/RISCV/jumptable-swguarded.ll
+++ b/llvm/test/CodeGen/RISCV/jumptable-swguarded.ll
@@ -8,6 +8,7 @@
define void @above_threshold(i32 signext %in, ptr %out) nounwind {
; CHECK-LABEL: above_threshold:
; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lpad 0
; CHECK-NEXT: addi a0, a0, -1
; CHECK-NEXT: li a2, 5
; CHECK-NEXT: bltu a2, a0, .LBB0_9
diff --git a/llvm/test/CodeGen/RISCV/lpad.ll b/llvm/test/CodeGen/RISCV/lpad.ll
new file mode 100644
index 0000000000000..de82a9ee4e34b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/lpad.ll
@@ -0,0 +1,101 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV32
+; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV64
+
+; Check indirectbr.
+ at __const.indirctbr.addr = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@indirctbr, %labelA), ptr blockaddress(@indirctbr, %labelB)], align 8
+define void @indirctbr(i32 %i, ptr %p) {
+; RV32-LABEL: indirctbr:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lpad 0
+; RV32-NEXT: slli a0, a0, 2
+; RV32-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
+; RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
+; RV32-NEXT: add a0, a2, a0
+; RV32-NEXT: lw a0, 0(a0)
+; RV32-NEXT: jr a0
+; RV32-NEXT: .p2align 2
+; RV32-NEXT: .Ltmp0: # 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: .LBB0_2: # %labelB
+; RV32-NEXT: lpad 0
+; RV32-NEXT: li a0, 2
+; RV32-NEXT: sw a0, 0(a1)
+; RV32-NEXT: ret
+;
+; RV64-LABEL: indirctbr:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lpad 0
+; RV64-NEXT: sext.w a0, a0
+; RV64-NEXT: slli a0, a0, 3
+; RV64-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
+; RV64-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
+; RV64-NEXT: add a0, a2, a0
+; RV64-NEXT: ld a0, 0(a0)
+; RV64-NEXT: jr a0
+; RV64-NEXT: .p2align 2
+; RV64-NEXT: .Ltmp0: # 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: .LBB0_2: # %labelB
+; RV64-NEXT: lpad 0
+; RV64-NEXT: li a0, 2
+; RV64-NEXT: sw a0, 0(a1)
+; RV64-NEXT: ret
+entry:
+ %arrayidx = getelementptr inbounds [2 x ptr], ptr @__const.indirctbr.addr, i64 0, i32 %i
+ %0 = load ptr, ptr %arrayidx
+ indirectbr ptr %0, [label %labelA, label %labelB]
+
+labelA: ; preds = %entry
+ store volatile i32 1, ptr %p
+ br label %labelB
+
+labelB: ; preds = %labelA, %entry
+ store volatile i32 2, ptr %p
+ ret void
+}
+
+; Check external linkage function.
+define void @external() {
+; CHECK-LABEL: external:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lpad 0
+; CHECK-NEXT: ret
+ ret void
+}
+
+; Check internal linkage function.
+define internal void @internal() {
+; CHECK-LABEL: internal:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ret
+ ret void
+}
+
+; Check internal linkage function with taken address.
+ at foo = constant ptr @internal2
+define internal void @internal2() {
+; CHECK-LABEL: internal2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lpad 0
+; CHECK-NEXT: ret
+ ret void
+}
+
+; Check interrupt function does not need landing pad.
+define void @interrupt() "interrupt"="user" {
+; CHECK-LABEL: interrupt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mret
+ ret void
+}
>From 291a909a33ac64f8604af1b450fde34850b54fe5 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 16 Jul 2024 01:46:06 -0700
Subject: [PATCH 2/2] [RISCV] Insert simple landing pad before indirect jumps
for Zicfilp.
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]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/417
---
llvm/lib/Target/RISCV/CMakeLists.txt | 1 +
llvm/lib/Target/RISCV/RISCV.h | 3 +
.../RISCV/RISCVIndirectBranchTracking.cpp | 2 +-
.../lib/Target/RISCV/RISCVLandingPadSetup.cpp | 85 +++++++++++++++++++
llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 1 +
llvm/test/CodeGen/RISCV/O0-pipeline.ll | 1 +
llvm/test/CodeGen/RISCV/O3-pipeline.ll | 1 +
llvm/test/CodeGen/RISCV/lpad.ll | 72 +++++++++++++++-
8 files changed, 161 insertions(+), 5 deletions(-)
create mode 100644 llvm/lib/Target/RISCV/RISCVLandingPadSetup.cpp
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 5146e519c3529..cbb4c2cedfb97 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -43,6 +43,7 @@ add_llvm_target(RISCVCodeGen
RISCVInstrInfo.cpp
RISCVISelDAGToDAG.cpp
RISCVISelLowering.cpp
+ RISCVLandingPadSetup.cpp
RISCVMachineFunctionInfo.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 80cb395291496..5a94ada8f8dd4 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -34,6 +34,9 @@ void initializeRISCVDeadRegisterDefinitionsPass(PassRegistry &);
FunctionPass *createRISCVIndirectBranchTrackingPass();
void initializeRISCVIndirectBranchTrackingPass(PassRegistry &);
+FunctionPass *createRISCVLandingPadSetupPass();
+void initializeRISCVLandingPadSetupPass(PassRegistry &);
+
FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM,
CodeGenOptLevel OptLevel);
diff --git a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
index 1b484d486edcb..50ca17f7fbc91 100644
--- a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
+++ b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
@@ -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"));
diff --git a/llvm/lib/Target/RISCV/RISCVLandingPadSetup.cpp b/llvm/lib/Target/RISCV/RISCVLandingPadSetup.cpp
new file mode 100644
index 0000000000000..e162c7112ae0e
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVLandingPadSetup.cpp
@@ -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();
+}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 8b3770aeb5d13..b6884321f0841 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -554,6 +554,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.
diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
index c1b081edacc7b..7277cd5e9e149 100644
--- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
@@ -42,6 +42,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
diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
index fe63cc808dece..53b0b5981cae3 100644
--- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
@@ -117,6 +117,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
diff --git a/llvm/test/CodeGen/RISCV/lpad.ll b/llvm/test/CodeGen/RISCV/lpad.ll
index de82a9ee4e34b..cc78305a1c87d 100644
--- a/llvm/test/CodeGen/RISCV/lpad.ll
+++ b/llvm/test/CodeGen/RISCV/lpad.ll
@@ -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
@@ -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
@@ -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:
More information about the llvm-commits
mailing list