From 94f41940733e8387d6e1528d60ff0479337e152a Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Thu, 20 Jun 2024 06:49:11 +0000 Subject: [PATCH 01/14] [RISCV] Implement trampolines for rv64 This is implementation is heavily based on what the X86 target does but emitting the instructions that GCC emits for rv64. --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 126 ++++++++++++++++++++ llvm/lib/Target/RISCV/RISCVISelLowering.h | 3 + llvm/test/CodeGen/RISCV/rv64-trampoline.ll | 80 +++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 llvm/test/CodeGen/RISCV/rv64-trampoline.ll diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 14249e34921ee..d807877372247 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -625,6 +625,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::READSTEADYCOUNTER, MVT::i64, Subtarget.is64Bit() ? Legal : Custom); + if (Subtarget.is64Bit()) { + setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom); + setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom); + } + setOperationAction({ISD::TRAP, ISD::DEBUGTRAP}, MVT::Other, Legal); setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); if (Subtarget.is64Bit()) @@ -7400,6 +7405,10 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, return emitFlushICache(DAG, Op.getOperand(0), Op.getOperand(1), Op.getOperand(2), Flags, DL); } + case ISD::INIT_TRAMPOLINE: + return lowerINIT_TRAMPOLINE(Op, DAG); + case ISD::ADJUST_TRAMPOLINE: + return lowerADJUST_TRAMPOLINE(Op, DAG); } } @@ -7415,6 +7424,123 @@ SDValue RISCVTargetLowering::emitFlushICache(SelectionDAG &DAG, SDValue InChain, return CallResult.second; } +SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, + SelectionDAG &DAG) const { + if (!Subtarget.is64Bit()) + llvm::report_fatal_error("Trampolines only implemented for RV64"); + + SDValue Root = Op.getOperand(0); + SDValue Trmp = Op.getOperand(1); // trampoline + SDLoc dl(Op); + + const Value *TrmpAddr = cast(Op.getOperand(4))->getValue(); + + // We store in the trampoline buffer the following instructions and data. + // Offset: + // 0: auipc t2, 0 + // 4: ld t0, 24(t2) + // 8: ld t2, 16(t2) + // 12: jalr t0 + // 16: + // 24: + // 32: + + // Constants shamelessly taken from GCC. + constexpr unsigned Opcode_AUIPC = 0x17; + constexpr unsigned Opcode_LD = 0x3003; + constexpr unsigned Opcode_JALR = 0x67; + constexpr unsigned ShiftField_RD = 7; + constexpr unsigned ShiftField_RS1 = 15; + constexpr unsigned ShiftField_IMM = 20; + constexpr unsigned Reg_X5 = 0x5; // x5/t0 (holds the address to the function) + constexpr unsigned Reg_X7 = 0x7; // x7/t2 (holds the static chain) + + constexpr unsigned StaticChainOffset = 16; + constexpr unsigned FunctionAddressOffset = 24; + + SDValue OutChains[6]; + SDValue Addr = Trmp; + + // auipc t2, 0 + // Loads the current PC into t2. + constexpr uint32_t AUIPC_X7_0 = + Opcode_AUIPC | (Reg_X7 << ShiftField_RD); + OutChains[0] = + DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64), + Addr, MachinePointerInfo(TrmpAddr), MVT::i32); + + // ld t0, 24(t2) + // Loads the function address into t0. Note that we are using offsets + // pc-relative to the first instruction of the trampoline. + const uint32_t LD_X5_TargetFunctionOffset = + Opcode_LD | (Reg_X5 << ShiftField_RD) | + (Reg_X7 << ShiftField_RS1) | (FunctionAddressOffset << ShiftField_IMM); + Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(4, dl, MVT::i64)); + OutChains[1] = DAG.getTruncStore( + Root, dl, + DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr, + MachinePointerInfo(TrmpAddr, 4), MVT::i32); + + // ld t2, 16(t2) + // Load the value of the static chain. + const uint32_t LD_X7_StaticChainOffset = + Opcode_LD | (Reg_X7 << ShiftField_RD) | + (Reg_X7 << ShiftField_RS1) | (StaticChainOffset << ShiftField_IMM); + Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(8, dl, MVT::i64)); + OutChains[2] = DAG.getTruncStore( + Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64), + Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32); + + // jalr t0 + // Jump to the function. + const uint32_t JALR_X5 = + Opcode_JALR | (Reg_X5 << ShiftField_RS1); + Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(12, dl, MVT::i64)); + OutChains[3] = + DAG.getTruncStore(Root, dl, DAG.getConstant(JALR_X5, dl, MVT::i64), Addr, + MachinePointerInfo(TrmpAddr, 12), MVT::i32); + + // Now store the variable part of the trampoline. + SDValue FunctionAddress = Op.getOperand(2); + SDValue StaticChain = Op.getOperand(3); + + // Store the given static chain in the trampoline buffer. + Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(StaticChainOffset, dl, MVT::i64)); + OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr, + MachinePointerInfo(TrmpAddr, StaticChainOffset)); + + // Store the given function address in the trampoline buffer. + Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(FunctionAddressOffset, dl, MVT::i64)); + OutChains[5] = + DAG.getStore(Root, dl, FunctionAddress, Addr, + MachinePointerInfo(TrmpAddr, FunctionAddressOffset)); + + SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); + + // Compute end of trampoline. + SDValue EndOfTrmp = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(32, dl, MVT::i64)); + + // Call clear cache on the trampoline buffer. + SDValue Chain = DAG.getNode(ISD::CLEAR_CACHE, dl, MVT::Other, StoreToken, + Trmp, EndOfTrmp); + + return Chain; +} + +SDValue RISCVTargetLowering::lowerADJUST_TRAMPOLINE(SDValue Op, + SelectionDAG &DAG) const { + if (!Subtarget.is64Bit()) + llvm::report_fatal_error("Trampolines only implemented for RV64"); + + return Op.getOperand(0); +} + static SDValue getTargetNode(GlobalAddressSDNode *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flags) { return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 3864d58a129e9..c374944795533 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -992,6 +992,9 @@ class RISCVTargetLowering : public TargetLowering { SDValue expandUnalignedRVVLoad(SDValue Op, SelectionDAG &DAG) const; SDValue expandUnalignedRVVStore(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; + bool isEligibleForTailCallOptimization( CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, const SmallVector &ArgLocs) const; diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll new file mode 100644 index 0000000000000..4a7a50fc09bf8 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll @@ -0,0 +1,80 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64 %s +; RUN: llc -mtriple=riscv64-unknown-linux-gnu -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64-LINUX %s + +declare void @llvm.init.trampoline(ptr, ptr, ptr) +declare ptr @llvm.adjust.trampoline(ptr) +declare i64 @f(ptr nest, i64) + +define i64 @test0(i64 %n, ptr %p) nounwind { +; RV64-LABEL: test0: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -64 +; RV64-NEXT: sd ra, 56(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 48(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s1, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: mv s0, a0 +; RV64-NEXT: lui a0, %hi(.LCPI0_0) +; RV64-NEXT: ld a0, %lo(.LCPI0_0)(a0) +; RV64-NEXT: lui a2, %hi(f) +; RV64-NEXT: addi a2, a2, %lo(f) +; RV64-NEXT: sd a2, 32(sp) +; RV64-NEXT: sd a1, 24(sp) +; RV64-NEXT: sd a0, 16(sp) +; RV64-NEXT: lui a0, 6203 +; RV64-NEXT: addi a0, a0, 643 +; RV64-NEXT: slli a0, a0, 32 +; RV64-NEXT: addi a0, a0, 919 +; RV64-NEXT: sd a0, 8(sp) +; RV64-NEXT: addi a1, sp, 40 +; RV64-NEXT: addi a0, sp, 8 +; RV64-NEXT: addi s1, sp, 8 +; RV64-NEXT: call __clear_cache +; RV64-NEXT: mv a0, s0 +; RV64-NEXT: jalr s1 +; RV64-NEXT: ld ra, 56(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 48(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s1, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: addi sp, sp, 64 +; RV64-NEXT: ret +; +; RV64-LINUX-LABEL: test0: +; RV64-LINUX: # %bb.0: +; RV64-LINUX-NEXT: addi sp, sp, -64 +; RV64-LINUX-NEXT: sd ra, 56(sp) # 8-byte Folded Spill +; RV64-LINUX-NEXT: sd s0, 48(sp) # 8-byte Folded Spill +; RV64-LINUX-NEXT: sd s1, 40(sp) # 8-byte Folded Spill +; RV64-LINUX-NEXT: mv s0, a0 +; RV64-LINUX-NEXT: lui a0, %hi(.LCPI0_0) +; RV64-LINUX-NEXT: ld a0, %lo(.LCPI0_0)(a0) +; RV64-LINUX-NEXT: lui a2, %hi(f) +; RV64-LINUX-NEXT: addi a2, a2, %lo(f) +; RV64-LINUX-NEXT: sd a2, 32(sp) +; RV64-LINUX-NEXT: sd a1, 24(sp) +; RV64-LINUX-NEXT: sd a0, 16(sp) +; RV64-LINUX-NEXT: lui a0, 6203 +; RV64-LINUX-NEXT: addi a0, a0, 643 +; RV64-LINUX-NEXT: slli a0, a0, 32 +; RV64-LINUX-NEXT: addi a0, a0, 919 +; RV64-LINUX-NEXT: sd a0, 8(sp) +; RV64-LINUX-NEXT: addi a1, sp, 40 +; RV64-LINUX-NEXT: addi a0, sp, 8 +; RV64-LINUX-NEXT: addi s1, sp, 8 +; RV64-LINUX-NEXT: li a2, 0 +; RV64-LINUX-NEXT: call __riscv_flush_icache +; RV64-LINUX-NEXT: mv a0, s0 +; RV64-LINUX-NEXT: jalr s1 +; RV64-LINUX-NEXT: ld ra, 56(sp) # 8-byte Folded Reload +; RV64-LINUX-NEXT: ld s0, 48(sp) # 8-byte Folded Reload +; RV64-LINUX-NEXT: ld s1, 40(sp) # 8-byte Folded Reload +; RV64-LINUX-NEXT: addi sp, sp, 64 +; RV64-LINUX-NEXT: ret + %alloca = alloca [32 x i8], align 8 + call void @llvm.init.trampoline(ptr %alloca, ptr @f, ptr %p) + %tramp = call ptr @llvm.adjust.trampoline(ptr %alloca) + %ret = call i64 %tramp(i64 %n) + ret i64 %ret + +} From 3e3d9fc94ad5cb055c3384aec7edfea93309ca0f Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Fri, 19 Jul 2024 07:27:15 +0000 Subject: [PATCH 02/14] Use MCCodeEmitter to encode instructions rather than hardcoded constants --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 56 +++++++++++++-------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index d807877372247..2294412c6beab 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -37,6 +37,8 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsRISCV.h" #include "llvm/IR/PatternMatch.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCInstBuilder.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -7429,6 +7431,14 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, if (!Subtarget.is64Bit()) llvm::report_fatal_error("Trampolines only implemented for RV64"); + // Create an MCCodeEmitter to encode instructions. + TargetLoweringObjectFile *TLO = getTargetMachine().getObjFileLowering(); + assert(TLO); + MCContext& MCCtx = TLO->getContext(); + + std::unique_ptr CodeEmitter( + createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx)); + SDValue Root = Op.getOperand(0); SDValue Trmp = Op.getOperand(1); // trampoline SDLoc dl(Op); @@ -7445,26 +7455,30 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // 24: // 32: - // Constants shamelessly taken from GCC. - constexpr unsigned Opcode_AUIPC = 0x17; - constexpr unsigned Opcode_LD = 0x3003; - constexpr unsigned Opcode_JALR = 0x67; - constexpr unsigned ShiftField_RD = 7; - constexpr unsigned ShiftField_RS1 = 15; - constexpr unsigned ShiftField_IMM = 20; - constexpr unsigned Reg_X5 = 0x5; // x5/t0 (holds the address to the function) - constexpr unsigned Reg_X7 = 0x7; // x7/t2 (holds the static chain) - constexpr unsigned StaticChainOffset = 16; constexpr unsigned FunctionAddressOffset = 24; + auto GetEncoding = [&](const MCInst &MC) { + SmallVector CB; + SmallVector Fixups; + const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo(); + assert(STI); + CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI); + assert(CB.size() == 4); + assert(Fixups.empty()); + uint32_t Encoding = support::endian::read32le(CB.data()); + return Encoding; + }; + SDValue OutChains[6]; SDValue Addr = Trmp; // auipc t2, 0 // Loads the current PC into t2. - constexpr uint32_t AUIPC_X7_0 = - Opcode_AUIPC | (Reg_X7 << ShiftField_RD); + MCInst AUIPC_X7_0_Inst = + MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0); + + uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst); OutChains[0] = DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64), Addr, MachinePointerInfo(TrmpAddr), MVT::i32); @@ -7472,9 +7486,10 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // ld t0, 24(t2) // Loads the function address into t0. Note that we are using offsets // pc-relative to the first instruction of the trampoline. - const uint32_t LD_X5_TargetFunctionOffset = - Opcode_LD | (Reg_X5 << ShiftField_RD) | - (Reg_X7 << ShiftField_RS1) | (FunctionAddressOffset << ShiftField_IMM); + MCInst LD_X5_TargetFunctionOffset_Inst = + MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(24); + uint32_t LD_X5_TargetFunctionOffset = + GetEncoding(LD_X5_TargetFunctionOffset_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(4, dl, MVT::i64)); OutChains[1] = DAG.getTruncStore( @@ -7484,9 +7499,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // ld t2, 16(t2) // Load the value of the static chain. - const uint32_t LD_X7_StaticChainOffset = - Opcode_LD | (Reg_X7 << ShiftField_RD) | - (Reg_X7 << ShiftField_RS1) | (StaticChainOffset << ShiftField_IMM); + MCInst LD_X7_StaticChainOffset_Inst = + MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(16); + uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(8, dl, MVT::i64)); OutChains[2] = DAG.getTruncStore( @@ -7495,8 +7510,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // jalr t0 // Jump to the function. - const uint32_t JALR_X5 = - Opcode_JALR | (Reg_X5 << ShiftField_RS1); + MCInst JALR_X5_Inst = + MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(RISCV::X5).addImm(0); + uint32_t JALR_X5 = GetEncoding(JALR_X5_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(12, dl, MVT::i64)); OutChains[3] = From 5e3ce766892b563ed5014c388ef2280f372b6227 Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Fri, 19 Jul 2024 07:51:44 +0000 Subject: [PATCH 03/14] Remove stray blank line --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 2294412c6beab..359a4bbc2538a 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7477,7 +7477,6 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // Loads the current PC into t2. MCInst AUIPC_X7_0_Inst = MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0); - uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst); OutChains[0] = DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64), From 82367f4616173758977aaa73d0138adb14de1b76 Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Fri, 19 Jul 2024 13:50:52 +0000 Subject: [PATCH 04/14] clang-format --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 359a4bbc2538a..163df9025386e 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7434,7 +7434,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // Create an MCCodeEmitter to encode instructions. TargetLoweringObjectFile *TLO = getTargetMachine().getObjFileLowering(); assert(TLO); - MCContext& MCCtx = TLO->getContext(); + MCContext &MCCtx = TLO->getContext(); std::unique_ptr CodeEmitter( createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx)); @@ -7492,8 +7492,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(4, dl, MVT::i64)); OutChains[1] = DAG.getTruncStore( - Root, dl, - DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr, + Root, dl, DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr, MachinePointerInfo(TrmpAddr, 4), MVT::i32); // ld t2, 16(t2) @@ -7504,8 +7503,8 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(8, dl, MVT::i64)); OutChains[2] = DAG.getTruncStore( - Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64), - Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32); + Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64), Addr, + MachinePointerInfo(TrmpAddr, 8), MVT::i32); // jalr t0 // Jump to the function. From 3a76960fe47b3f24af4f48e3e85ee079d73f90d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Ferrer=20Ib=C3=A1=C3=B1ez?= Date: Tue, 30 Jul 2024 14:46:51 +0200 Subject: [PATCH 05/14] Apply suggestions from code review Co-authored-by: Pengcheng Wang --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 163df9025386e..5f94e47b45d49 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7486,7 +7486,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // Loads the function address into t0. Note that we are using offsets // pc-relative to the first instruction of the trampoline. MCInst LD_X5_TargetFunctionOffset_Inst = - MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(24); + MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(FunctionAddressOffset); uint32_t LD_X5_TargetFunctionOffset = GetEncoding(LD_X5_TargetFunctionOffset_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, @@ -7498,7 +7498,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // ld t2, 16(t2) // Load the value of the static chain. MCInst LD_X7_StaticChainOffset_Inst = - MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(16); + MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(StaticChainOffset); uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(8, dl, MVT::i64)); From b6f7492ad3e6c838f5d2f28f2387407c8690039b Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Tue, 30 Jul 2024 13:02:27 +0000 Subject: [PATCH 06/14] Avoid awkward variable names --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 49 ++++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 5f94e47b45d49..574c3a2afb757 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7475,47 +7475,52 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // auipc t2, 0 // Loads the current PC into t2. - MCInst AUIPC_X7_0_Inst = - MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0); - uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst); - OutChains[0] = - DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64), - Addr, MachinePointerInfo(TrmpAddr), MVT::i32); + OutChains[0] = DAG.getTruncStore( + Root, dl, + DAG.getConstant( + GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)), + dl, MVT::i64), + Addr, MachinePointerInfo(TrmpAddr), MVT::i32); // ld t0, 24(t2) // Loads the function address into t0. Note that we are using offsets // pc-relative to the first instruction of the trampoline. - MCInst LD_X5_TargetFunctionOffset_Inst = - MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(FunctionAddressOffset); - uint32_t LD_X5_TargetFunctionOffset = - GetEncoding(LD_X5_TargetFunctionOffset_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(4, dl, MVT::i64)); OutChains[1] = DAG.getTruncStore( - Root, dl, DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr, - MachinePointerInfo(TrmpAddr, 4), MVT::i32); + Root, dl, + DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD) + .addReg(RISCV::X5) + .addReg(RISCV::X7) + .addImm(FunctionAddressOffset)), + dl, MVT::i64), + Addr, MachinePointerInfo(TrmpAddr, 4), MVT::i32); // ld t2, 16(t2) // Load the value of the static chain. - MCInst LD_X7_StaticChainOffset_Inst = - MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(StaticChainOffset); - uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(8, dl, MVT::i64)); OutChains[2] = DAG.getTruncStore( - Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64), Addr, - MachinePointerInfo(TrmpAddr, 8), MVT::i32); + Root, dl, + DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD) + .addReg(RISCV::X7) + .addReg(RISCV::X7) + .addImm(StaticChainOffset)), + dl, MVT::i64), + Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32); // jalr t0 // Jump to the function. - MCInst JALR_X5_Inst = - MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(RISCV::X5).addImm(0); - uint32_t JALR_X5 = GetEncoding(JALR_X5_Inst); Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(12, dl, MVT::i64)); OutChains[3] = - DAG.getTruncStore(Root, dl, DAG.getConstant(JALR_X5, dl, MVT::i64), Addr, - MachinePointerInfo(TrmpAddr, 12), MVT::i32); + DAG.getTruncStore(Root, dl, + DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::JALR) + .addReg(RISCV::X0) + .addReg(RISCV::X5) + .addImm(0)), + dl, MVT::i64), + Addr, MachinePointerInfo(TrmpAddr, 12), MVT::i32); // Now store the variable part of the trampoline. SDValue FunctionAddress = Op.getOperand(2); From ca45c156c70b9716afde79ecba7d9816a5c05d1e Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Fri, 2 Aug 2024 06:19:50 +0000 Subject: [PATCH 07/14] Reduce the amount of repetition --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 84 ++++++++------------- 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 574c3a2afb757..0dd853c3d3bd3 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7471,63 +7471,45 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, }; SDValue OutChains[6]; - SDValue Addr = Trmp; - - // auipc t2, 0 - // Loads the current PC into t2. - OutChains[0] = DAG.getTruncStore( - Root, dl, - DAG.getConstant( - GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)), - dl, MVT::i64), - Addr, MachinePointerInfo(TrmpAddr), MVT::i32); - - // ld t0, 24(t2) - // Loads the function address into t0. Note that we are using offsets - // pc-relative to the first instruction of the trampoline. - Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(4, dl, MVT::i64)); - OutChains[1] = DAG.getTruncStore( - Root, dl, - DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD) - .addReg(RISCV::X5) - .addReg(RISCV::X7) - .addImm(FunctionAddressOffset)), - dl, MVT::i64), - Addr, MachinePointerInfo(TrmpAddr, 4), MVT::i32); - - // ld t2, 16(t2) - // Load the value of the static chain. - Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(8, dl, MVT::i64)); - OutChains[2] = DAG.getTruncStore( - Root, dl, - DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD) - .addReg(RISCV::X7) - .addReg(RISCV::X7) - .addImm(StaticChainOffset)), - dl, MVT::i64), - Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32); - - // jalr t0 - // Jump to the function. - Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(12, dl, MVT::i64)); - OutChains[3] = - DAG.getTruncStore(Root, dl, - DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::JALR) - .addReg(RISCV::X0) - .addReg(RISCV::X5) - .addImm(0)), - dl, MVT::i64), - Addr, MachinePointerInfo(TrmpAddr, 12), MVT::i32); + + uint32_t Encodings[] = { + // auipc t2, 0 + // Loads the current PC into t2. + GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)), + // ld t0, 24(t2) + // Loads the function address into t0. Note that we are using offsets + // pc-relative to the first instruction of the trampoline. + GetEncoding( + MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm( + FunctionAddressOffset)), + // ld t2, 16(t2) + // Load the value of the static chain. + GetEncoding( + MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm( + StaticChainOffset)), + // jalr t0 + // Jump to the function. + GetEncoding(MCInstBuilder(RISCV::JALR) + .addReg(RISCV::X0) + .addReg(RISCV::X5) + .addImm(0))}; + + // Store encoded instructions. + for (auto [Idx, Encoding] : llvm::enumerate(Encodings)) { + SDValue Addr = Idx > 0 ? DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(Idx * 4, dl, MVT::i64)) + : Trmp; + OutChains[Idx] = DAG.getTruncStore( + Root, dl, DAG.getConstant(Encoding, dl, MVT::i64), Addr, + MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32); + } // Now store the variable part of the trampoline. SDValue FunctionAddress = Op.getOperand(2); SDValue StaticChain = Op.getOperand(3); // Store the given static chain in the trampoline buffer. - Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(StaticChainOffset, dl, MVT::i64)); OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr, MachinePointerInfo(TrmpAddr, StaticChainOffset)); From 215597bfcf0f91a793874858163a586ba83e844e Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Fri, 2 Aug 2024 10:20:26 +0000 Subject: [PATCH 08/14] clang-format --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 0dd853c3d3bd3..5b5f39e9139ea 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7497,8 +7497,8 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // Store encoded instructions. for (auto [Idx, Encoding] : llvm::enumerate(Encodings)) { SDValue Addr = Idx > 0 ? DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(Idx * 4, dl, MVT::i64)) - : Trmp; + DAG.getConstant(Idx * 4, dl, MVT::i64)) + : Trmp; OutChains[Idx] = DAG.getTruncStore( Root, dl, DAG.getConstant(Encoding, dl, MVT::i64), Addr, MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32); @@ -7510,7 +7510,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // Store the given static chain in the trampoline buffer. SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(StaticChainOffset, dl, MVT::i64)); + DAG.getConstant(StaticChainOffset, dl, MVT::i64)); OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr, MachinePointerInfo(TrmpAddr, StaticChainOffset)); From 9a0c0bbad33017ebd0f771d0b4a2d4ca681fd916 Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Tue, 6 Aug 2024 08:17:29 +0200 Subject: [PATCH 09/14] Remove assertions --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 5b5f39e9139ea..c131d21d7d169 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7464,8 +7464,6 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo(); assert(STI); CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI); - assert(CB.size() == 4); - assert(Fixups.empty()); uint32_t Encoding = support::endian::read32le(CB.data()); return Encoding; }; From 63d0daa1c16dbb9f23ebdbcf469277ba9af7781c Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Tue, 6 Aug 2024 08:19:56 +0200 Subject: [PATCH 10/14] Hoist initialisation --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c131d21d7d169..1b563b70d1212 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7458,11 +7458,11 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, constexpr unsigned StaticChainOffset = 16; constexpr unsigned FunctionAddressOffset = 24; + const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo(); + assert(STI); auto GetEncoding = [&](const MCInst &MC) { SmallVector CB; SmallVector Fixups; - const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo(); - assert(STI); CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI); uint32_t Encoding = support::endian::read32le(CB.data()); return Encoding; From 6d65d1bc8cc53ad87e73795ddda758bed1a517ca Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Tue, 6 Aug 2024 08:26:00 +0200 Subject: [PATCH 11/14] Only flush the part of the trampoline buffer containing instructions --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 9 +++++---- llvm/test/CodeGen/RISCV/rv64-trampoline.ll | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 1b563b70d1212..1f25c10d9a018 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7521,11 +7521,12 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); - // Compute end of trampoline. - SDValue EndOfTrmp = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(32, dl, MVT::i64)); + // Compute end of instructions of trampoline. + SDValue EndOfTrmp = + DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(StaticChainOffset, dl, MVT::i64)); - // Call clear cache on the trampoline buffer. + // Call clear cache on the trampoline instructions. SDValue Chain = DAG.getNode(ISD::CLEAR_CACHE, dl, MVT::Other, StoreToken, Trmp, EndOfTrmp); diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll index 4a7a50fc09bf8..1ddc5fb159777 100644 --- a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll +++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll @@ -28,7 +28,7 @@ define i64 @test0(i64 %n, ptr %p) nounwind { ; RV64-NEXT: slli a0, a0, 32 ; RV64-NEXT: addi a0, a0, 919 ; RV64-NEXT: sd a0, 8(sp) -; RV64-NEXT: addi a1, sp, 40 +; RV64-NEXT: addi a1, sp, 24 ; RV64-NEXT: addi a0, sp, 8 ; RV64-NEXT: addi s1, sp, 8 ; RV64-NEXT: call __clear_cache @@ -59,7 +59,7 @@ define i64 @test0(i64 %n, ptr %p) nounwind { ; RV64-LINUX-NEXT: slli a0, a0, 32 ; RV64-LINUX-NEXT: addi a0, a0, 919 ; RV64-LINUX-NEXT: sd a0, 8(sp) -; RV64-LINUX-NEXT: addi a1, sp, 40 +; RV64-LINUX-NEXT: addi a1, sp, 24 ; RV64-LINUX-NEXT: addi a0, sp, 8 ; RV64-LINUX-NEXT: addi s1, sp, 8 ; RV64-LINUX-NEXT: li a2, 0 From 3a73d1c6645f26e27712cd290397c56ec5ffb410 Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Tue, 6 Aug 2024 08:39:49 +0200 Subject: [PATCH 12/14] Reduce the amount of repetition --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 28 ++++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 1f25c10d9a018..98063e28bca9c 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7506,18 +7506,22 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, SDValue FunctionAddress = Op.getOperand(2); SDValue StaticChain = Op.getOperand(3); - // Store the given static chain in the trampoline buffer. - SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(StaticChainOffset, dl, MVT::i64)); - OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr, - MachinePointerInfo(TrmpAddr, StaticChainOffset)); - - // Store the given function address in the trampoline buffer. - Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(FunctionAddressOffset, dl, MVT::i64)); - OutChains[5] = - DAG.getStore(Root, dl, FunctionAddress, Addr, - MachinePointerInfo(TrmpAddr, FunctionAddressOffset)); + // Store the given static chain and function pointer in the trampoline buffer. + struct OffsetValuePair { + unsigned Offset; + SDValue Value; + } OffsetValues[] = { + {StaticChainOffset, StaticChain}, + {FunctionAddressOffset, FunctionAddress}, + }; + for (auto [Idx, OffsetValue] : llvm::enumerate(OffsetValues)) { + SDValue Addr = + DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, + DAG.getConstant(OffsetValue.Offset, dl, MVT::i64)); + OutChains[Idx + 4] = + DAG.getStore(Root, dl, OffsetValue.Value, Addr, + MachinePointerInfo(TrmpAddr, OffsetValue.Offset)); + } SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); From 54248d56214bd7806ec0407c6408a0020a44e1b3 Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Tue, 6 Aug 2024 08:44:09 +0200 Subject: [PATCH 13/14] Remove some more repetition --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 98063e28bca9c..ad1244c4d5a66 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7508,8 +7508,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, // Store the given static chain and function pointer in the trampoline buffer. struct OffsetValuePair { - unsigned Offset; - SDValue Value; + const unsigned Offset; + const SDValue Value; + SDValue Addr = SDValue(); // Used to cache the address. } OffsetValues[] = { {StaticChainOffset, StaticChain}, {FunctionAddressOffset, FunctionAddress}, @@ -7518,6 +7519,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, DAG.getConstant(OffsetValue.Offset, dl, MVT::i64)); + OffsetValue.Addr = Addr; OutChains[Idx + 4] = DAG.getStore(Root, dl, OffsetValue.Value, Addr, MachinePointerInfo(TrmpAddr, OffsetValue.Offset)); @@ -7525,10 +7527,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op, SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); - // Compute end of instructions of trampoline. - SDValue EndOfTrmp = - DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp, - DAG.getConstant(StaticChainOffset, dl, MVT::i64)); + // The end of instructions of trampoline is the same as the static chain + // address that we computed earlier. + SDValue EndOfTrmp = OffsetValues[0].Addr; // Call clear cache on the trampoline instructions. SDValue Chain = DAG.getNode(ISD::CLEAR_CACHE, dl, MVT::Other, StoreToken, From acb1e6b69765101c536d29c3fca55c35dfc9b971 Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Thu, 17 Oct 2024 05:48:28 +0000 Subject: [PATCH 14/14] Update test Codegen used to coalesce the stores into a single sd. Now it emits two sw. --- llvm/test/CodeGen/RISCV/rv64-trampoline.ll | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll index 1ddc5fb159777..ba18406326509 100644 --- a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll +++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll @@ -16,18 +16,18 @@ define i64 @test0(i64 %n, ptr %p) nounwind { ; RV64-NEXT: sd s0, 48(sp) # 8-byte Folded Spill ; RV64-NEXT: sd s1, 40(sp) # 8-byte Folded Spill ; RV64-NEXT: mv s0, a0 -; RV64-NEXT: lui a0, %hi(.LCPI0_0) -; RV64-NEXT: ld a0, %lo(.LCPI0_0)(a0) -; RV64-NEXT: lui a2, %hi(f) -; RV64-NEXT: addi a2, a2, %lo(f) -; RV64-NEXT: sd a2, 32(sp) +; RV64-NEXT: lui a0, %hi(f) +; RV64-NEXT: addi a0, a0, %lo(f) +; RV64-NEXT: sd a0, 32(sp) +; RV64-NEXT: li a0, 919 +; RV64-NEXT: lui a2, %hi(.LCPI0_0) +; RV64-NEXT: ld a2, %lo(.LCPI0_0)(a2) +; RV64-NEXT: lui a3, 6203 +; RV64-NEXT: addi a3, a3, 643 +; RV64-NEXT: sw a0, 8(sp) +; RV64-NEXT: sw a3, 12(sp) +; RV64-NEXT: sd a2, 16(sp) ; RV64-NEXT: sd a1, 24(sp) -; RV64-NEXT: sd a0, 16(sp) -; RV64-NEXT: lui a0, 6203 -; RV64-NEXT: addi a0, a0, 643 -; RV64-NEXT: slli a0, a0, 32 -; RV64-NEXT: addi a0, a0, 919 -; RV64-NEXT: sd a0, 8(sp) ; RV64-NEXT: addi a1, sp, 24 ; RV64-NEXT: addi a0, sp, 8 ; RV64-NEXT: addi s1, sp, 8 @@ -47,18 +47,18 @@ define i64 @test0(i64 %n, ptr %p) nounwind { ; RV64-LINUX-NEXT: sd s0, 48(sp) # 8-byte Folded Spill ; RV64-LINUX-NEXT: sd s1, 40(sp) # 8-byte Folded Spill ; RV64-LINUX-NEXT: mv s0, a0 -; RV64-LINUX-NEXT: lui a0, %hi(.LCPI0_0) -; RV64-LINUX-NEXT: ld a0, %lo(.LCPI0_0)(a0) -; RV64-LINUX-NEXT: lui a2, %hi(f) -; RV64-LINUX-NEXT: addi a2, a2, %lo(f) -; RV64-LINUX-NEXT: sd a2, 32(sp) +; RV64-LINUX-NEXT: lui a0, %hi(f) +; RV64-LINUX-NEXT: addi a0, a0, %lo(f) +; RV64-LINUX-NEXT: sd a0, 32(sp) +; RV64-LINUX-NEXT: li a0, 919 +; RV64-LINUX-NEXT: lui a2, %hi(.LCPI0_0) +; RV64-LINUX-NEXT: ld a2, %lo(.LCPI0_0)(a2) +; RV64-LINUX-NEXT: lui a3, 6203 +; RV64-LINUX-NEXT: addi a3, a3, 643 +; RV64-LINUX-NEXT: sw a0, 8(sp) +; RV64-LINUX-NEXT: sw a3, 12(sp) +; RV64-LINUX-NEXT: sd a2, 16(sp) ; RV64-LINUX-NEXT: sd a1, 24(sp) -; RV64-LINUX-NEXT: sd a0, 16(sp) -; RV64-LINUX-NEXT: lui a0, 6203 -; RV64-LINUX-NEXT: addi a0, a0, 643 -; RV64-LINUX-NEXT: slli a0, a0, 32 -; RV64-LINUX-NEXT: addi a0, a0, 919 -; RV64-LINUX-NEXT: sd a0, 8(sp) ; RV64-LINUX-NEXT: addi a1, sp, 24 ; RV64-LINUX-NEXT: addi a0, sp, 8 ; RV64-LINUX-NEXT: addi s1, sp, 8