summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelLowering.cpp')
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp114
1 files changed, 81 insertions, 33 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1f7cf7e857d0..1cbd3f4233ee 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8362,9 +8362,23 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// 16: <StaticChainOffset>
// 24: <FunctionAddressOffset>
// 32:
-
- constexpr unsigned StaticChainOffset = 16;
- constexpr unsigned FunctionAddressOffset = 24;
+ // Offset with branch control flow protection enabled:
+ // 0: lpad <imm20>
+ // 4: auipc t3, 0
+ // 8: ld t2, 28(t3)
+ // 12: ld t3, 20(t3)
+ // 16: jalr t2
+ // 20: <StaticChainOffset>
+ // 28: <FunctionAddressOffset>
+ // 36:
+
+ const bool HasCFBranch =
+ Subtarget.hasStdExtZicfilp() &&
+ DAG.getMachineFunction().getFunction().getParent()->getModuleFlag(
+ "cf-protection-branch");
+ const unsigned StaticChainIdx = HasCFBranch ? 5 : 4;
+ const unsigned StaticChainOffset = StaticChainIdx * 4;
+ const unsigned FunctionAddressOffset = StaticChainOffset + 8;
const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
assert(STI);
@@ -8376,38 +8390,70 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
return Encoding;
};
- SDValue OutChains[6];
-
- 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))};
+ SmallVector<SDValue> OutChains;
+
+ SmallVector<uint32_t> Encodings;
+ if (!HasCFBranch) {
+ Encodings.append(
+ {// 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))});
+ } else {
+ Encodings.append(
+ {// auipc x0, <imm20> (lpad <imm20>)
+ // Landing pad.
+ GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X0).addImm(0)),
+ // auipc t3, 0
+ // Loads the current PC into t3.
+ GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X28).addImm(0)),
+ // ld t2, (FunctionAddressOffset - 4)(t3)
+ // Loads the function address into t2. Note that we are using offsets
+ // pc-relative to the SECOND instruction of the trampoline.
+ GetEncoding(MCInstBuilder(RISCV::LD)
+ .addReg(RISCV::X7)
+ .addReg(RISCV::X28)
+ .addImm(FunctionAddressOffset - 4)),
+ // ld t3, (StaticChainOffset - 4)(t3)
+ // Load the value of the static chain.
+ GetEncoding(MCInstBuilder(RISCV::LD)
+ .addReg(RISCV::X28)
+ .addReg(RISCV::X28)
+ .addImm(StaticChainOffset - 4)),
+ // jalr t2
+ // Software-guarded jump to the function.
+ GetEncoding(MCInstBuilder(RISCV::JALR)
+ .addReg(RISCV::X0)
+ .addReg(RISCV::X7)
+ .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(
+ OutChains.push_back(DAG.getTruncStore(
Root, dl, DAG.getConstant(Encoding, dl, MVT::i64), Addr,
- MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32);
+ MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32));
}
// Now store the variable part of the trampoline.
@@ -8423,16 +8469,18 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
{StaticChainOffset, StaticChain},
{FunctionAddressOffset, FunctionAddress},
};
- for (auto [Idx, OffsetValue] : llvm::enumerate(OffsetValues)) {
+ for (auto &OffsetValue : OffsetValues) {
SDValue Addr =
DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(OffsetValue.Offset, dl, MVT::i64));
OffsetValue.Addr = Addr;
- OutChains[Idx + 4] =
+ OutChains.push_back(
DAG.getStore(Root, dl, OffsetValue.Value, Addr,
- MachinePointerInfo(TrmpAddr, OffsetValue.Offset));
+ MachinePointerInfo(TrmpAddr, OffsetValue.Offset)));
}
+ assert(OutChains.size() == StaticChainIdx + 2 &&
+ "Size of OutChains mismatch");
SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
// The end of instructions of trampoline is the same as the static chain
@@ -20413,8 +20461,8 @@ bool RISCVTargetLowering::isDesirableToCommuteWithShift(
auto *C2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
// Bail if we might break a sh{1,2,3}add pattern.
- if (Subtarget.hasStdExtZba() && C2 && C2->getZExtValue() >= 1 &&
- C2->getZExtValue() <= 3 && N->hasOneUse() &&
+ if ((Subtarget.hasStdExtZba() || Subtarget.hasVendorXAndesPerf()) && C2 &&
+ C2->getZExtValue() >= 1 && C2->getZExtValue() <= 3 && N->hasOneUse() &&
N->user_begin()->getOpcode() == ISD::ADD &&
!isUsedByLdSt(*N->user_begin(), nullptr) &&
!isa<ConstantSDNode>(N->user_begin()->getOperand(1)))