[llvm] [RISCV] Implement trampolines for rv64 (PR #96309)

Roger Ferrer Ibáñez via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 5 23:55:42 PDT 2024


https://github.com/rofirrim updated https://github.com/llvm/llvm-project/pull/96309

>From 1e5b136255bd4befcff2e436d5391bc4f6c269f6 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Thu, 20 Jun 2024 06:49:11 +0000
Subject: [PATCH 01/13] [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 e5460bff6a0ce..23e559e8eb0f7 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -633,6 +633,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())
@@ -7264,6 +7269,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);
   }
 }
 
@@ -7279,6 +7288,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<SrcValueSDNode>(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: <StaticChainOffset>
+  //     24: <FunctionAddressOffset>
+  //     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 d1d0760d8ffd1..b97feef365086 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -998,6 +998,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<CCValAssign, 16> &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 dc3990c65474d533e3f7f83889e399cd233b7c28 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 19 Jul 2024 07:27:15 +0000
Subject: [PATCH 02/13] 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 23e559e8eb0f7..278860908c4e0 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"
@@ -7293,6 +7295,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<MCCodeEmitter> CodeEmitter(
+      createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx));
+
   SDValue Root = Op.getOperand(0);
   SDValue Trmp = Op.getOperand(1); // trampoline
   SDLoc dl(Op);
@@ -7309,26 +7319,30 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
   //     24: <FunctionAddressOffset>
   //     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<char, 4> CB;
+    SmallVector<MCFixup> 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);
@@ -7336,9 +7350,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(
@@ -7348,9 +7363,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(
@@ -7359,8 +7374,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 6bd8bd5451a81a6758bfea81502dab4ef75cd3a6 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 19 Jul 2024 07:51:44 +0000
Subject: [PATCH 03/13] 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 278860908c4e0..2ac0c07940f32 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7341,7 +7341,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 34d0efb1648996dc41f7f055210b4c9c2aa5608b Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 19 Jul 2024 13:50:52 +0000
Subject: [PATCH 04/13] 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 2ac0c07940f32..ce222c5ea225f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7298,7 +7298,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<MCCodeEmitter> CodeEmitter(
       createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx));
@@ -7356,8 +7356,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)
@@ -7368,8 +7367,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 14e4c4e2682fc73fec58f83890e1684da7d67f4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roger=20Ferrer=20Ib=C3=A1=C3=B1ez?= <rofirrim at gmail.com>
Date: Tue, 30 Jul 2024 14:46:51 +0200
Subject: [PATCH 05/13] Apply suggestions from code review

Co-authored-by: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
---
 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 ce222c5ea225f..525aafff3ad05 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7350,7 +7350,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,
@@ -7362,7 +7362,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 0675caeb1b2e9f5e49e674b2c6b412594634685b Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Tue, 30 Jul 2024 13:02:27 +0000
Subject: [PATCH 06/13] 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 525aafff3ad05..74b3e51530495 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7339,47 +7339,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 3097a41bdd3945d951de9d84131f39ad0b69f802 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 2 Aug 2024 06:19:50 +0000
Subject: [PATCH 07/13] 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 74b3e51530495..f1696fb9d8b6d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7335,63 +7335,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 ddd4a5d1ae13ec43bea22467d44a9758c2f56542 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 2 Aug 2024 10:20:26 +0000
Subject: [PATCH 08/13] 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 f1696fb9d8b6d..89dcadae01c1c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7361,8 +7361,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);
@@ -7374,7 +7374,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 790c277b7ca13e73ed2d87d9fb6d7a82265958ad Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:17:29 +0200
Subject: [PATCH 09/13] 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 89dcadae01c1c..7fe589b7f5a03 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7328,8 +7328,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 a68d6ad9a6ad4f485ecfd812cadaef8a22829723 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:19:56 +0200
Subject: [PATCH 10/13] 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 7fe589b7f5a03..eff91b998be86 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7322,11 +7322,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<char, 4> CB;
     SmallVector<MCFixup> 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 ba764efaf0347c08202a9e869d665037f9505c4a Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:26:00 +0200
Subject: [PATCH 11/13] 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 eff91b998be86..15e298d5f6aed 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7385,11 +7385,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 ddb09eda7818ebdab5ce75f0612cb86944165ea0 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:39:49 +0200
Subject: [PATCH 12/13] 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 15e298d5f6aed..293de052d750d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7370,18 +7370,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 9cc30f6658191ed4c2352a87767b215b73a02f36 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:44:09 +0200
Subject: [PATCH 13/13] 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 293de052d750d..610ed688a615d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7372,8 +7372,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},
@@ -7382,6 +7383,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));
@@ -7389,10 +7391,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,



More information about the llvm-commits mailing list