diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 114 |
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))) |
