https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/66915
>From ce9772dd519a62025cf545ded306bf40c75f2924 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Tue, 19 Sep 2023 20:53:54 +0000 Subject: [PATCH 01/15] [RISCV] Support Global Dynamic TLSDESC in the RISC-V backend This patch adds basic TLSDESC support for the global dynamic case in the RISC-V backend by adding new relocation types for TLSDESC, as prescribed in https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373. We also add a new pseudo instruction to simplify code generation. Possible improvements for the local dynamic case will be addressed in separate patches. The current implementation is only enabled when passing the -riscv-enable-tlsdesc flag. --- .../llvm/BinaryFormat/ELFRelocs/RISCV.def | 4 + .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 97 +++++++++++++++++-- .../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 9 ++ .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 6 +- .../MCTargetDesc/RISCVELFObjectWriter.cpp | 15 +++ .../RISCV/MCTargetDesc/RISCVFixupKinds.h | 12 +++ .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 46 +++++++++ .../Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp | 18 ++++ .../Target/RISCV/MCTargetDesc/RISCVMCExpr.h | 4 + llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 12 +++ .../Target/RISCV/RISCVExpandPseudoInsts.cpp | 53 ++++++++++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 23 ++++- llvm/lib/Target/RISCV/RISCVISelLowering.h | 3 + llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 6 +- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 36 +++++++ llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 4 + llvm/test/CodeGen/RISCV/tls-models.ll | 96 ++++++++++++++++++ 17 files changed, 432 insertions(+), 12 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def index 9a126df0153119..94420395fa0fad 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def @@ -55,3 +55,7 @@ ELF_RELOC(R_RISCV_SET32, 56) ELF_RELOC(R_RISCV_32_PCREL, 57) ELF_RELOC(R_RISCV_IRELATIVE, 58) ELF_RELOC(R_RISCV_PLT32, 59) +ELF_RELOC(R_RISCV_TLSDESC_HI20, 62) +ELF_RELOC(R_RISCV_TLSDESC_LOAD_LO12, 63) +ELF_RELOC(R_RISCV_TLSDESC_ADD_LO12, 64) +ELF_RELOC(R_RISCV_TLSDESC_CALL, 65) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 7d8d82e381313b..1303f5e85aeeb6 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -152,6 +152,7 @@ class RISCVAsmParser : public MCTargetAsmParser { // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS // addressing. void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); + void emitLoadTLSDescAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); // Helper to emit pseudo load/store instruction with a symbol. void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, @@ -170,6 +171,12 @@ class RISCVAsmParser : public MCTargetAsmParser { // 'add' is an overloaded mnemonic. bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); + // Checks that a PseudoTLSDESCCall is using x5/t0 in its output operand. + // Enforcing this using a restricted register class for the output + // operand of PseudoTLSDESCCall results in a poor diagnostic due to the fact + // 'jalr' is an overloaded mnemonic. + bool checkPseudoTLSDESCCall(MCInst &Inst, OperandVector &Operands); + // Check instruction constraints. bool validateInstruction(MCInst &Inst, OperandVector &Operands); @@ -533,6 +540,16 @@ struct RISCVOperand final : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_RISCV_TPREL_ADD; } + bool isTLSDESCCallSymbol() const { + int64_t Imm; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + // Must be of 'immediate' type but not a constant. + if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) + return false; + return RISCVAsmParser::classifySymbolRef(getImm(), VK) && + VK == RISCVMCExpr::VK_RISCV_TLSDESC_CALL; + } + bool isCSRSystemRegister() const { return isSystemRegister(); } bool isVTypeImm(unsigned N) const { @@ -584,7 +601,10 @@ struct RISCVOperand final : public MCParsedAsmOperand { if (!isImm()) return false; bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); - if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO) + if (VK == RISCVMCExpr::VK_RISCV_LO || + VK == RISCVMCExpr::VK_RISCV_PCREL_LO || + VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO || + VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO) return true; // Given only Imm, ensuring that the actually specified constant is either // a signed or unsigned 64-bit number is unfortunately impossible. @@ -837,7 +857,9 @@ struct RISCVOperand final : public MCParsedAsmOperand { return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO || - VK == RISCVMCExpr::VK_RISCV_TPREL_LO); + VK == RISCVMCExpr::VK_RISCV_TPREL_LO || + VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO || + VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO); } bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } @@ -894,14 +916,16 @@ struct RISCVOperand final : public MCParsedAsmOperand { return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || VK == RISCVMCExpr::VK_RISCV_GOT_HI || VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || - VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); - } else { - return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || - VK == RISCVMCExpr::VK_RISCV_PCREL_HI || - VK == RISCVMCExpr::VK_RISCV_GOT_HI || - VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || - VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); + VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI || + VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI); } + + return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || + VK == RISCVMCExpr::VK_RISCV_PCREL_HI || + VK == RISCVMCExpr::VK_RISCV_GOT_HI || + VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || + VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI || + VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI); } bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } @@ -1515,6 +1539,11 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); } + case Match_InvalidTLSDESCCallSymbol: { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, + "operand must be a symbol with %tlsdesc_call modifier"); + } case Match_InvalidRTZArg: { SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be 'rtz' floating-point rounding mode"); @@ -3107,6 +3136,41 @@ void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, RISCV::ADDI, IDLoc, Out); } +void RISCVAsmParser::emitLoadTLSDescAddress(MCInst &Inst, SMLoc IDLoc, + MCStreamer &Out) { + // The load TLS GD address pseudo-instruction "la.tlsdesc" is used in + // global-dynamic TLS model addressing of global symbols: + // la.tlsdesc rdest, symbol + // expands to + // TmpLabel: AUIPC rdest, %tlsdesc_hi(symbol) + // ADDI rdest, rdest, %pcrel_lo(TmpLabel) + MCOperand DestReg = Inst.getOperand(0); + const MCExpr *Symbol = Inst.getOperand(1).getExpr(); + + MCContext &Ctx = getContext(); + + MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); + Out.emitLabel(TmpLabel); + + const RISCVMCExpr *SymbolHi = + RISCVMCExpr::create(Symbol, RISCVMCExpr::VK_RISCV_TLSDESC_HI, Ctx); + emitToStreamer( + Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(SymbolHi)); + + const MCExpr *RefToLinkTmpLabel = + RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), + RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO, Ctx); + + emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) + .addOperand(DestReg) + .addOperand(DestReg) + .addExpr(RefToLinkTmpLabel)); + + emitToStreamer( + Out, + MCInstBuilder(RISCV::JALR).addReg(RISCV::X5).addReg(RISCV::X5).addImm(0)); +} + void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out, bool HasTmpReg) { @@ -3246,6 +3310,18 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, return false; } +bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst, + OperandVector &Operands) { + assert(Inst.getOpcode() == RISCV::PseudoTLSDESCCall && "Invalid instruction"); + assert(Inst.getOperand(0).isReg() && "Unexpected operand kind"); + if (Inst.getOperand(0).getReg() != RISCV::X5) { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); + return Error(ErrorLoc, "the output operand must be t0/x5 when using " + "%tlsdesc_call modifier"); + } + + return false; +} std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), @@ -3443,6 +3519,9 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, case RISCV::PseudoLA_TLS_GD: emitLoadTLSGDAddress(Inst, IDLoc, Out); return false; + case RISCV::PseudoLA_TLSDESC: + emitLoadTLSDescAddress(Inst, IDLoc, Out); + return false; case RISCV::PseudoLB: emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index ca5aeb943c3be7..0b070e72c3ecb3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -80,6 +80,11 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_riscv_relax", 0, 0, 0}, {"fixup_riscv_align", 0, 0, 0}, + + {"fixup_riscv_tlsdesc_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget}, + {"fixup_riscv_tlsdesc_load_lo12", 20, 12, 0}, + {"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0}, + {"fixup_riscv_tlsdesc_call", 0, 0, 0}, }; static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds, "Not all fixup kinds added to Infos array"); @@ -118,6 +123,7 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, case RISCV::fixup_riscv_got_hi20: case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: + case RISCV::fixup_riscv_tlsdesc_hi20: return true; } @@ -390,6 +396,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case RISCV::fixup_riscv_got_hi20: case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: + case RISCV::fixup_riscv_tlsdesc_hi20: llvm_unreachable("Relocation should be unconditionally forced\n"); case FK_Data_1: case FK_Data_2: @@ -399,6 +406,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case RISCV::fixup_riscv_lo12_i: case RISCV::fixup_riscv_pcrel_lo12_i: case RISCV::fixup_riscv_tprel_lo12_i: + case RISCV::fixup_riscv_tlsdesc_load_lo12: return Value & 0xfff; case RISCV::fixup_riscv_12_i: if (!isInt<12>(Value)) { @@ -502,6 +510,7 @@ bool RISCVAsmBackend::evaluateTargetFixup( switch (Fixup.getTargetKind()) { default: llvm_unreachable("Unexpected fixup kind!"); + case RISCV::fixup_riscv_tlsdesc_hi20: case RISCV::fixup_riscv_pcrel_hi20: AUIPCFixup = &Fixup; AUIPCDF = DF; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 20ff26a39dc3b3..244d2e56c9fa2e 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -256,11 +256,15 @@ enum { MO_TPREL_ADD = 10, MO_TLS_GOT_HI = 11, MO_TLS_GD_HI = 12, + MO_TLSDESC_HI = 13, + MO_TLSDESC_LOAD_LO = 14, + MO_TLSDESC_ADD_LO = 15, + MO_TLSDESC_CALL = 16, // Used to differentiate between target-specific "direct" flags and "bitmask" // flags. A machine operand can only have one "direct" flag, but can have // multiple "bitmask" flags. - MO_DIRECT_FLAG_MASK = 15 + MO_DIRECT_FLAG_MASK = 31 }; } // namespace RISCVII diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index 0799267eaf7c76..bf73b82eaea880 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -77,6 +77,14 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_RISCV_TLS_GOT_HI20; case RISCV::fixup_riscv_tls_gd_hi20: return ELF::R_RISCV_TLS_GD_HI20; + case RISCV::fixup_riscv_tlsdesc_hi20: + return ELF::R_RISCV_TLSDESC_HI20; + case RISCV::fixup_riscv_tlsdesc_load_lo12: + return ELF::R_RISCV_TLSDESC_LOAD_LO12; + case RISCV::fixup_riscv_tlsdesc_add_lo12: + return ELF::R_RISCV_TLSDESC_ADD_LO12; + case RISCV::fixup_riscv_tlsdesc_call: + return ELF::R_RISCV_TLSDESC_CALL; case RISCV::fixup_riscv_jal: return ELF::R_RISCV_JAL; case RISCV::fixup_riscv_branch: @@ -96,6 +104,13 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, default: Ctx.reportError(Fixup.getLoc(), "unsupported relocation type"); return ELF::R_RISCV_NONE; + case RISCV::fixup_riscv_tlsdesc_load_lo12: + return ELF::R_RISCV_TLSDESC_LOAD_LO12; + case RISCV::fixup_riscv_tlsdesc_add_lo12: + return ELF::R_RISCV_TLSDESC_ADD_LO12; + case RISCV::fixup_riscv_tlsdesc_call: + return ELF::R_RISCV_TLSDESC_CALL; + case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_RISCV_NONE; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h index f3d0841eb6bca6..3e8239ac08458b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -71,6 +71,18 @@ enum Fixups { // Used to generate an R_RISCV_ALIGN relocation, which indicates the linker // should fixup the alignment after linker relaxation. fixup_riscv_align, + // 20-bit fixup corresponding to %tlsdesc_hi(foo) for instructions like + // auipc + fixup_riscv_tlsdesc_hi20, + // 12-bit fixup corresponding to %tlsdesc_load_lo(foo) for instructions like + // addi + fixup_riscv_tlsdesc_load_lo12, + // 12-bit fixup corresponding to %tlsdesc_add_lo(foo) for instructions like + // addi + fixup_riscv_tlsdesc_add_lo12, + // Fixup representing a function call to TLS descriptor resolve function, + // %tlsdesc_call + fixup_riscv_tlsdesc_call, // Used as a sentinel, must be the last fixup_riscv_invalid, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 716c3ac14d116b..a0f6c74ba7d9f8 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -57,6 +57,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + void expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; @@ -150,6 +154,31 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, support::endian::write(CB, Binary, support::little); } +void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + MCOperand SrcSymbol = MI.getOperand(3); + assert(SrcSymbol.isExpr() && + "Expected expression as first input to TLSDESCCALL"); + const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr()); + MCRegister Link = MI.getOperand(0).getReg(); + MCRegister Dest = MI.getOperand(1).getReg(); + MCRegister Imm = MI.getOperand(2).getImm(); + Fixups.push_back(MCFixup::create( + 0, Expr, MCFixupKind(RISCV::fixup_riscv_tlsdesc_call), MI.getLoc())); + // Emit fixup_riscv_relax for jalr where the relax feature is enabled. + if (STI.hasFeature(RISCV::FeatureRelax)) { + const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); + Fixups.push_back(MCFixup::create( + 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc())); + } + MCInst Call = + MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm); + + uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI); + support::endian::write(CB, Binary, support::little); +} + // Expand PseudoAddTPRel to a simple ADD with the correct relocation. void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB, @@ -299,6 +328,10 @@ void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, expandLongCondBr(MI, CB, Fixups, STI); MCNumEmitted += 2; return; + case RISCV::PseudoTLSDESCCall: + expandTLSDESCCall(MI, CB, Fixups, STI); + MCNumEmitted += 1; + return; } switch (Size) { @@ -441,6 +474,19 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, FixupKind = RISCV::fixup_riscv_call_plt; RelaxCandidate = true; break; + case RISCVMCExpr::VK_RISCV_TLSDESC_HI: + FixupKind = RISCV::fixup_riscv_tlsdesc_hi20; + break; + case RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO: + FixupKind = RISCV::fixup_riscv_tlsdesc_load_lo12; + break; + case RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO: + FixupKind = RISCV::fixup_riscv_tlsdesc_add_lo12; + break; + case RISCVMCExpr::VK_RISCV_TLSDESC_CALL: + FixupKind = RISCV::fixup_riscv_tlsdesc_call; + RelaxCandidate = true; + break; } } else if ((Kind == MCExpr::SymbolRef && cast<MCSymbolRefExpr>(Expr)->getKind() == diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp index d67351102bc1cd..35d0b7dfff3c39 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp @@ -81,6 +81,7 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup(const MCFragment **DFOut) const { case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: case RISCV::fixup_riscv_pcrel_hi20: + case RISCV::fixup_riscv_tlsdesc_hi20: if (DFOut) *DFOut = DF; return &F; @@ -121,6 +122,10 @@ RISCVMCExpr::VariantKind RISCVMCExpr::getVariantKindForName(StringRef name) { .Case("tprel_add", VK_RISCV_TPREL_ADD) .Case("tls_ie_pcrel_hi", VK_RISCV_TLS_GOT_HI) .Case("tls_gd_pcrel_hi", VK_RISCV_TLS_GD_HI) + .Case("tlsdesc_hi", VK_RISCV_TLSDESC_HI) + .Case("tlsdesc_load_lo", VK_RISCV_TLSDESC_LOAD_LO) + .Case("tlsdesc_add_lo", VK_RISCV_TLSDESC_ADD_LO) + .Case("tlsdesc_call", VK_RISCV_TLSDESC_CALL) .Default(VK_RISCV_Invalid); } @@ -147,6 +152,14 @@ StringRef RISCVMCExpr::getVariantKindName(VariantKind Kind) { return "tprel_add"; case VK_RISCV_TLS_GOT_HI: return "tls_ie_pcrel_hi"; + case VK_RISCV_TLSDESC_HI: + return "tlsdesc_hi"; + case VK_RISCV_TLSDESC_LOAD_LO: + return "tlsdesc_load_lo"; + case VK_RISCV_TLSDESC_ADD_LO: + return "tlsdesc_add_lo"; + case VK_RISCV_TLSDESC_CALL: + return "tlsdesc_call"; case VK_RISCV_TLS_GD_HI: return "tls_gd_pcrel_hi"; case VK_RISCV_CALL: @@ -195,6 +208,9 @@ void RISCVMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { case VK_RISCV_TPREL_HI: case VK_RISCV_TLS_GOT_HI: case VK_RISCV_TLS_GD_HI: + case VK_RISCV_TLSDESC_HI: + case VK_RISCV_TLSDESC_ADD_LO: + case VK_RISCV_TLSDESC_LOAD_LO: break; } @@ -208,6 +224,8 @@ bool RISCVMCExpr::evaluateAsConstant(int64_t &Res) const { Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_TPREL_HI || Kind == VK_RISCV_TPREL_LO || Kind == VK_RISCV_TPREL_ADD || Kind == VK_RISCV_TLS_GOT_HI || Kind == VK_RISCV_TLS_GD_HI || + Kind == VK_RISCV_TLSDESC_HI || Kind == VK_RISCV_TLSDESC_LOAD_LO || + Kind == VK_RISCV_TLSDESC_ADD_LO || Kind == VK_RISCV_TLSDESC_CALL || Kind == VK_RISCV_CALL || Kind == VK_RISCV_CALL_PLT) return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h index ee83bf0208ef46..fcc4c5c439645a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h @@ -37,6 +37,10 @@ class RISCVMCExpr : public MCTargetExpr { VK_RISCV_CALL, VK_RISCV_CALL_PLT, VK_RISCV_32_PCREL, + VK_RISCV_TLSDESC_HI, + VK_RISCV_TLSDESC_LOAD_LO, + VK_RISCV_TLSDESC_ADD_LO, + VK_RISCV_TLSDESC_CALL, VK_RISCV_Invalid // Must be the last item }; diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 526520e6c5267d..d49a1b5ae2849e 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -695,6 +695,18 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, case RISCVII::MO_TLS_GD_HI: Kind = RISCVMCExpr::VK_RISCV_TLS_GD_HI; break; + case RISCVII::MO_TLSDESC_HI: + Kind = RISCVMCExpr::VK_RISCV_TLSDESC_HI; + break; + case RISCVII::MO_TLSDESC_LOAD_LO: + Kind = RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO; + break; + case RISCVII::MO_TLSDESC_ADD_LO: + Kind = RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO; + break; + case RISCVII::MO_TLSDESC_CALL: + Kind = RISCVMCExpr::VK_RISCV_TLSDESC_CALL; + break; } const MCExpr *ME = diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp index ff35a8fc9c5a1e..2b879d77a5f169 100644 --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -415,6 +415,10 @@ class RISCVPreRAExpandPseudo : public MachineFunctionPass { bool expandLoadTLSGDAddress(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI); + bool expandLoadTLSDescAddress(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI); + #ifndef NDEBUG unsigned getInstSizeInBytes(const MachineFunction &MF) const { unsigned Size = 0; @@ -473,6 +477,8 @@ bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB, return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); case RISCV::PseudoLA_TLS_GD: return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI); + case RISCV::PseudoLA_TLSDESC: + return expandLoadTLSDescAddress(MBB, MBBI, NextMBBI); } return false; } @@ -539,6 +545,53 @@ bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress( RISCV::ADDI); } +bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI) { + MachineFunction *MF = MBB.getParent(); + MachineInstr &MI = *MBBI; + DebugLoc DL = MI.getDebugLoc(); + + const auto &STI = MF->getSubtarget<RISCVSubtarget>(); + unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; + + Register FinalReg = MI.getOperand(0).getReg(); + Register DestReg = + MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); + Register ScratchReg = + MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); + + MachineOperand &Symbol = MI.getOperand(1); + Symbol.setTargetFlags(RISCVII::MO_TLSDESC_HI); + MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("tlsdesc_hi"); + + MachineInstr *MIAUIPC = + BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); + MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); + + BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) + .addReg(ScratchReg) + .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_LOAD_LO); + + BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), RISCV::X10) + .addReg(ScratchReg) + .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_ADD_LO); + + BuildMI(MBB, MBBI, DL, TII->get(RISCV::PseudoTLSDESCCall), RISCV::X5) + .addReg(DestReg) + .addImm(0) + .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_CALL); + + MachineInstr *TPAdd = BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), FinalReg) + .addReg(RISCV::X10) + .addReg(RISCV::X4); + + if (MI.hasOneMemOperand()) + TPAdd->addMemOperand(*MF, *MI.memoperands_begin()); + MI.eraseFromParent(); + return true; +} + } // end of anonymous namespace INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 0214bd1d7dda32..edcec8a984e690 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -50,6 +50,8 @@ using namespace llvm; STATISTIC(NumTailCalls, "Number of tail calls"); +extern cl::opt<bool> EnableRISCVTLSDESC; + static cl::opt<unsigned> ExtensionMaxWebSize( DEBUG_TYPE "-ext-max-web-size", cl::Hidden, cl::desc("Give the maximum size (in number of nodes) of the web of " @@ -6492,6 +6494,24 @@ SDValue RISCVTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N, return LowerCallTo(CLI).first; } +SDValue +RISCVTargetLowering::getGeneralDynamicTLSDescAddr(GlobalAddressSDNode *N, + SelectionDAG &DAG) const { + SDLoc DL(N); + EVT Ty = getPointerTy(DAG.getDataLayout()); + const GlobalValue *GV = N->getGlobal(); + + // Use a PC-relative addressing mode to access the global dynamic GOT address. + // This generates the pattern (PseudoLA_TLSDESC sym), which expands to + // + // auipc tX, %tlsdesc_hi(symbol) // R_RISCV_TLSDESC_HI20(symbol) + // lw tY, tX, %tlsdesc_lo_load(label) // R_RISCV_TLSDESC_LOAD_LO12_I(label) + // addi a0, tX, %tlsdesc_lo_add(label) // R_RISCV_TLSDESC_ADD_LO12_I(label) + // jalr t0, tY // R_RISCV_TLSDESC_CALL(label) + SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, 0); + return DAG.getNode(RISCVISD::LA_TLSDESC, DL, Ty, Addr); +} + SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op); @@ -6516,7 +6536,8 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, break; case TLSModel::LocalDynamic: case TLSModel::GeneralDynamic: - Addr = getDynamicTLSAddr(N, DAG); + Addr = EnableRISCVTLSDESC ? getGeneralDynamicTLSDescAddr(N, DAG) + : getDynamicTLSAddr(N, DAG); break; } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 815b9be47f5602..38be15fb288e8c 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -57,6 +57,7 @@ enum NodeType : unsigned { // Load address. LA_TLS_GD, + LA_TLSDESC, // Multiply high for signedxunsigned. MULHSU, @@ -845,6 +846,8 @@ class RISCVTargetLowering : public TargetLowering { SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, bool UseGOT) const; SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const; + SDValue getGeneralDynamicTLSDescAddr(GlobalAddressSDNode *N, + SelectionDAG &DAG) const; SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 816ceaf95607e7..713d1224cdc4bb 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1984,7 +1984,11 @@ RISCVInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { {MO_TPREL_HI, "riscv-tprel-hi"}, {MO_TPREL_ADD, "riscv-tprel-add"}, {MO_TLS_GOT_HI, "riscv-tls-got-hi"}, - {MO_TLS_GD_HI, "riscv-tls-gd-hi"}}; + {MO_TLS_GD_HI, "riscv-tls-gd-hi"}, + {MO_TLSDESC_HI, "riscv-tlsdesc-hi"}, + {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"}, + {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"}, + {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}}; return ArrayRef(TargetFlags); } bool RISCVInstrInfo::isFunctionSafeToOutlineFrom( diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index abbeff78b6e286..1c84ba5c056be4 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -95,6 +95,7 @@ def riscv_add_tprel : SDNode<"RISCVISD::ADD_TPREL", def riscv_la_tls_ie : SDNode<"RISCVISD::LA_TLS_IE", SDTLoad, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def riscv_la_tls_gd : SDNode<"RISCVISD::LA_TLS_GD", SDTIntUnaryOp>; +def riscv_la_tlsdesc : SDNode<"RISCVISD::LA_TLSDESC", SDTIntUnaryOp>; //===----------------------------------------------------------------------===// // Operand and SDNode transformation definitions. @@ -1752,10 +1753,45 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0, isAsmParserOnly = 1 in def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la.tls.gd", "$dst, $src">; +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0, + isAsmParserOnly = 1 in +def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], + "la.tlsdesc", "$dst, $src">; def : Pat<(riscv_la_tls_gd tglobaltlsaddr:$in), (PseudoLA_TLS_GD tglobaltlsaddr:$in)>; +def : Pat<(riscv_la_tlsdesc tglobaltlsaddr:$in), + (PseudoLA_TLSDESC tglobaltlsaddr:$in)>; +def : Pat<(riscv_la_tlsdesc texternalsym:$in), + (PseudoLA_TLSDESC texternalsym:$in)>; + +def TLSDESCCallSymbol : AsmOperandClass { + let Name = "TLSDESCCallSymbol"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidTLSDESCCallSymbol"; + let ParserMethod = "parseOperandWithModifier"; +} + +// A bare symbol with the %tlsdesc_call variant. +def tlsdesc_call_symbol : Operand<XLenVT> { + let ParserMatchClass = TLSDESCCallSymbol; +} +// This is a special case of the JALR instruction used to facilitate the use of a +// fourth operand to emit a relocation on a symbol relating to this instruction. +// The relocation does not affect any bits of the instruction itself but is used +// as a hint to the linker. +let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0, + mayStore = 0, mayLoad = 0 in +def PseudoTLSDESCCall : Pseudo<(outs GPR:$rd), + (ins GPR:$rs1, simm12:$imm12, tlsdesc_call_symbol:$src), [], + "jalr", "$rd, ${imm12}(${rs1}), $src">, + Sched<[WriteJalr, ReadJalr]> { + let Defs = [X10]; + let Uses = [X10]; +} + + /// Sign/Zero Extends // There are single-instruction versions of these in Zbb, so disable these diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index 30d559a4958c32..deaadb27477bb4 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -78,6 +78,10 @@ static cl::opt<bool> EnableRISCVDeadRegisterElimination( " them with stores to x0"), cl::init(true)); +cl::opt<bool> EnableRISCVTLSDESC("riscv-enable-tlsdesc", + cl::desc("Enable the tlsdesc for RISC-V"), + cl::Hidden); + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target()); RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target()); diff --git a/llvm/test/CodeGen/RISCV/tls-models.ll b/llvm/test/CodeGen/RISCV/tls-models.ll index d9b37cb0c7c22c..11e223068f9c3a 100644 --- a/llvm/test/CodeGen/RISCV/tls-models.ll +++ b/llvm/test/CodeGen/RISCV/tls-models.ll @@ -58,6 +58,42 @@ define ptr @f1() nounwind { ; RV64-NOPIC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) ; RV64-NOPIC-NEXT: add a0, a0, tp ; RV64-NOPIC-NEXT: ret +; +; RV32-PIC-TLSDESC-LABEL: f1: +; RV32-PIC-TLSDESC: # %bb.0: # %entry +; RV32-PIC-TLSDESC-NEXT: .Ltlsdesc_hi0: +; RV32-PIC-TLSDESC-NEXT: auipc a0, %tlsdesc_hi(unspecified) +; RV32-PIC-TLSDESC-NEXT: lw a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0) +; RV32-PIC-TLSDESC-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0) +; RV32-PIC-TLSDESC-NEXT: jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) +; RV32-PIC-TLSDESC-NEXT: add a0, a0, tp +; RV32-PIC-TLSDESC-NEXT: ret +; +; RV64-PIC-TLSDESC-LABEL: f1: +; RV64-PIC-TLSDESC: # %bb.0: # %entry +; RV64-PIC-TLSDESC-NEXT: .Ltlsdesc_hi0: +; RV64-PIC-TLSDESC-NEXT: auipc a0, %tlsdesc_hi(unspecified) +; RV64-PIC-TLSDESC-NEXT: ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0) +; RV64-PIC-TLSDESC-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0) +; RV64-PIC-TLSDESC-NEXT: jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) +; RV64-PIC-TLSDESC-NEXT: add a0, a0, tp +; RV64-PIC-TLSDESC-NEXT: ret +; +; RV32-NOPIC-TLSDESC-LABEL: f1: +; RV32-NOPIC-TLSDESC: # %bb.0: # %entry +; RV32-NOPIC-TLSDESC-NEXT: .Lpcrel_hi0: +; RV32-NOPIC-TLSDESC-NEXT: auipc a0, %tls_ie_pcrel_hi(unspecified) +; RV32-NOPIC-TLSDESC-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi0)(a0) +; RV32-NOPIC-TLSDESC-NEXT: add a0, a0, tp +; RV32-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-TLSDESC-LABEL: f1: +; RV64-NOPIC-TLSDESC: # %bb.0: # %entry +; RV64-NOPIC-TLSDESC-NEXT: .Lpcrel_hi0: +; RV64-NOPIC-TLSDESC-NEXT: auipc a0, %tls_ie_pcrel_hi(unspecified) +; RV64-NOPIC-TLSDESC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) +; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp +; RV64-NOPIC-TLSDESC-NEXT: ret entry: ret ptr @unspecified } @@ -144,6 +180,38 @@ define ptr @f3() nounwind { ; RV64-NOPIC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0) ; RV64-NOPIC-NEXT: add a0, a0, tp ; RV64-NOPIC-NEXT: ret +; +; RV32-PIC-TLSDESC-LABEL: f3: +; RV32-PIC-TLSDESC: # %bb.0: # %entry +; RV32-PIC-TLSDESC-NEXT: .Lpcrel_hi0: +; RV32-PIC-TLSDESC-NEXT: auipc a0, %tls_ie_pcrel_hi(ie) +; RV32-PIC-TLSDESC-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi0)(a0) +; RV32-PIC-TLSDESC-NEXT: add a0, a0, tp +; RV32-PIC-TLSDESC-NEXT: ret +; +; RV64-PIC-TLSDESC-LABEL: f3: +; RV64-PIC-TLSDESC: # %bb.0: # %entry +; RV64-PIC-TLSDESC-NEXT: .Lpcrel_hi0: +; RV64-PIC-TLSDESC-NEXT: auipc a0, %tls_ie_pcrel_hi(ie) +; RV64-PIC-TLSDESC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) +; RV64-PIC-TLSDESC-NEXT: add a0, a0, tp +; RV64-PIC-TLSDESC-NEXT: ret +; +; RV32-NOPIC-TLSDESC-LABEL: f3: +; RV32-NOPIC-TLSDESC: # %bb.0: # %entry +; RV32-NOPIC-TLSDESC-NEXT: .Lpcrel_hi2: +; RV32-NOPIC-TLSDESC-NEXT: auipc a0, %tls_ie_pcrel_hi(ie) +; RV32-NOPIC-TLSDESC-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi2)(a0) +; RV32-NOPIC-TLSDESC-NEXT: add a0, a0, tp +; RV32-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-TLSDESC-LABEL: f3: +; RV64-NOPIC-TLSDESC: # %bb.0: # %entry +; RV64-NOPIC-TLSDESC-NEXT: .Lpcrel_hi2: +; RV64-NOPIC-TLSDESC-NEXT: auipc a0, %tls_ie_pcrel_hi(ie) +; RV64-NOPIC-TLSDESC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0) +; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp +; RV64-NOPIC-TLSDESC-NEXT: ret entry: ret ptr @ie } @@ -179,6 +247,34 @@ define ptr @f4() nounwind { ; RV64-NOPIC-NEXT: add a0, a0, tp, %tprel_add(le) ; RV64-NOPIC-NEXT: addi a0, a0, %tprel_lo(le) ; RV64-NOPIC-NEXT: ret +; +; RV32-PIC-TLSDESC-LABEL: f4: +; RV32-PIC-TLSDESC: # %bb.0: # %entry +; RV32-PIC-TLSDESC-NEXT: lui a0, %tprel_hi(le) +; RV32-PIC-TLSDESC-NEXT: add a0, a0, tp, %tprel_add(le) +; RV32-PIC-TLSDESC-NEXT: addi a0, a0, %tprel_lo(le) +; RV32-PIC-TLSDESC-NEXT: ret +; +; RV64-PIC-TLSDESC-LABEL: f4: +; RV64-PIC-TLSDESC: # %bb.0: # %entry +; RV64-PIC-TLSDESC-NEXT: lui a0, %tprel_hi(le) +; RV64-PIC-TLSDESC-NEXT: add a0, a0, tp, %tprel_add(le) +; RV64-PIC-TLSDESC-NEXT: addi a0, a0, %tprel_lo(le) +; RV64-PIC-TLSDESC-NEXT: ret +; +; RV32-NOPIC-TLSDESC-LABEL: f4: +; RV32-NOPIC-TLSDESC: # %bb.0: # %entry +; RV32-NOPIC-TLSDESC-NEXT: lui a0, %tprel_hi(le) +; RV32-NOPIC-TLSDESC-NEXT: add a0, a0, tp, %tprel_add(le) +; RV32-NOPIC-TLSDESC-NEXT: addi a0, a0, %tprel_lo(le) +; RV32-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-TLSDESC-LABEL: f4: +; RV64-NOPIC-TLSDESC: # %bb.0: # %entry +; RV64-NOPIC-TLSDESC-NEXT: lui a0, %tprel_hi(le) +; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp, %tprel_add(le) +; RV64-NOPIC-TLSDESC-NEXT: addi a0, a0, %tprel_lo(le) +; RV64-NOPIC-TLSDESC-NEXT: ret entry: ret ptr @le } >From 8a7ecf7ccdfd1c3e29fe5fe0513709dd386b7b0e Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Wed, 29 Nov 2023 21:35:03 +0000 Subject: [PATCH 02/15] !fixup Call and test checkPseudoTLSDESCCall --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 5 +++++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 1 + llvm/test/MC/RISCV/rv32i-invalid.s | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 1303f5e85aeeb6..7578405c6ba6ce 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -3310,6 +3310,7 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, return false; } + bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst, OperandVector &Operands) { assert(Inst.getOpcode() == RISCV::PseudoTLSDESCCall && "Invalid instruction"); @@ -3577,6 +3578,10 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, if (checkPseudoAddTPRel(Inst, Operands)) return true; break; + case RISCV::PseudoTLSDESCCall: + if(checkPseudoTLSDESCCall(Inst, Operands)) + return true; + break; case RISCV::PseudoSEXT_B: emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); return false; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index edcec8a984e690..64719c115f8739 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -17269,6 +17269,7 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(ADD_TPREL) NODE_NAME_CASE(LA_TLS_IE) NODE_NAME_CASE(LA_TLS_GD) + NODE_NAME_CASE(LA_TLSDESC) NODE_NAME_CASE(MULHSU) NODE_NAME_CASE(SLLW) NODE_NAME_CASE(SRAW) diff --git a/llvm/test/MC/RISCV/rv32i-invalid.s b/llvm/test/MC/RISCV/rv32i-invalid.s index c5e0657b838094..c509883e69e640 100644 --- a/llvm/test/MC/RISCV/rv32i-invalid.s +++ b/llvm/test/MC/RISCV/rv32i-invalid.s @@ -188,3 +188,8 @@ addi a2, ft0, 24 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction # fence.tso accepts no operands fence.tso rw, rw # CHECK: :[[@LINE]]:11: error: invalid operand for instruction + +.Ltlsdesc_hi0: +jalr x5, 0(a1), %tlsdesc_hi(.Ltlsdesc_hi0) # CHECK: :[[@LINE]]:17: error: operand must be a symbol with %tlsdesc_call modifier +jalr x1, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) # CHECK: :[[@LINE]]:12: error: the output operand must be t0/x5 when using %tlsdesc_call modifier + >From 388dfac0191d2cad0569aa551e04e640f506868b Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Wed, 29 Nov 2023 22:13:06 +0000 Subject: [PATCH 03/15] fixup! clang-format --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 7578405c6ba6ce..40a54722b82971 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -3579,7 +3579,7 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, return true; break; case RISCV::PseudoTLSDESCCall: - if(checkPseudoTLSDESCCall(Inst, Operands)) + if (checkPseudoTLSDESCCall(Inst, Operands)) return true; break; case RISCV::PseudoSEXT_B: >From 896ca77a7fea8cae9787659480dc131f5a3e3c34 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Mon, 18 Dec 2023 19:05:50 +0000 Subject: [PATCH 04/15] !fixup Address code differences after rebase --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 3 ++- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 5 +++-- llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp | 8 +++----- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 6 ------ 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 4a74eb20a1cfeb..ae362ae3bba223 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -87,7 +87,8 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_riscv_relax", 0, 0, 0}, {"fixup_riscv_align", 0, 0, 0}, - {"fixup_riscv_tlsdesc_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget}, + {"fixup_riscv_tlsdesc_hi20", 12, 20, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget}, {"fixup_riscv_tlsdesc_load_lo12", 20, 12, 0}, {"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0}, {"fixup_riscv_tlsdesc_call", 0, 0, 0}, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 532199d085ad6e..2b603e974e68e1 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -158,7 +158,8 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, support::endian::write(CB, Binary, llvm::endianness::little); } -void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB, +void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI, + SmallVectorImpl<char> &CB, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { MCOperand SrcSymbol = MI.getOperand(3); @@ -180,7 +181,7 @@ void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<cha MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm); uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI); - support::endian::write(CB, Binary, support::little); + support::endian::write(CB, Binary, llvm::endianness::little); } // Expand PseudoAddTPRel to a simple ADD with the correct relocation. diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp index 321e5777f61637..4b84bd567f6b34 100644 --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -578,12 +578,10 @@ bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress( .addImm(0) .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_CALL); - MachineInstr *TPAdd = BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), FinalReg) - .addReg(RISCV::X10) - .addReg(RISCV::X4); + BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), FinalReg) + .addReg(RISCV::X10) + .addReg(RISCV::X4); - if (MI.hasOneMemOperand()) - TPAdd->addMemOperand(*MF, *MI.memoperands_begin()); MI.eraseFromParent(); return true; } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index cd5ef299361686..fbb8590a8278e0 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6860,7 +6860,7 @@ RISCVTargetLowering::getGeneralDynamicTLSDescAddr(GlobalAddressSDNode *N, // addi a0, tX, %tlsdesc_lo_add(label) // R_RISCV_TLSDESC_ADD_LO12_I(label) // jalr t0, tY // R_RISCV_TLSDESC_CALL(label) SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, 0); - return DAG.getNode(RISCVISD::LA_TLSDESC, DL, Ty, Addr); + return SDValue(DAG.getMachineNode(RISCV::PseudoLA_TLSDESC, DL, Ty, Addr), 0); } SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 23f7bba1510ff6..00c2d17c8a4167 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1727,12 +1727,6 @@ let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0, def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la.tlsdesc", "$dst, $src">; - -def : Pat<(riscv_la_tlsdesc tglobaltlsaddr:$in), - (PseudoLA_TLSDESC tglobaltlsaddr:$in)>; -def : Pat<(riscv_la_tlsdesc texternalsym:$in), - (PseudoLA_TLSDESC texternalsym:$in)>; - def TLSDESCCallSymbol : AsmOperandClass { let Name = "TLSDESCCallSymbol"; let RenderMethod = "addImmOperands"; >From df381c9f0aa4127081f3903b1ea61441a669dd7f Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Mon, 18 Dec 2023 19:20:55 +0000 Subject: [PATCH 05/15] !fixup Remove parsing for `la.tlsdesc` Since this pseudo wasn't in the psABI, we shouldn't be emitting it anywhere, and having the AsmParser handle it is a challenge without introducing more operands, since it would need to know which registers to use or have a way to scavenge registers. For now, we can leave the pseudo-instruction as an implementation detail, with the understanding that it shouldn't be emitted into the assembly output. --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 1ca4597bbbd1db..0f893b8eaf57f6 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -151,7 +151,6 @@ class RISCVAsmParser : public MCTargetAsmParser { // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS // addressing. void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); - void emitLoadTLSDescAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); // Helper to emit pseudo load/store instruction with a symbol. void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, @@ -3203,41 +3202,6 @@ void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, RISCV::ADDI, IDLoc, Out); } -void RISCVAsmParser::emitLoadTLSDescAddress(MCInst &Inst, SMLoc IDLoc, - MCStreamer &Out) { - // The load TLS GD address pseudo-instruction "la.tlsdesc" is used in - // global-dynamic TLS model addressing of global symbols: - // la.tlsdesc rdest, symbol - // expands to - // TmpLabel: AUIPC rdest, %tlsdesc_hi(symbol) - // ADDI rdest, rdest, %pcrel_lo(TmpLabel) - MCOperand DestReg = Inst.getOperand(0); - const MCExpr *Symbol = Inst.getOperand(1).getExpr(); - - MCContext &Ctx = getContext(); - - MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); - Out.emitLabel(TmpLabel); - - const RISCVMCExpr *SymbolHi = - RISCVMCExpr::create(Symbol, RISCVMCExpr::VK_RISCV_TLSDESC_HI, Ctx); - emitToStreamer( - Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(SymbolHi)); - - const MCExpr *RefToLinkTmpLabel = - RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), - RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO, Ctx); - - emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) - .addOperand(DestReg) - .addOperand(DestReg) - .addExpr(RefToLinkTmpLabel)); - - emitToStreamer( - Out, - MCInstBuilder(RISCV::JALR).addReg(RISCV::X5).addReg(RISCV::X5).addImm(0)); -} - void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out, bool HasTmpReg) { @@ -3592,9 +3556,6 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, case RISCV::PseudoLA_TLS_GD: emitLoadTLSGDAddress(Inst, IDLoc, Out); return false; - case RISCV::PseudoLA_TLSDESC: - emitLoadTLSDescAddress(Inst, IDLoc, Out); - return false; case RISCV::PseudoLB: emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); return false; >From 50d3ffb5e25f965dcff93bb38d068d15d0b23cfe Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Mon, 18 Dec 2023 20:06:13 +0000 Subject: [PATCH 06/15] !fixup Add TODO to remove the cl::opt option --- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index 3eff9da05a1454..867a9378501f8c 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -80,6 +80,7 @@ static cl::opt<bool> EnableRISCVDeadRegisterElimination( " them with stores to x0"), cl::init(true)); +// TODO: This should be controlled by -mtls-dialect=<option> cl::opt<bool> EnableRISCVTLSDESC("riscv-enable-tlsdesc", cl::desc("Enable the tlsdesc for RISC-V"), cl::Hidden); >From c54f7ac947c8639aa2dbf5a0e0239a342ac6e387 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Mon, 18 Dec 2023 20:10:35 +0000 Subject: [PATCH 07/15] !fixup Rename getGeneralDynamicTLSDescAddr to getTLSDescAddr --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 9 ++++----- llvm/lib/Target/RISCV/RISCVISelLowering.h | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index fbb8590a8278e0..a5b7f7f1f01135 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6845,9 +6845,8 @@ SDValue RISCVTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N, return LowerCallTo(CLI).first; } -SDValue -RISCVTargetLowering::getGeneralDynamicTLSDescAddr(GlobalAddressSDNode *N, - SelectionDAG &DAG) const { +SDValue RISCVTargetLowering::getTLSDescAddr(GlobalAddressSDNode *N, + SelectionDAG &DAG) const { SDLoc DL(N); EVT Ty = getPointerTy(DAG.getDataLayout()); const GlobalValue *GV = N->getGlobal(); @@ -6887,8 +6886,8 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, break; case TLSModel::LocalDynamic: case TLSModel::GeneralDynamic: - Addr = EnableRISCVTLSDESC ? getGeneralDynamicTLSDescAddr(N, DAG) - : getDynamicTLSAddr(N, DAG); + Addr = + EnableRISCVTLSDESC ? getTLSDescAddr(N, DAG) : getDynamicTLSAddr(N, DAG); break; } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 308b2b7092924a..65f7d06494dd8f 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -855,8 +855,7 @@ class RISCVTargetLowering : public TargetLowering { SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, bool UseGOT) const; SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const; - SDValue getGeneralDynamicTLSDescAddr(GlobalAddressSDNode *N, - SelectionDAG &DAG) const; + SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const; SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; >From 152b415d74a9e5a2ad232302031c5f47302d4041 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Wed, 3 Jan 2024 21:40:20 +0000 Subject: [PATCH 08/15] Don't set isAsmParserOnly bits in PseudoLA_TLSDESC --- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 5796cfca3d41b7..9365ab461e2138 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1722,8 +1722,8 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0, isAsmParserOnly = 1 in def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la.tls.gd", "$dst, $src">; -let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0, - isAsmParserOnly = 1 in + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0 in def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la.tlsdesc", "$dst, $src">; >From 7ba52955052f508751778aad1df87d53aea61ebf Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Wed, 3 Jan 2024 21:41:05 +0000 Subject: [PATCH 09/15] Add back RUN lines to test removed in old rebase --- llvm/test/CodeGen/RISCV/tls-models.ll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/tls-models.ll b/llvm/test/CodeGen/RISCV/tls-models.ll index 11e223068f9c3a..9cc9e8fd0d69dd 100644 --- a/llvm/test/CodeGen/RISCV/tls-models.ll +++ b/llvm/test/CodeGen/RISCV/tls-models.ll @@ -1,10 +1,16 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -relocation-model=pic < %s \ ; RUN: | FileCheck -check-prefix=RV32-PIC %s +; RUN: llc -mtriple=riscv32 -relocation-model=pic < %s -riscv-enable-tlsdesc \ +; RUN: | FileCheck -check-prefix=RV32-PIC-TLSDESC %s ; RUN: llc -mtriple=riscv64 -relocation-model=pic < %s \ ; RUN: | FileCheck -check-prefix=RV64-PIC %s +; RUN: llc -mtriple=riscv64 -relocation-model=pic -riscv-enable-tlsdesc < %s \ +; RUN: | FileCheck -check-prefix=RV64-PIC-TLSDESC %s ; RUN: llc -mtriple=riscv32 < %s | FileCheck -check-prefix=RV32-NOPIC %s +; RUN: llc -mtriple=riscv32 < %s -riscv-enable-tlsdesc | FileCheck -check-prefix=RV32-NOPIC-TLSDESC %s ; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefix=RV64-NOPIC %s +; RUN: llc -mtriple=riscv64 < %s -riscv-enable-tlsdesc | FileCheck -check-prefix=RV64-NOPIC-TLSDESC %s ; Check that TLS symbols are lowered correctly based on the specified ; model. Make sure they're external to avoid them all being optimised to Local >From 1ba4890430b3e20c0799c0f6327ea75cfc12609e Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Wed, 3 Jan 2024 21:46:57 +0000 Subject: [PATCH 10/15] Test tlsdesc relocations in MC layer --- llvm/test/MC/RISCV/rv32-tlsdesc-valid.s | 17 +++++++++++++++++ llvm/test/MC/RISCV/rv64-tlsdesc-valid.s | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 llvm/test/MC/RISCV/rv32-tlsdesc-valid.s create mode 100644 llvm/test/MC/RISCV/rv64-tlsdesc-valid.s diff --git a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s new file mode 100644 index 00000000000000..78756a4d195d7a --- /dev/null +++ b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc -filetype=obj -triple riscv32 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s + +start: # @start +# %bb.0: # %entry +.Ltlsdesc_hi0: + auipc a0, %tlsdesc_hi(unspecified) + #CHECK: auipc a0, 0x0 + lw a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0) + #CHECK: lw a1, 0x0(a0) + addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0) + #CHECK: addi a0, a0, 0x0 + jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) + #CHECK: jalr t0, 0x0(a1) + add a0, a0, tp + #CHECK: add a0, a0, tp + ret + diff --git a/llvm/test/MC/RISCV/rv64-tlsdesc-valid.s b/llvm/test/MC/RISCV/rv64-tlsdesc-valid.s new file mode 100644 index 00000000000000..8aba8aac79d702 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64-tlsdesc-valid.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -triple riscv64 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s + +start: # @start +# %bb.0: # %entry +.Ltlsdesc_hi0: + auipc a0, %tlsdesc_hi(unspecified) + #CHECK: auipc a0, 0x0 + ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0) + #CHECK: ld a1, 0x0(a0) + addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0) + #CHECK: addi a0, a0, 0x0 + jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) + #CHECK: jalr t0, 0x0(a1) + add a0, a0, tp + #CHECK: add a0, a0, tp + ret >From de4b9fc62c00003536543972624ec19aa1d92bb1 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Thu, 4 Jan 2024 00:15:54 +0000 Subject: [PATCH 11/15] Add test for invalid TLSDESC relocations --- llvm/test/MC/RISCV/tlsdesc-invalid.s | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 llvm/test/MC/RISCV/tlsdesc-invalid.s diff --git a/llvm/test/MC/RISCV/tlsdesc-invalid.s b/llvm/test/MC/RISCV/tlsdesc-invalid.s new file mode 100644 index 00000000000000..4619db6ace9e32 --- /dev/null +++ b/llvm/test/MC/RISCV/tlsdesc-invalid.s @@ -0,0 +1,14 @@ +# RUN: not llvm-mc %s -triple=riscv32 2>&1 | FileCheck %s +# RUN: not llvm-mc %s -triple=riscv64 2>&1 | FileCheck %s + +lga x1, %tlsdesc_hi(1234) # CHECK: :[[@LINE]]:10: error: operand must be a bare symbol name +lga x1, %tlsdesc_hi(foo) # CHECK: :[[@LINE]]:10: error: operand must be a bare symbol name + +lw a0, t0, %tlsdesc_load_lo(a_symbol) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +lw a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction + +addi a0, t0, %tlsdesc_add_lo(a_symbol)(a4) # CHECK: :[[@LINE]]:40: error: invalid operand for instruction +addi a0, %tlsdesc_add_lo(a_symbol) # CHECK: :[[@LINE]]:10: error: invalid operand for instruction + +jalr t0, a0, %tlsdesc_call(a_symbol) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +jalr t0, 12345(a1), %tlsdesc_call(a_symbol) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] >From d60118ce3079cc64036cbb142a57819e96ed424a Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulki...@google.com> Date: Thu, 4 Jan 2024 00:18:11 +0000 Subject: [PATCH 12/15] Remove trailing whitespace --- llvm/test/MC/RISCV/rv32-tlsdesc-valid.s | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s index 78756a4d195d7a..fd42f3892632db 100644 --- a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s +++ b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s @@ -14,4 +14,3 @@ start: # @start add a0, a0, tp #CHECK: add a0, a0, tp ret - >From aa301e3747dc6141fcf529441e801e2017b2e384 Mon Sep 17 00:00:00 2001 From: Paul Kirth <pk1...@gmail.com> Date: Thu, 4 Jan 2024 21:58:20 +0000 Subject: [PATCH 13/15] Update error string to match checks --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 2 +- llvm/test/MC/RISCV/corev/XCVelw-invalid.s | 2 +- llvm/test/MC/RISCV/corev/XCVmem-invalid.s | 26 +++++++++---------- llvm/test/MC/RISCV/insn-invalid.s | 2 +- llvm/test/MC/RISCV/rv32d-invalid.s | 4 +-- llvm/test/MC/RISCV/rv32f-invalid.s | 4 +-- llvm/test/MC/RISCV/rv32i-invalid.s | 14 +++++----- llvm/test/MC/RISCV/rv32zfbfmin-invalid.s | 4 +-- llvm/test/MC/RISCV/rv32zfh-invalid.s | 4 +-- llvm/test/MC/RISCV/rv32zfhmin-invalid.s | 4 +-- llvm/test/MC/RISCV/rv64i-invalid.s | 6 ++--- llvm/test/MC/RISCV/rv64zdinx-invalid.s | 2 +- llvm/test/MC/RISCV/rv64zfh-invalid.s | 4 +-- llvm/test/MC/RISCV/rvi-pseudos-invalid.s | 2 +- llvm/test/MC/RISCV/tlsdesc-invalid.s | 8 +++--- 15 files changed, 44 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 80ad3dd88590e9..2b29905f876f4e 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1515,7 +1515,7 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSImm12: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, - "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " + "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an " "integer in the range"); case Match_InvalidSImm12Lsb0: return generateImmOutOfRangeError( diff --git a/llvm/test/MC/RISCV/corev/XCVelw-invalid.s b/llvm/test/MC/RISCV/corev/XCVelw-invalid.s index 24870904ac49b1..70011d85d22e74 100644 --- a/llvm/test/MC/RISCV/corev/XCVelw-invalid.s +++ b/llvm/test/MC/RISCV/corev/XCVelw-invalid.s @@ -8,7 +8,7 @@ cv.elw 0, 0(x6) # CHECK-ERROR: invalid operand for instruction cv.elw x12, 2048(x6) -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.elw x12, x1(2047) # CHECK-ERROR: unexpected token diff --git a/llvm/test/MC/RISCV/corev/XCVmem-invalid.s b/llvm/test/MC/RISCV/corev/XCVmem-invalid.s index e71cd7daa890e6..959675deb19d21 100644 --- a/llvm/test/MC/RISCV/corev/XCVmem-invalid.s +++ b/llvm/test/MC/RISCV/corev/XCVmem-invalid.s @@ -11,10 +11,10 @@ cv.lb 0, (0), t2 # CHECK-ERROR: invalid operand for instruction cv.lb t0, (t1), -2049 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lb t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lb t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -41,10 +41,10 @@ cv.lbu 0, (0), t0 # CHECK-ERROR: invalid operand for instruction cv.lbu t0, (t1), -2049 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lbu t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lbu t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -71,10 +71,10 @@ cv.lh 0, (0), t2 # CHECK-ERROR: invalid operand for instruction cv.lh t0, (t1), -2049 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lh t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lh t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -104,10 +104,10 @@ cv.lhu 0, 0(t1) # CHECK-ERROR: invalid operand for instruction cv.lhu t0, (t1), -2049 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lhu t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lhu t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -137,10 +137,10 @@ cv.lw 0, (0), t2 # CHECK-ERROR: invalid operand for instruction cv.lw t0, (t1), -2049 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lw t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.lw t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -170,7 +170,7 @@ cv.sb t0, 0(t1) # CHECK-ERROR: operands must be register and register cv.sb t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.sb t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -191,7 +191,7 @@ cv.sh t0, 0(t1) # CHECK-ERROR: operands must be register and register cv.sh t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.sh t0, (0), t1 # CHECK-ERROR: operands must be register and register @@ -212,7 +212,7 @@ cv.sw t0, 0(t1) # CHECK-ERROR: operands must be register and register cv.sw t0, (t1), 2048 -# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] cv.sw t0, (0), t1 # CHECK-ERROR: operands must be register and register diff --git a/llvm/test/MC/RISCV/insn-invalid.s b/llvm/test/MC/RISCV/insn-invalid.s index 32ebd6867377c2..0f99a3e7adc980 100644 --- a/llvm/test/MC/RISCV/insn-invalid.s +++ b/llvm/test/MC/RISCV/insn-invalid.s @@ -9,7 +9,7 @@ .insn i 0x13, 0, a0, a1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction .insn r 0x33, 0, 0, a0, 13 # CHECK: :[[@LINE]]:28: error: invalid operand for instruction -.insn i 0x13, 0, a0, a1, a2 # CHECK: :[[@LINE]]:28: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +.insn i 0x13, 0, a0, a1, a2 # CHECK: :[[@LINE]]:28: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] .insn q 0x13, 0, a0, a1, 13, 14 # CHECK: :[[@LINE]]:7: error: invalid instruction format diff --git a/llvm/test/MC/RISCV/rv32d-invalid.s b/llvm/test/MC/RISCV/rv32d-invalid.s index ee363ec7db79cb..5b38a073a71757 100644 --- a/llvm/test/MC/RISCV/rv32d-invalid.s +++ b/llvm/test/MC/RISCV/rv32d-invalid.s @@ -2,8 +2,8 @@ # Out of range immediates ## simm12 -fld ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -fsd ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +fld ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +fsd ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly fld ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32f-invalid.s b/llvm/test/MC/RISCV/rv32f-invalid.s index f2d368071a0bbb..7897897c773596 100644 --- a/llvm/test/MC/RISCV/rv32f-invalid.s +++ b/llvm/test/MC/RISCV/rv32f-invalid.s @@ -2,8 +2,8 @@ # Out of range immediates ## simm12 -flw ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -fsw ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +flw ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +fsw ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly flw ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32i-invalid.s b/llvm/test/MC/RISCV/rv32i-invalid.s index c509883e69e640..9075fc2c974972 100644 --- a/llvm/test/MC/RISCV/rv32i-invalid.s +++ b/llvm/test/MC/RISCV/rv32i-invalid.s @@ -17,8 +17,8 @@ csrrsi t1, 999, 32 # CHECK: :[[@LINE]]:17: error: immediate must be an integer i csrrci x0, 43, -90 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] ## simm12 -ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -andi ra, sp, 2048 # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +andi ra, sp, 2048 # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] ## uimm12 csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] @@ -67,11 +67,11 @@ csrrsi t1, 999, %pcrel_lo(4) # CHECK: :[[@LINE]]:17: error: immediate must be an csrrci x0, 43, %pcrel_lo(d) # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] ## simm12 -ori a0, a1, %hi(foo) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -andi ra, sp, %pcrel_hi(123) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -xori a2, a3, %hi(345) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -add a1, a2, (a3) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -add a1, a2, foo # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +ori a0, a1, %hi(foo) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +andi ra, sp, %pcrel_hi(123) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +xori a2, a3, %hi(345) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +add a1, a2, (a3) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +add a1, a2, foo # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] ## uimm12 csrrw a0, %lo(1), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] diff --git a/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s b/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s index b7b5a0a84b32df..967aa14d603276 100644 --- a/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s +++ b/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s @@ -5,8 +5,8 @@ # Out of range immediates ## simm12 -flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly flh ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32zfh-invalid.s b/llvm/test/MC/RISCV/rv32zfh-invalid.s index efa5e871616f66..f265ae40c0249a 100644 --- a/llvm/test/MC/RISCV/rv32zfh-invalid.s +++ b/llvm/test/MC/RISCV/rv32zfh-invalid.s @@ -3,8 +3,8 @@ # Out of range immediates ## simm12 -flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly flh ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv32zfhmin-invalid.s b/llvm/test/MC/RISCV/rv32zfhmin-invalid.s index 8fe90d4f7100c2..1549803cd9a71b 100644 --- a/llvm/test/MC/RISCV/rv32zfhmin-invalid.s +++ b/llvm/test/MC/RISCV/rv32zfhmin-invalid.s @@ -5,8 +5,8 @@ # Out of range immediates ## simm12 -flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly flh ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv64i-invalid.s b/llvm/test/MC/RISCV/rv64i-invalid.s index deb8ea54fde35e..a176d0608062c5 100644 --- a/llvm/test/MC/RISCV/rv64i-invalid.s +++ b/llvm/test/MC/RISCV/rv64i-invalid.s @@ -12,8 +12,8 @@ srli a0, a0, -1 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in t srai a0, a0, -19 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 63] ## simm12 -addiw a0, a1, -2049 # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -ld ra, 2048(sp) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +addiw a0, a1, -2049 # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +ld ra, 2048(sp) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Illegal operand modifier ## uimm5 @@ -27,4 +27,4 @@ srli a0, a0, %lo(a) # CHECK: :[[@LINE]]:14: error: immediate must be an integer srai a0, a0, %hi(2) # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 63] ## simm12 -addiw a0, a1, %hi(foo) # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +addiw a0, a1, %hi(foo) # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] diff --git a/llvm/test/MC/RISCV/rv64zdinx-invalid.s b/llvm/test/MC/RISCV/rv64zdinx-invalid.s index 31414d87e6f4e5..79f979fee52abf 100644 --- a/llvm/test/MC/RISCV/rv64zdinx-invalid.s +++ b/llvm/test/MC/RISCV/rv64zdinx-invalid.s @@ -2,7 +2,7 @@ # Not support float registers fld fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point){{$}} -ld a0, -2049(a1) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +ld a0, -2049(a1) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Invalid instructions fsd a5, 12(sp) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rv64zfh-invalid.s b/llvm/test/MC/RISCV/rv64zfh-invalid.s index d6835746f0a8cf..fb770973401f62 100644 --- a/llvm/test/MC/RISCV/rv64zfh-invalid.s +++ b/llvm/test/MC/RISCV/rv64zfh-invalid.s @@ -3,8 +3,8 @@ # Out of range immediates ## simm12 -flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] +fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] # Integer registers where FP regs are expected fcvt.l.h ft0, a0 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rvi-pseudos-invalid.s b/llvm/test/MC/RISCV/rvi-pseudos-invalid.s index c10bef53732b23..ca52e213ed2c85 100644 --- a/llvm/test/MC/RISCV/rvi-pseudos-invalid.s +++ b/llvm/test/MC/RISCV/rvi-pseudos-invalid.s @@ -11,7 +11,7 @@ lga x1, %lo(1234) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol na lga x1, %hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name lga x1, %lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name -sw a2, %hi(a_symbol), a3 # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +sw a2, %hi(a_symbol), a3 # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an integer in the range [-2048, 2047] sw a2, %lo(a_symbol), a3 # CHECK: :[[@LINE]]:23: error: invalid operand for instruction sw a2, %lo(a_symbol)(a4), a3 # CHECK: :[[@LINE]]:27: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/tlsdesc-invalid.s b/llvm/test/MC/RISCV/tlsdesc-invalid.s index 4619db6ace9e32..5b40b9b50585c4 100644 --- a/llvm/test/MC/RISCV/tlsdesc-invalid.s +++ b/llvm/test/MC/RISCV/tlsdesc-invalid.s @@ -1,8 +1,8 @@ # RUN: not llvm-mc %s -triple=riscv32 2>&1 | FileCheck %s # RUN: not llvm-mc %s -triple=riscv64 2>&1 | FileCheck %s -lga x1, %tlsdesc_hi(1234) # CHECK: :[[@LINE]]:10: error: operand must be a bare symbol name -lga x1, %tlsdesc_hi(foo) # CHECK: :[[@LINE]]:10: error: operand must be a bare symbol name +auipc x1, %tlsdesc_call(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range +auipc x1, %tlsdesc_call(1234) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range lw a0, t0, %tlsdesc_load_lo(a_symbol) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction lw a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction @@ -10,5 +10,5 @@ lw a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # CHECK: :[[@LINE]]:14: error: inval addi a0, t0, %tlsdesc_add_lo(a_symbol)(a4) # CHECK: :[[@LINE]]:40: error: invalid operand for instruction addi a0, %tlsdesc_add_lo(a_symbol) # CHECK: :[[@LINE]]:10: error: invalid operand for instruction -jalr t0, a0, %tlsdesc_call(a_symbol) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -jalr t0, 12345(a1), %tlsdesc_call(a_symbol) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +jalr x5, 0(a1), %tlsdesc_hi(a_symbol) # CHECK: :[[@LINE]]:17: error: operand must be a symbol with %tlsdesc_call modifier +jalr x1, 0(a1), %tlsdesc_call(a_symbol) # CHECK: :[[@LINE]]:12: error: the output operand must be t0/x5 when using %tlsdesc_call modifier >From dcce10110017a19ca36e7a4aac6d829c53a88bd1 Mon Sep 17 00:00:00 2001 From: Paul Kirth <pk1...@gmail.com> Date: Thu, 4 Jan 2024 22:16:09 +0000 Subject: [PATCH 14/15] Fix documentation for fixup_riscv_tlsdesc_load_lo12 --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h index 47e8ca01b480d5..8304826830dde4 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -75,7 +75,7 @@ enum Fixups { // auipc fixup_riscv_tlsdesc_hi20, // 12-bit fixup corresponding to %tlsdesc_load_lo(foo) for instructions like - // addi + // lw fixup_riscv_tlsdesc_load_lo12, // 12-bit fixup corresponding to %tlsdesc_add_lo(foo) for instructions like // addi >From cde5cba5d227e2bfb85a3fd0db19ca7a702ce6a8 Mon Sep 17 00:00:00 2001 From: Paul Kirth <pk1...@gmail.com> Date: Thu, 4 Jan 2024 22:21:57 +0000 Subject: [PATCH 15/15] Run clang-format on patch --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 2b29905f876f4e..6b6699f91d6263 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1515,7 +1515,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSImm12: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, - "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi modifier or an " + "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_hi " + "modifier or an " "integer in the range"); case Match_InvalidSImm12Lsb0: return generateImmOutOfRangeError( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits