From 045314517ee6a694b4261cb377bef67c29bd9932 Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Thu, 4 Dec 2025 01:33:10 +0800 Subject: [PATCH 1/3] [RISCV] Emit lpad for function with returns-twice attribute Insert landing pads after the callsite of attribute "returs-twice" as these functions could result in a indirect call to land after it. --- .../RISCV/RISCVIndirectBranchTracking.cpp | 28 +++++++- llvm/test/CodeGen/RISCV/lpad.ll | 71 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp index 9664ab345dcbf..7697b176daffb 100644 --- a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp +++ b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp @@ -20,7 +20,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#define DEBUG_TYPE "riscv-indrect-branch-tracking" +#define DEBUG_TYPE "riscv-indirect-branch-tracking" #define PASS_NAME "RISC-V Indirect Branch Tracking" using namespace llvm; @@ -61,6 +61,16 @@ static void emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII, .addImm(Label); } +static bool IsCallReturnTwice(llvm::MachineOperand &MOp) { + if (!MOp.isGlobal()) + return false; + auto *CalleeFn = dyn_cast(MOp.getGlobal()); + if (!CalleeFn) + return false; + AttributeList Attrs = CalleeFn->getAttributes(); + return Attrs.hasFnAttr(Attribute::ReturnsTwice); +} + bool RISCVIndirectBranchTracking::runOnMachineFunction(MachineFunction &MF) { const auto &Subtarget = MF.getSubtarget(); const RISCVInstrInfo *TII = Subtarget.getInstrInfo(); @@ -100,5 +110,21 @@ bool RISCVIndirectBranchTracking::runOnMachineFunction(MachineFunction &MF) { } } + // Check for calls to functions with ReturnsTwice attribute and insert + // LPAD after such calls + for (MachineBasicBlock &MBB : MF) { + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { + if (I->isCall() && I->getNumOperands() > 0) { + if (IsCallReturnTwice(I->getOperand(0))) { + auto NextI = std::next(I); + BuildMI(MBB, NextI, MBB.findDebugLoc(NextI), TII->get(RISCV::AUIPC), + RISCV::X0) + .addImm(FixedLabel); + Changed = true; + } + } + } + } + return Changed; } diff --git a/llvm/test/CodeGen/RISCV/lpad.ll b/llvm/test/CodeGen/RISCV/lpad.ll index 93eda6f10eedb..28873ab6c49a4 100644 --- a/llvm/test/CodeGen/RISCV/lpad.ll +++ b/llvm/test/CodeGen/RISCV/lpad.ll @@ -289,3 +289,74 @@ define void @interrupt() "interrupt"="machine" { ; FIXED-ONE-NEXT: mret ret void } + +declare i32 @setjmp(ptr) returns_twice + +define i32 @test_returns_twice() { +; RV32-LABEL: test_returns_twice: +; RV32: # %bb.0: +; 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: addi a0, sp, 8 +; RV32-NEXT: call setjmp +; RV32-NEXT: lpad 0 +; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: addi sp, sp, 16 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: ret +; +; RV64-LABEL: test_returns_twice: +; RV64: # %bb.0: +; 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: addi a0, sp, 4 +; RV64-NEXT: call setjmp +; RV64-NEXT: lpad 0 +; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: addi sp, sp, 16 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: ret +; +; FIXED-ONE-RV32-LABEL: test_returns_twice: +; FIXED-ONE-RV32: # %bb.0: +; FIXED-ONE-RV32-NEXT: lpad 1 +; FIXED-ONE-RV32-NEXT: addi sp, sp, -16 +; FIXED-ONE-RV32-NEXT: .cfi_def_cfa_offset 16 +; FIXED-ONE-RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; FIXED-ONE-RV32-NEXT: .cfi_offset ra, -4 +; FIXED-ONE-RV32-NEXT: addi a0, sp, 8 +; FIXED-ONE-RV32-NEXT: call setjmp +; FIXED-ONE-RV32-NEXT: lpad 1 +; FIXED-ONE-RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; FIXED-ONE-RV32-NEXT: .cfi_restore ra +; FIXED-ONE-RV32-NEXT: addi sp, sp, 16 +; FIXED-ONE-RV32-NEXT: .cfi_def_cfa_offset 0 +; FIXED-ONE-RV32-NEXT: ret +; +; FIXED-ONE-RV64-LABEL: test_returns_twice: +; FIXED-ONE-RV64: # %bb.0: +; FIXED-ONE-RV64-NEXT: lpad 1 +; FIXED-ONE-RV64-NEXT: addi sp, sp, -16 +; FIXED-ONE-RV64-NEXT: .cfi_def_cfa_offset 16 +; FIXED-ONE-RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; FIXED-ONE-RV64-NEXT: .cfi_offset ra, -8 +; FIXED-ONE-RV64-NEXT: addi a0, sp, 4 +; FIXED-ONE-RV64-NEXT: call setjmp +; FIXED-ONE-RV64-NEXT: lpad 1 +; FIXED-ONE-RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; FIXED-ONE-RV64-NEXT: .cfi_restore ra +; FIXED-ONE-RV64-NEXT: addi sp, sp, 16 +; FIXED-ONE-RV64-NEXT: .cfi_def_cfa_offset 0 +; FIXED-ONE-RV64-NEXT: ret + %buf = alloca [1 x i32], align 4 + %call = call i32 @setjmp(ptr %buf) + ret i32 %call +} From 31390f4e665b18c50f5c8d1e1e253a44317f8bca Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Thu, 4 Dec 2025 02:28:04 +0800 Subject: [PATCH 2/3] Address comments --- .../RISCV/RISCVIndirectBranchTracking.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp index 7697b176daffb..2f0b13b7e932b 100644 --- a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp +++ b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp @@ -16,6 +16,7 @@ #include "RISCVInstrInfo.h" #include "RISCVSubtarget.h" #include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -54,14 +55,16 @@ FunctionPass *llvm::createRISCVIndirectBranchTrackingPass() { return new RISCVIndirectBranchTracking(); } -static void emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII, - uint32_t Label) { - auto I = MBB.begin(); +static void +emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII, uint32_t Label, + MachineBasicBlock::iterator I = MachineBasicBlock::iterator{}) { + if (!I.isValid()) + I = MBB.begin(); BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(RISCV::AUIPC), RISCV::X0) .addImm(Label); } -static bool IsCallReturnTwice(llvm::MachineOperand &MOp) { +static bool isCallReturnTwice(MachineOperand &MOp) { if (!MOp.isGlobal()) return false; auto *CalleeFn = dyn_cast(MOp.getGlobal()); @@ -114,14 +117,11 @@ bool RISCVIndirectBranchTracking::runOnMachineFunction(MachineFunction &MF) { // LPAD after such calls for (MachineBasicBlock &MBB : MF) { for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { - if (I->isCall() && I->getNumOperands() > 0) { - if (IsCallReturnTwice(I->getOperand(0))) { - auto NextI = std::next(I); - BuildMI(MBB, NextI, MBB.findDebugLoc(NextI), TII->get(RISCV::AUIPC), - RISCV::X0) - .addImm(FixedLabel); - Changed = true; - } + if (I->isCall() && I->getNumOperands() > 0 && + isCallReturnTwice(I->getOperand(0))) { + auto NextI = std::next(I); + emitLpad(MBB, TII, FixedLabel, NextI); + Changed = true; } } } From ae3de94b8afecc4649a5bd4981ef2372f70a6339 Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Thu, 4 Dec 2025 02:28:50 +0800 Subject: [PATCH 3/3] Add const for isCallReturnTwice --- llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp index 2f0b13b7e932b..0fc139a30ae76 100644 --- a/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp +++ b/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp @@ -64,7 +64,7 @@ emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII, uint32_t Label, .addImm(Label); } -static bool isCallReturnTwice(MachineOperand &MOp) { +static bool isCallReturnTwice(const MachineOperand &MOp) { if (!MOp.isGlobal()) return false; auto *CalleeFn = dyn_cast(MOp.getGlobal());