[flang-commits] [libunwind] [lldb] [libc] [lld] [clang-tools-extra] [compiler-rt] [llvm] [clang] [libclc] [flang] [libcxxabi] [libcxx] [RISCV] Support Global Dynamic TLSDESC in the RISC-V backend (PR #66915)

Paul Kirth via flang-commits flang-commits at lists.llvm.org
Thu Jan 18 15:20:07 PST 2024


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 <paulkirth at google.com>
Date: Tue, 19 Sep 2023 20:53:54 +0000
Subject: [PATCH 01/26] [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 9a126df01531195..94420395fa0fadd 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 7d8d82e381313bf..1303f5e85aeeb65 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 ca5aeb943c3be75..0b070e72c3ecb3d 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 20ff26a39dc3b30..244d2e56c9fa2e7 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 0799267eaf7c769..bf73b82eaea880c 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 f3d0841eb6bca64..3e8239ac08458b8 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 716c3ac14d116ba..a0f6c74ba7d9f8f 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 d67351102bc1cde..35d0b7dfff3c39e 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 ee83bf0208ef46e..fcc4c5c439645a9 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 526520e6c5267df..d49a1b5ae2849ed 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 ff35a8fc9c5a1e0..2b879d77a5f1696 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 0214bd1d7dda326..edcec8a984e690b 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 815b9be47f56026..38be15fb288e8cb 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 816ceaf95607e71..713d1224cdc4bbe 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 abbeff78b6e2864..1c84ba5c056be4f 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 30d559a4958c320..deaadb27477bb49 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 d9b37cb0c7c22cd..11e223068f9c3aa 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 <paulkirth at google.com>
Date: Wed, 29 Nov 2023 21:35:03 +0000
Subject: [PATCH 02/26] !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 1303f5e85aeeb65..7578405c6ba6cee 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 edcec8a984e690b..64719c115f8739e 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 c5e0657b838094f..c509883e69e640d 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 <paulkirth at google.com>
Date: Wed, 29 Nov 2023 22:13:06 +0000
Subject: [PATCH 03/26] 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 7578405c6ba6cee..40a54722b829712 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 <paulkirth at google.com>
Date: Mon, 18 Dec 2023 19:05:50 +0000
Subject: [PATCH 04/26] !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 4a74eb20a1cfeb7..ae362ae3bba2231 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 532199d085ad6ea..2b603e974e68e14 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 321e5777f616373..4b84bd567f6b341 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 cd5ef2993616867..fbb8590a8278e09 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 23f7bba1510ff67..00c2d17c8a41679 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 <paulkirth at google.com>
Date: Mon, 18 Dec 2023 19:20:55 +0000
Subject: [PATCH 05/26] !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 1ca4597bbbd1dbc..0f893b8eaf57f66 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 <paulkirth at google.com>
Date: Mon, 18 Dec 2023 20:06:13 +0000
Subject: [PATCH 06/26] !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 3eff9da05a14544..867a9378501f8cb 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 <paulkirth at google.com>
Date: Mon, 18 Dec 2023 20:10:35 +0000
Subject: [PATCH 07/26] !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 fbb8590a8278e09..a5b7f7f1f01135b 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 308b2b7092924ad..65f7d06494dd8fe 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 <paulkirth at google.com>
Date: Wed, 3 Jan 2024 21:40:20 +0000
Subject: [PATCH 08/26] 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 5796cfca3d41b76..9365ab461e21382 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 <paulkirth at google.com>
Date: Wed, 3 Jan 2024 21:41:05 +0000
Subject: [PATCH 09/26] 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 11e223068f9c3aa..9cc9e8fd0d69dda 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 <paulkirth at google.com>
Date: Wed, 3 Jan 2024 21:46:57 +0000
Subject: [PATCH 10/26] 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 000000000000000..78756a4d195d7a4
--- /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 000000000000000..8aba8aac79d7021
--- /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 <paulkirth at google.com>
Date: Thu, 4 Jan 2024 00:15:54 +0000
Subject: [PATCH 11/26] 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 000000000000000..4619db6ace9e329
--- /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 <paulkirth at google.com>
Date: Thu, 4 Jan 2024 00:18:11 +0000
Subject: [PATCH 12/26] 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 78756a4d195d7a4..fd42f3892632db1 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 <pk1574 at gmail.com>
Date: Thu, 4 Jan 2024 21:58:20 +0000
Subject: [PATCH 13/26] 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 80ad3dd88590e99..2b29905f876f4e8 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 24870904ac49b1c..70011d85d22e741 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 e71cd7daa890e60..959675deb19d21d 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 32ebd6867377c2c..0f99a3e7adc9808 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 ee363ec7db79cb4..5b38a073a71757b 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 f2d368071a0bbbf..7897897c7735966 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 c509883e69e640d..9075fc2c9749720 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 b7b5a0a84b32dfc..967aa14d6032768 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 efa5e871616f667..f265ae40c0249ad 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 8fe90d4f7100c2f..1549803cd9a71b0 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 deb8ea54fde35e4..a176d0608062c5a 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 31414d87e6f4e54..79f979fee52abfb 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 d6835746f0a8cfc..fb770973401f622 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 c10bef53732b232..ca52e213ed2c854 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 4619db6ace9e329..5b40b9b50585c4d 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 <pk1574 at gmail.com>
Date: Thu, 4 Jan 2024 22:16:09 +0000
Subject: [PATCH 14/26] 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 47e8ca01b480d5d..8304826830dde4c 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 <pk1574 at gmail.com>
Date: Thu, 4 Jan 2024 22:21:57 +0000
Subject: [PATCH 15/26] 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 2b29905f876f4e8..6b6699f91d62635 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(

>From ca753eef960553920e57c1f890fa9e42fe335535 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Mon, 8 Jan 2024 23:36:27 +0000
Subject: [PATCH 16/26] Update error string to mach checks, and fix tests

---
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp |  8 +++---
 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/relocations.s              | 21 +++++++++++++++
 llvm/test/MC/RISCV/rv32-tlsdesc-valid.s       | 14 +++++-----
 llvm/test/MC/RISCV/rv32d-invalid.s            |  4 +--
 llvm/test/MC/RISCV/rv32f-invalid.s            |  4 +--
 llvm/test/MC/RISCV/rv32i-invalid.s            | 26 +++++++++----------
 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          |  5 ++--
 17 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 42fb9e1fffed082..4473f0ef6b048b8 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1511,9 +1511,9 @@ 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 "
-        "integer in the range");
+        "operand must be a symbol with "
+        "%lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo modifier or an integer in "
+        "the range");
   case Match_InvalidSImm12Lsb0:
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
@@ -1537,7 +1537,7 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 20) - 1,
         "operand must be a symbol with a "
-        "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
+        "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or "
         "an integer in the range");
   case Match_InvalidSImm21Lsb0JAL:
     return generateImmOutOfRangeError(
diff --git a/llvm/test/MC/RISCV/corev/XCVelw-invalid.s b/llvm/test/MC/RISCV/corev/XCVelw-invalid.s
index 70011d85d22e741..28510d4b00c46b2 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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 959675deb19d21d..ca82d60be5d5f3a 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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/%tlsdesc_hi modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_lo 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 0f99a3e7adc9808..28d7341967548d6 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/%tlsdesc_hi 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_load_lo 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/relocations.s b/llvm/test/MC/RISCV/relocations.s
index 262b3e44c6f007b..d9d941697704c2b 100644
--- a/llvm/test/MC/RISCV/relocations.s
+++ b/llvm/test/MC/RISCV/relocations.s
@@ -176,3 +176,24 @@ bgeu a0, a1, foo
 # RELOC: R_RISCV_JAL
 # INSTR: bgeu a0, a1, foo
 # FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_branch
+
+.L5:
+auipc a0, %tlsdesc_hi(a_symbol)
+# RELOC: R_RISCV_TLSDESC_HI20
+# INST: auipc a0, 0x0
+# FIXUP: fixup A - offset: 0, value: %tlsdesc_hi(a_symbol), kind: fixup_riscv_tlsdesc_hi20
+
+lw a1, %tlsdesc_load_lo(.L5)(a0)
+# RELOC: R_RISCV_TLSDESC_LOAD_LO12
+# INST: lw a1, 0x0(a0)
+# FIXUP: fixup A - offset: 0, value: %tlsdesc_load_lo(.L5), kind: fixup_riscv_tlsdesc_load_lo12
+
+addi a0, a0, %tlsdesc_add_lo(.L5)
+# RELOC: R_RISCV_TLSDESC_ADD_LO12
+# INST: addi a0, a0, 0x0
+# FIXUP: fixup A - offset: 0, value: %tlsdesc_add_lo(.L5), kind: fixup_riscv_tlsdesc_add_lo12
+
+jalr t0, 0(a1), %tlsdesc_call(.L5)
+# RELOC: R_RISCV_TLSDESC_CALL
+# INST: jalr t0, 0x0(a1)
+# FIXUP: fixup A - offset: 0, value: %tlsdesc_call(.L5), kind: fixup_riscv_tlsdesc_call
diff --git a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
index fd42f3892632db1..6e8ccfa17eb644e 100644
--- a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
+++ b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
@@ -1,16 +1,18 @@
-# RUN: llvm-mc -filetype=obj -triple riscv32 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s --check-prefix=INST
 
 start:                                  # @start
 # %bb.0:                                # %entry
 .Ltlsdesc_hi0:
+	auipc a0, %tlsdesc_hi(a-4)
+	# INST: auipc a0, 0x0
 	auipc	a0, %tlsdesc_hi(unspecified)
-	#CHECK: auipc a0, 0x0
+	# INST: auipc a0, 0x0
 	lw	a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
-	#CHECK: lw a1, 0x0(a0)
+	# INST: lw a1, 0x0(a0)
 	addi	a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
-	#CHECK: addi a0, a0, 0x0
+	# INST: addi a0, a0, 0x0
 	jalr	t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
-	#CHECK: jalr t0, 0x0(a1)
+	# INST: jalr t0, 0x0(a1)
 	add	a0, a0, tp
-	#CHECK: add a0, a0, tp
+	# INST: add a0, a0, tp
 	ret
diff --git a/llvm/test/MC/RISCV/rv32d-invalid.s b/llvm/test/MC/RISCV/rv32d-invalid.s
index 5b38a073a71757b..6935c5dce3f770f 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/%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]
+fld ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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 7897897c7735966..f83a393c6af7012 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/%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]
+flw ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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 9075fc2c9749720..0f7f824ab325077 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/%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]
+ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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]
@@ -40,7 +40,7 @@ bgeu t0, t1, -13 # CHECK: :[[@LINE]]:14: error: immediate must be a multiple of
 ## uimm20
 lui a0, -1 # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
 lui s0, 1048576 # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
-auipc zero, -0xf # CHECK: :[[@LINE]]:13: 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 [0, 1048575]
+auipc zero, -0xf # CHECK: :[[@LINE]]:13: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
 
 ## simm21_lsb0
 jal gp, -1048578 # CHECK: :[[@LINE]]:9: error: immediate must be a multiple of 2 bytes in the range [-1048576, 1048574]
@@ -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/%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]
+ori a0, a1, %hi(foo) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_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/%tlsdesc_load_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/%tlsdesc_load_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/%tlsdesc_load_lo 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]
@@ -105,7 +105,7 @@ bgeu t0, t1, %pcrel_lo(d) # CHECK: :[[@LINE]]:14: error: immediate must be a mul
 
 ## uimm20
 lui a0, %lo(1) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
-auipc a1, %lo(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 [0, 1048575]
+auipc a1, %lo(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
 
 ## simm21_lsb0
 jal gp, %lo(1) # CHECK: :[[@LINE]]:9: error: immediate must be a multiple of 2 bytes in the range [-1048576, 1048574]
@@ -125,10 +125,10 @@ lui a0, %lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi
 lui a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
 lui a0, %pcrel_hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
 
-auipc a0, 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 [0, 1048575]
-auipc a0, %lo(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 [0, 1048575]
-auipc a0, %hi(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 [0, 1048575]
-auipc a0, %pcrel_lo(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 [0, 1048575]
+auipc a0, 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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
+auipc a0, %lo(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
+auipc a0, %hi(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
+auipc a0, %pcrel_lo(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
 
 # TP-relative symbol names require a %tprel_add modifier.
 add a0, a0, tp, zero # CHECK: :[[@LINE]]:17: error: expected '%' for operand modifier
diff --git a/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s b/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s
index 967aa14d6032768..91784148273947d 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/%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]
+flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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 f265ae40c0249ad..b7b90cbaca61aa8 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/%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]
+flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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 1549803cd9a71b0..238d7876dd97c45 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/%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]
+flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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 a176d0608062c5a..9759b6ec6b3bbcd 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/%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]
+addiw a0, a1, -2049 # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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/%tlsdesc_hi 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_load_lo 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 79f979fee52abfb..4752e4024b062e8 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/%tlsdesc_hi 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_load_lo 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 fb770973401f622..3b7755d425c10b6 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/%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]
+flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo/%tlsdesc_load_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/%tlsdesc_load_lo 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 ca52e213ed2c854..24309d5201219f6 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/%tlsdesc_hi 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_load_lo 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 5b40b9b50585c4d..73cfebebb873f42 100644
--- a/llvm/test/MC/RISCV/tlsdesc-invalid.s
+++ b/llvm/test/MC/RISCV/tlsdesc-invalid.s
@@ -1,8 +1,9 @@
 # RUN: not llvm-mc %s -triple=riscv32 2>&1 | FileCheck %s
 # RUN: not llvm-mc %s -triple=riscv64 2>&1 | FileCheck %s
 
-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
+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/%tlsdesc_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/%tlsdesc_hi modifier or an integer in the range
+auipc a0, %tlsdesc_hi(a+b) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_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

>From 8458b1971bdca4934dfa77d4ee05b56b9a690dd8 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 00:04:16 +0000
Subject: [PATCH 17/26] Update test directives

---
 llvm/test/MC/RISCV/rv32-tlsdesc-valid.s | 8 +++++++-
 llvm/test/MC/RISCV/tlsdesc-invalid.s    | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
index 6e8ccfa17eb644e..09d2bf97c5589a6 100644
--- a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
+++ b/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
@@ -1,4 +1,5 @@
-# RUN: llvm-mc -filetype=obj -triple riscv32 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s --check-prefix=INST
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s --defsym BIT32=1  | llvm-objdump -d -M no-aliases - | FileCheck %s --check-prefix=INST
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s
 
 start:                                  # @start
 # %bb.0:                                # %entry
@@ -7,8 +8,13 @@ start:                                  # @start
 	# INST: auipc a0, 0x0
 	auipc	a0, %tlsdesc_hi(unspecified)
 	# INST: auipc a0, 0x0
+.ifdef BIT32
 	lw	a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
 	# INST: lw a1, 0x0(a0)
+.else
+	ld	a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
+	#INST: ld a1, 0x0(a0)
+.endif
 	addi	a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
 	# INST: addi a0, a0, 0x0
 	jalr	t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
diff --git a/llvm/test/MC/RISCV/tlsdesc-invalid.s b/llvm/test/MC/RISCV/tlsdesc-invalid.s
index 73cfebebb873f42..81d6892faf5386c 100644
--- a/llvm/test/MC/RISCV/tlsdesc-invalid.s
+++ b/llvm/test/MC/RISCV/tlsdesc-invalid.s
@@ -10,6 +10,7 @@ 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
+addi x1, %tlsdesc_load_lo(a_symbol)(a0) # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
 
 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 e896fb9c8c313f6fbd7601675741ba94f5059732 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 00:05:19 +0000
Subject: [PATCH 18/26] Don't use separate rv32/rv64 files for the same content

---
 llvm/test/MC/RISCV/rv64-tlsdesc-valid.s          | 16 ----------------
 .../{rv32-tlsdesc-valid.s => tlsdesc-valid.s}    |  0
 2 files changed, 16 deletions(-)
 delete mode 100644 llvm/test/MC/RISCV/rv64-tlsdesc-valid.s
 rename llvm/test/MC/RISCV/{rv32-tlsdesc-valid.s => tlsdesc-valid.s} (100%)

diff --git a/llvm/test/MC/RISCV/rv64-tlsdesc-valid.s b/llvm/test/MC/RISCV/rv64-tlsdesc-valid.s
deleted file mode 100644
index 8aba8aac79d7021..000000000000000
--- a/llvm/test/MC/RISCV/rv64-tlsdesc-valid.s
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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
diff --git a/llvm/test/MC/RISCV/rv32-tlsdesc-valid.s b/llvm/test/MC/RISCV/tlsdesc-valid.s
similarity index 100%
rename from llvm/test/MC/RISCV/rv32-tlsdesc-valid.s
rename to llvm/test/MC/RISCV/tlsdesc-valid.s

>From 8f8d5095f51d82c9ed1aa48db14e01a156b00b43 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 00:24:16 +0000
Subject: [PATCH 19/26] Add invalid cases to tlsdesc-valid.s

---
 llvm/test/MC/RISCV/tlsdesc-valid.s | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/llvm/test/MC/RISCV/tlsdesc-valid.s b/llvm/test/MC/RISCV/tlsdesc-valid.s
index 09d2bf97c5589a6..9160b41070fc359 100644
--- a/llvm/test/MC/RISCV/tlsdesc-valid.s
+++ b/llvm/test/MC/RISCV/tlsdesc-valid.s
@@ -1,5 +1,8 @@
-# RUN: llvm-mc -filetype=obj -triple riscv32 < %s --defsym BIT32=1  | llvm-objdump -d -M no-aliases - | FileCheck %s --check-prefix=INST
-# RUN: llvm-mc -filetype=obj -triple riscv64 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s --defsym RV32=1  | llvm-objdump -d -M no-aliases - | FileCheck %s --check-prefixes=INST,RV32
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s | llvm-objdump -d -M no-aliases - | FileCheck %s --check-prefixes=INST,RV64
+
+# RUN: not llvm-mc -triple riscv32 < %s --defsym RV32=1 --defsym ERR=1 2>&1 | FileCheck %s --check-prefixes=ERR
+# RUN: not llvm-mc -triple riscv64 < %s --defsym ERR=1 2>&1 | FileCheck %s --check-prefixes=ERR
 
 start:                                  # @start
 # %bb.0:                                # %entry
@@ -8,12 +11,12 @@ start:                                  # @start
 	# INST: auipc a0, 0x0
 	auipc	a0, %tlsdesc_hi(unspecified)
 	# INST: auipc a0, 0x0
-.ifdef BIT32
+.ifdef RV32
 	lw	a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
-	# INST: lw a1, 0x0(a0)
+	# RV32: lw a1, 0x0(a0)
 .else
 	ld	a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
-	#INST: ld a1, 0x0(a0)
+	#RV64: ld a1, 0x0(a0)
 .endif
 	addi	a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
 	# INST: addi a0, a0, 0x0
@@ -22,3 +25,20 @@ start:                                  # @start
 	add	a0, a0, tp
 	# INST: add a0, a0, tp
 	ret
+
+## Check invalid usage
+.ifdef ERR
+	auipc x1, %tlsdesc_call(foo) # ERR: :[[@LINE]]:12: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range
+	auipc x1, %tlsdesc_call(1234) # ERR: :[[@LINE]]:12: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range
+	auipc a0, %tlsdesc_hi(a+b) # ERR: :[[@LINE]]:12: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range
+
+	lw   a0, t0, %tlsdesc_load_lo(a_symbol) # ERR: :[[@LINE]]:15: error: invalid operand for instruction
+	lw   a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # ERR: :[[@LINE]]:15: error: invalid operand for instruction
+
+	addi a0, t0, %tlsdesc_add_lo(a_symbol)(a4) # ERR: :[[@LINE]]:41: error: invalid operand for instruction
+	addi a0, %tlsdesc_add_lo(a_symbol) # ERR: :[[@LINE]]:11: error: invalid operand for instruction
+	addi x1, %tlsdesc_load_lo(a_symbol)(a0) # ERR: :[[@LINE]]:11: error: invalid operand for instruction
+
+	jalr x5, 0(a1), %tlsdesc_hi(a_symbol) # ERR: :[[@LINE]]:18: error: operand must be a symbol with %tlsdesc_call modifier
+	jalr x1, 0(a1), %tlsdesc_call(a_symbol) # ERR: :[[@LINE]]:13: error: the output operand must be t0/x5 when using %tlsdesc_call modifier
+.endif

>From 2975f08f9ea06f61b723971cfd949a34747ef61a Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 00:25:07 +0000
Subject: [PATCH 20/26] Consolidate valid/invalid tlsdesc test files

---
 llvm/test/MC/RISCV/tlsdesc-invalid.s             | 16 ----------------
 .../test/MC/RISCV/{tlsdesc-valid.s => tlsdesc.s} |  0
 2 files changed, 16 deletions(-)
 delete mode 100644 llvm/test/MC/RISCV/tlsdesc-invalid.s
 rename llvm/test/MC/RISCV/{tlsdesc-valid.s => tlsdesc.s} (100%)

diff --git a/llvm/test/MC/RISCV/tlsdesc-invalid.s b/llvm/test/MC/RISCV/tlsdesc-invalid.s
deleted file mode 100644
index 81d6892faf5386c..000000000000000
--- a/llvm/test/MC/RISCV/tlsdesc-invalid.s
+++ /dev/null
@@ -1,16 +0,0 @@
-# RUN: not llvm-mc %s -triple=riscv32 2>&1 | FileCheck %s
-# RUN: not llvm-mc %s -triple=riscv64 2>&1 | FileCheck %s
-
-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/%tlsdesc_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/%tlsdesc_hi modifier or an integer in the range
-auipc a0, %tlsdesc_hi(a+b) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_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
-
-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
-addi x1, %tlsdesc_load_lo(a_symbol)(a0) # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
-
-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
diff --git a/llvm/test/MC/RISCV/tlsdesc-valid.s b/llvm/test/MC/RISCV/tlsdesc.s
similarity index 100%
rename from llvm/test/MC/RISCV/tlsdesc-valid.s
rename to llvm/test/MC/RISCV/tlsdesc.s

>From ead5e4ceb8d06129221043ab9ab990bac8a8b198 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 00:26:53 +0000
Subject: [PATCH 21/26] Clang format

---
 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 4473f0ef6b048b8..9f684b86bffcb16 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1537,7 +1537,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 20) - 1,
         "operand must be a symbol with a "
-        "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or "
+        "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi "
+        "modifier or "
         "an integer in the range");
   case Match_InvalidSImm21Lsb0JAL:
     return generateImmOutOfRangeError(

>From 53cbeb6fa87bec2e5efa615d76ef7137b097cf48 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 17:14:09 +0000
Subject: [PATCH 22/26] Avoid changing error message for now.

---
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp |  8 +++---
 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            | 26 +++++++++----------
 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.s                  |  6 ++---
 15 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 9f684b86bffcb16..60cbb984f2ea812 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1511,9 +1511,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_load_lo modifier or an integer in "
-        "the range");
+        "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
+        "integer in the range");
   case Match_InvalidSImm12Lsb0:
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
@@ -1537,8 +1536,7 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 20) - 1,
         "operand must be a symbol with a "
-        "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi "
-        "modifier or "
+        "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
         "an integer in the range");
   case Match_InvalidSImm21Lsb0JAL:
     return generateImmOutOfRangeError(
diff --git a/llvm/test/MC/RISCV/corev/XCVelw-invalid.s b/llvm/test/MC/RISCV/corev/XCVelw-invalid.s
index 28510d4b00c46b2..24870904ac49b1c 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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 ca82d60be5d5f3a..e71cd7daa890e60 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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/%tlsdesc_load_lo modifier or an integer in the range [-2048, 2047]
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo 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 28d7341967548d6..32ebd6867377c2c 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/%tlsdesc_load_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 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 6935c5dce3f770f..ee363ec7db79cb4 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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 f83a393c6af7012..f2d368071a0bbbf 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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 0f7f824ab325077..c509883e69e640d 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 ## uimm12
 csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
@@ -40,7 +40,7 @@ bgeu t0, t1, -13 # CHECK: :[[@LINE]]:14: error: immediate must be a multiple of
 ## uimm20
 lui a0, -1 # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
 lui s0, 1048576 # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
-auipc zero, -0xf # CHECK: :[[@LINE]]:13: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
+auipc zero, -0xf # CHECK: :[[@LINE]]:13: 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 [0, 1048575]
 
 ## simm21_lsb0
 jal gp, -1048578 # CHECK: :[[@LINE]]:9: error: immediate must be a multiple of 2 bytes in the range [-1048576, 1048574]
@@ -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/%tlsdesc_load_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/%tlsdesc_load_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/%tlsdesc_load_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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 ## uimm12
 csrrw a0, %lo(1), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
@@ -105,7 +105,7 @@ bgeu t0, t1, %pcrel_lo(d) # CHECK: :[[@LINE]]:14: error: immediate must be a mul
 
 ## uimm20
 lui a0, %lo(1) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
-auipc a1, %lo(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
+auipc a1, %lo(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 [0, 1048575]
 
 ## simm21_lsb0
 jal gp, %lo(1) # CHECK: :[[@LINE]]:9: error: immediate must be a multiple of 2 bytes in the range [-1048576, 1048574]
@@ -125,10 +125,10 @@ lui a0, %lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi
 lui a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
 lui a0, %pcrel_hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575]
 
-auipc a0, 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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
-auipc a0, %lo(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
-auipc a0, %hi(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
-auipc a0, %pcrel_lo(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/%tlsdesc_hi modifier or an integer in the range [0, 1048575]
+auipc a0, 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 [0, 1048575]
+auipc a0, %lo(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 [0, 1048575]
+auipc a0, %hi(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 [0, 1048575]
+auipc a0, %pcrel_lo(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 [0, 1048575]
 
 # TP-relative symbol names require a %tprel_add modifier.
 add a0, a0, tp, zero # CHECK: :[[@LINE]]:17: error: expected '%' for operand modifier
diff --git a/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s b/llvm/test/MC/RISCV/rv32zfbfmin-invalid.s
index 91784148273947d..b7b5a0a84b32dfc 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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 b7b90cbaca61aa8..efa5e871616f667 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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 238d7876dd97c45..8fe90d4f7100c2f 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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 9759b6ec6b3bbcd..deb8ea54fde35e4 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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/%tlsdesc_load_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 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 4752e4024b062e8..31414d87e6f4e54 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/%tlsdesc_load_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 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 3b7755d425c10b6..d6835746f0a8cfc 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/%tlsdesc_load_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/%tlsdesc_load_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 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]
 
 # 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 24309d5201219f6..c10bef53732b232 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/%tlsdesc_load_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 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.s b/llvm/test/MC/RISCV/tlsdesc.s
index 9160b41070fc359..673dd07426d50b7 100644
--- a/llvm/test/MC/RISCV/tlsdesc.s
+++ b/llvm/test/MC/RISCV/tlsdesc.s
@@ -28,9 +28,9 @@ start:                                  # @start
 
 ## Check invalid usage
 .ifdef ERR
-	auipc x1, %tlsdesc_call(foo) # ERR: :[[@LINE]]:12: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range
-	auipc x1, %tlsdesc_call(1234) # ERR: :[[@LINE]]:12: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range
-	auipc a0, %tlsdesc_hi(a+b) # ERR: :[[@LINE]]:12: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi/%tlsdesc_hi modifier or an integer in the range
+	auipc x1, %tlsdesc_call(foo) # ERR: :[[@LINE]]:12: 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) # ERR: :[[@LINE]]:12: 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 a0, %tlsdesc_hi(a+b) # ERR: :[[@LINE]]:12: 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) # ERR: :[[@LINE]]:15: error: invalid operand for instruction
 	lw   a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # ERR: :[[@LINE]]:15: error: invalid operand for instruction

>From 30df9eb6f8c6376f6c8f9e2505d191c1947b09f1 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 17:22:41 +0000
Subject: [PATCH 23/26] Update LINE directives in test

---
 llvm/test/MC/RISCV/tlsdesc.s | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/llvm/test/MC/RISCV/tlsdesc.s b/llvm/test/MC/RISCV/tlsdesc.s
index 673dd07426d50b7..f455e266ab1557d 100644
--- a/llvm/test/MC/RISCV/tlsdesc.s
+++ b/llvm/test/MC/RISCV/tlsdesc.s
@@ -28,17 +28,17 @@ start:                                  # @start
 
 ## Check invalid usage
 .ifdef ERR
-	auipc x1, %tlsdesc_call(foo) # ERR: :[[@LINE]]:12: 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) # ERR: :[[@LINE]]:12: 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 a0, %tlsdesc_hi(a+b) # ERR: :[[@LINE]]:12: 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(foo) # ERR: :[[#@LINE]]:12: 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) # ERR: :[[#@LINE]]:12: 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 a0, %tlsdesc_hi(a+b) # ERR: :[[#@LINE]]:12: 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) # ERR: :[[@LINE]]:15: error: invalid operand for instruction
-	lw   a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # ERR: :[[@LINE]]:15: error: invalid operand for instruction
+	lw   a0, t0, %tlsdesc_load_lo(a_symbol) # ERR: :[[#@LINE]]:15: error: invalid operand for instruction
+	lw   a0, t0, %tlsdesc_load_lo(a_symbol)(a4) # ERR: :[[#@LINE]]:15: error: invalid operand for instruction
 
-	addi a0, t0, %tlsdesc_add_lo(a_symbol)(a4) # ERR: :[[@LINE]]:41: error: invalid operand for instruction
-	addi a0, %tlsdesc_add_lo(a_symbol) # ERR: :[[@LINE]]:11: error: invalid operand for instruction
-	addi x1, %tlsdesc_load_lo(a_symbol)(a0) # ERR: :[[@LINE]]:11: error: invalid operand for instruction
+	addi a0, t0, %tlsdesc_add_lo(a_symbol)(a4) # ERR: :[[#@LINE]]:41: error: invalid operand for instruction
+	addi a0, %tlsdesc_add_lo(a_symbol) # ERR: :[[#@LINE]]:11: error: invalid operand for instruction
+	addi x1, %tlsdesc_load_lo(a_symbol)(a0) # ERR: :[[#@LINE]]:11: error: invalid operand for instruction
 
-	jalr x5, 0(a1), %tlsdesc_hi(a_symbol) # ERR: :[[@LINE]]:18: error: operand must be a symbol with %tlsdesc_call modifier
-	jalr x1, 0(a1), %tlsdesc_call(a_symbol) # ERR: :[[@LINE]]:13: error: the output operand must be t0/x5 when using %tlsdesc_call modifier
+	jalr x5, 0(a1), %tlsdesc_hi(a_symbol) # ERR: :[[#@LINE]]:18: error: operand must be a symbol with %tlsdesc_call modifier
+	jalr x1, 0(a1), %tlsdesc_call(a_symbol) # ERR: :[[#@LINE]]:13: error: the output operand must be t0/x5 when using %tlsdesc_call modifier
 .endif

>From 193ad23a233bd1671c675eb3dfac2f8193c98cd1 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 17:23:35 +0000
Subject: [PATCH 24/26] Remove redundant checks in rvi32 test

These make more sense in a dedicated tlsdesc test file.
---
 llvm/test/MC/RISCV/rv32i-invalid.s | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/llvm/test/MC/RISCV/rv32i-invalid.s b/llvm/test/MC/RISCV/rv32i-invalid.s
index c509883e69e640d..c5e0657b838094f 100644
--- a/llvm/test/MC/RISCV/rv32i-invalid.s
+++ b/llvm/test/MC/RISCV/rv32i-invalid.s
@@ -188,8 +188,3 @@ 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 c3baeaac684fa1962683b157639c60faf0ab1b55 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Tue, 9 Jan 2024 17:34:18 +0000
Subject: [PATCH 25/26] Reduce number of comments for TLSDESC fixups

---
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
index 8304826830dde4c..821372d3d39a63f 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
@@ -71,17 +71,11 @@ 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
+  // Fixups indicating a TLS descriptor code sequence, corresponding to auipc,
+  // lw/ld, addi, and jalr, respectively.
   fixup_riscv_tlsdesc_hi20,
-  // 12-bit fixup corresponding to %tlsdesc_load_lo(foo) for instructions like
-  // lw
   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

>From 2f714ddd30db9fbc6925dcd7ca905f83937dc313 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574 at gmail.com>
Date: Thu, 18 Jan 2024 23:14:38 +0000
Subject: [PATCH 26/26] Move EnableRISCVTLSDESC option to CodeGen/CommandFlags

---
 llvm/include/llvm/CodeGen/CommandFlags.h     |   3 +
 llvm/include/llvm/Target/TargetMachine.h     |   3 +
 llvm/include/llvm/Target/TargetOptions.h     |  17 +-
 llvm/include/llvm/TargetParser/Triple.h      |   7 +
 llvm/lib/CodeGen/CommandFlags.cpp            |   8 +
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp  | 809 ++++++++++---------
 llvm/lib/Target/RISCV/RISCVTargetMachine.cpp |   5 -
 llvm/lib/Target/TargetMachine.cpp            |   1 +
 llvm/test/CodeGen/RISCV/tls-models.ll        |   8 +-
 9 files changed, 478 insertions(+), 383 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index 6407dde5bcd6c78..bf166a63edb0713 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -117,6 +117,9 @@ unsigned getTLSSize();
 bool getEmulatedTLS();
 std::optional<bool> getExplicitEmulatedTLS();
 
+bool getEnableTLSDESC();
+std::optional<bool> getExplicitEnableTLSDESC();
+
 bool getUniqueSectionNames();
 
 bool getUniqueBasicBlockSectionNames();
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index 1fe47dec70b1630..a522a12299bb029 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -248,6 +248,9 @@ class TargetMachine {
   /// Returns true if this target uses emulated TLS.
   bool useEmulatedTLS() const;
 
+  /// Returns true if this target uses TLS Descriptors.
+  bool useTLSDESC() const;
+
   /// Returns the TLS model which should be used for the given global variable.
   TLSModel::Model getTLSModel(const GlobalValue *GV) const;
 
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 4df897c047a38ac..71e83feae9060e2 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -145,13 +145,13 @@ namespace llvm {
           IgnoreXCOFFVisibility(false), XCOFFTracebackTable(true),
           UniqueSectionNames(true), UniqueBasicBlockSectionNames(false),
           TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
-          EmulatedTLS(false), EnableIPRA(false), EmitStackSizeSection(false),
-          EnableMachineOutliner(false), EnableMachineFunctionSplitter(false),
-          SupportsDefaultOutlining(false), EmitAddrsig(false),
-          EmitCallSiteInfo(false), SupportsDebugEntryValues(false),
-          EnableDebugEntryValues(false), ValueTrackingVariableLocations(false),
-          ForceDwarfFrameSection(false), XRayFunctionIndex(true),
-          DebugStrictDwarf(false), Hotpatch(false),
+          EmulatedTLS(false), EnableTLSDESC(false), EnableIPRA(false),
+          EmitStackSizeSection(false), EnableMachineOutliner(false),
+          EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
+          EmitAddrsig(false), EmitCallSiteInfo(false),
+          SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
+          ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
+          XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
           PPCGenScalarMASSEntries(false), JMCInstrument(false),
           EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
           FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
@@ -295,6 +295,9 @@ namespace llvm {
     /// function in the runtime library..
     unsigned EmulatedTLS : 1;
 
+    /// EnableTLSDESC - This flag enables TLS Descriptors.
+    unsigned EnableTLSDESC: 1;
+
     /// This flag enables InterProcedural Register Allocation (IPRA).
     unsigned EnableIPRA : 1;
 
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 95014a546f72453..3032db246b8343f 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -1021,6 +1021,13 @@ class Triple {
            isWindowsCygwinEnvironment() || isOHOSFamily();
   }
 
+  /// Tests whether the target uses TLS Descriptor by default.
+  bool hasDefaultTLSDESC() const {
+    // TODO: Improve check for other platforms, like Android, and RISC-V
+    // Note: This is currently only used on RISC-V.
+    return isOSBinFormatELF() && isAArch64();
+  }
+
   /// Tests whether the target uses -data-sections as default.
   bool hasDefaultDataSections() const {
     return isOSBinFormatXCOFF() || isWasm();
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index c6d7827f36dfd63..51406fb287e6653 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -93,6 +93,7 @@ CGOPT(bool, XCOFFTracebackTable)
 CGOPT(std::string, BBSections)
 CGOPT(unsigned, TLSSize)
 CGOPT_EXP(bool, EmulatedTLS)
+CGOPT_EXP(bool, EnableTLSDESC)
 CGOPT(bool, UniqueSectionNames)
 CGOPT(bool, UniqueBasicBlockSectionNames)
 CGOPT(EABI, EABIVersion)
@@ -404,6 +405,11 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
       "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
   CGBINDOPT(EmulatedTLS);
 
+  static cl::opt<bool> EnableTLSDESC(
+      "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
+      cl::init(false));
+  CGBINDOPT(EnableTLSDESC);
+
   static cl::opt<bool> UniqueSectionNames(
       "unique-section-names", cl::desc("Give unique names to every section"),
       cl::init(true));
@@ -568,6 +574,8 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
   Options.TLSSize = getTLSSize();
   Options.EmulatedTLS =
       getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
+  Options.EnableTLSDESC =
+      getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
   Options.ExceptionModel = getExceptionModel();
   Options.EmitStackSizeSection = getEnableStackSizeSection();
   Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 92e697c02826242..2ccebb210f03b04 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -51,8 +51,6 @@ 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 "
@@ -94,8 +92,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
   if ((ABI == RISCVABI::ABI_ILP32F || ABI == RISCVABI::ABI_LP64F) &&
       !Subtarget.hasStdExtF()) {
     errs() << "Hard-float 'f' ABI can't be used for a target that "
-                "doesn't support the F instruction set extension (ignoring "
-                          "target-abi)\n";
+              "doesn't support the F instruction set extension (ignoring "
+              "target-abi)\n";
     ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
   } else if ((ABI == RISCVABI::ABI_ILP32D || ABI == RISCVABI::ABI_LP64D) &&
              !Subtarget.hasStdExtD()) {
@@ -160,8 +158,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
       MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
   static const MVT::SimpleValueType F32VecVTs[] = {
       MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
-  static const MVT::SimpleValueType F64VecVTs[] = {
-      MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
+  static const MVT::SimpleValueType F64VecVTs[] = {MVT::nxv1f64, MVT::nxv2f64,
+                                                   MVT::nxv4f64, MVT::nxv8f64};
 
   if (Subtarget.hasVInstructions()) {
     auto addRegClassForRVV = [this](MVT VT) {
@@ -305,8 +303,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
   }
 
   if (!Subtarget.hasStdExtM()) {
-    setOperationAction({ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM},
-                       XLenVT, Expand);
+    setOperationAction({ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM}, XLenVT,
+                       Expand);
     if (RV64LegalI32 && Subtarget.is64Bit())
       setOperationAction({ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM}, MVT::i32,
                          Promote);
@@ -359,7 +357,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
                            ? Promote
                            : Expand);
 
-
   if (Subtarget.hasVendorXCVbitmanip()) {
     setOperationAction(ISD::BITREVERSE, XLenVT, Legal);
   } else {
@@ -433,13 +430,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
       ISD::SETUGE, ISD::SETULT, ISD::SETULE, ISD::SETUNE, ISD::SETGT,
       ISD::SETGE,  ISD::SETNE,  ISD::SETO,   ISD::SETUO};
 
-  static const unsigned FPOpToExpand[] = {
-      ISD::FSIN, ISD::FCOS,       ISD::FSINCOS,   ISD::FPOW,
-      ISD::FREM};
+  static const unsigned FPOpToExpand[] = {ISD::FSIN, ISD::FCOS, ISD::FSINCOS,
+                                          ISD::FPOW, ISD::FREM};
 
-  static const unsigned FPRndMode[] = {
-      ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FRINT, ISD::FROUND,
-      ISD::FROUNDEVEN};
+  static const unsigned FPRndMode[] = {ISD::FCEIL,  ISD::FFLOOR,
+                                       ISD::FTRUNC, ISD::FRINT,
+                                       ISD::FROUND, ISD::FROUNDEVEN};
 
   if (Subtarget.hasStdExtZfhminOrZhinxmin())
     setOperationAction(ISD::BITCAST, MVT::i16, Custom);
@@ -496,10 +492,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
 
     setOperationAction(ISD::FNEARBYINT, MVT::f16,
                        Subtarget.hasStdExtZfa() ? Legal : Promote);
-    setOperationAction({ISD::FREM, ISD::FPOW, ISD::FPOWI,
-                        ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
-                        ISD::FEXP2, ISD::FEXP10, ISD::FLOG, ISD::FLOG2,
-                        ISD::FLOG10},
+    setOperationAction({ISD::FREM, ISD::FPOW, ISD::FPOWI, ISD::FCOS, ISD::FSIN,
+                        ISD::FSINCOS, ISD::FEXP, ISD::FEXP2, ISD::FEXP10,
+                        ISD::FLOG, ISD::FLOG2, ISD::FLOG10},
                        MVT::f16, Promote);
 
     // FIXME: Need to promote f16 STRICT_* to f32 libcalls, but we don't have
@@ -652,9 +647,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
 
     // RVV intrinsics may have illegal operands.
     // We also need to custom legalize vmv.x.s.
-    setOperationAction({ISD::INTRINSIC_WO_CHAIN, ISD::INTRINSIC_W_CHAIN,
-                        ISD::INTRINSIC_VOID},
-                       {MVT::i8, MVT::i16}, Custom);
+    setOperationAction(
+        {ISD::INTRINSIC_WO_CHAIN, ISD::INTRINSIC_W_CHAIN, ISD::INTRINSIC_VOID},
+        {MVT::i8, MVT::i16}, Custom);
     if (Subtarget.is64Bit())
       setOperationAction({ISD::INTRINSIC_W_CHAIN, ISD::INTRINSIC_VOID},
                          MVT::i32, Custom);
@@ -665,32 +660,75 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction({ISD::INTRINSIC_W_CHAIN, ISD::INTRINSIC_VOID},
                        MVT::Other, Custom);
 
-    static const unsigned IntegerVPOps[] = {
-        ISD::VP_ADD,         ISD::VP_SUB,         ISD::VP_MUL,
-        ISD::VP_SDIV,        ISD::VP_UDIV,        ISD::VP_SREM,
-        ISD::VP_UREM,        ISD::VP_AND,         ISD::VP_OR,
-        ISD::VP_XOR,         ISD::VP_ASHR,        ISD::VP_LSHR,
-        ISD::VP_SHL,         ISD::VP_REDUCE_ADD,  ISD::VP_REDUCE_AND,
-        ISD::VP_REDUCE_OR,   ISD::VP_REDUCE_XOR,  ISD::VP_REDUCE_SMAX,
-        ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
-        ISD::VP_MERGE,       ISD::VP_SELECT,      ISD::VP_FP_TO_SINT,
-        ISD::VP_FP_TO_UINT,  ISD::VP_SETCC,       ISD::VP_SIGN_EXTEND,
-        ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE,    ISD::VP_SMIN,
-        ISD::VP_SMAX,        ISD::VP_UMIN,        ISD::VP_UMAX,
-        ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE};
-
-    static const unsigned FloatingPointVPOps[] = {
-        ISD::VP_FADD,        ISD::VP_FSUB,        ISD::VP_FMUL,
-        ISD::VP_FDIV,        ISD::VP_FNEG,        ISD::VP_FABS,
-        ISD::VP_FMA,         ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
-        ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
-        ISD::VP_SELECT,      ISD::VP_SINT_TO_FP,  ISD::VP_UINT_TO_FP,
-        ISD::VP_SETCC,       ISD::VP_FP_ROUND,    ISD::VP_FP_EXTEND,
-        ISD::VP_SQRT,        ISD::VP_FMINNUM,     ISD::VP_FMAXNUM,
-        ISD::VP_FCEIL,       ISD::VP_FFLOOR,      ISD::VP_FROUND,
-        ISD::VP_FROUNDEVEN,  ISD::VP_FCOPYSIGN,   ISD::VP_FROUNDTOZERO,
-        ISD::VP_FRINT,       ISD::VP_FNEARBYINT,  ISD::VP_IS_FPCLASS,
-        ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE};
+    static const unsigned IntegerVPOps[] = {ISD::VP_ADD,
+                                            ISD::VP_SUB,
+                                            ISD::VP_MUL,
+                                            ISD::VP_SDIV,
+                                            ISD::VP_UDIV,
+                                            ISD::VP_SREM,
+                                            ISD::VP_UREM,
+                                            ISD::VP_AND,
+                                            ISD::VP_OR,
+                                            ISD::VP_XOR,
+                                            ISD::VP_ASHR,
+                                            ISD::VP_LSHR,
+                                            ISD::VP_SHL,
+                                            ISD::VP_REDUCE_ADD,
+                                            ISD::VP_REDUCE_AND,
+                                            ISD::VP_REDUCE_OR,
+                                            ISD::VP_REDUCE_XOR,
+                                            ISD::VP_REDUCE_SMAX,
+                                            ISD::VP_REDUCE_SMIN,
+                                            ISD::VP_REDUCE_UMAX,
+                                            ISD::VP_REDUCE_UMIN,
+                                            ISD::VP_MERGE,
+                                            ISD::VP_SELECT,
+                                            ISD::VP_FP_TO_SINT,
+                                            ISD::VP_FP_TO_UINT,
+                                            ISD::VP_SETCC,
+                                            ISD::VP_SIGN_EXTEND,
+                                            ISD::VP_ZERO_EXTEND,
+                                            ISD::VP_TRUNCATE,
+                                            ISD::VP_SMIN,
+                                            ISD::VP_SMAX,
+                                            ISD::VP_UMIN,
+                                            ISD::VP_UMAX,
+                                            ISD::VP_ABS,
+                                            ISD::EXPERIMENTAL_VP_REVERSE,
+                                            ISD::EXPERIMENTAL_VP_SPLICE};
+
+    static const unsigned FloatingPointVPOps[] = {ISD::VP_FADD,
+                                                  ISD::VP_FSUB,
+                                                  ISD::VP_FMUL,
+                                                  ISD::VP_FDIV,
+                                                  ISD::VP_FNEG,
+                                                  ISD::VP_FABS,
+                                                  ISD::VP_FMA,
+                                                  ISD::VP_REDUCE_FADD,
+                                                  ISD::VP_REDUCE_SEQ_FADD,
+                                                  ISD::VP_REDUCE_FMIN,
+                                                  ISD::VP_REDUCE_FMAX,
+                                                  ISD::VP_MERGE,
+                                                  ISD::VP_SELECT,
+                                                  ISD::VP_SINT_TO_FP,
+                                                  ISD::VP_UINT_TO_FP,
+                                                  ISD::VP_SETCC,
+                                                  ISD::VP_FP_ROUND,
+                                                  ISD::VP_FP_EXTEND,
+                                                  ISD::VP_SQRT,
+                                                  ISD::VP_FMINNUM,
+                                                  ISD::VP_FMAXNUM,
+                                                  ISD::VP_FCEIL,
+                                                  ISD::VP_FFLOOR,
+                                                  ISD::VP_FROUND,
+                                                  ISD::VP_FROUNDEVEN,
+                                                  ISD::VP_FCOPYSIGN,
+                                                  ISD::VP_FROUNDTOZERO,
+                                                  ISD::VP_FRINT,
+                                                  ISD::VP_FNEARBYINT,
+                                                  ISD::VP_IS_FPCLASS,
+                                                  ISD::EXPERIMENTAL_VP_REVERSE,
+                                                  ISD::EXPERIMENTAL_VP_SPLICE};
 
     static const unsigned IntegerVecReduceOps[] = {
         ISD::VECREDUCE_ADD,  ISD::VECREDUCE_AND,  ISD::VECREDUCE_OR,
@@ -1398,12 +1436,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setTargetDAGCombine({ISD::ZERO_EXTEND, ISD::FP_TO_SINT, ISD::FP_TO_UINT,
                          ISD::FP_TO_SINT_SAT, ISD::FP_TO_UINT_SAT});
   if (Subtarget.hasVInstructions())
-    setTargetDAGCombine({ISD::FCOPYSIGN, ISD::MGATHER, ISD::MSCATTER,
-                         ISD::VP_GATHER, ISD::VP_SCATTER, ISD::SRA, ISD::SRL,
-                         ISD::SHL, ISD::STORE, ISD::SPLAT_VECTOR,
-                         ISD::BUILD_VECTOR, ISD::CONCAT_VECTORS,
-                         ISD::EXPERIMENTAL_VP_REVERSE, ISD::MUL,
-                         ISD::INSERT_VECTOR_ELT});
+    setTargetDAGCombine(
+        {ISD::FCOPYSIGN, ISD::MGATHER, ISD::MSCATTER, ISD::VP_GATHER,
+         ISD::VP_SCATTER, ISD::SRA, ISD::SRL, ISD::SHL, ISD::STORE,
+         ISD::SPLAT_VECTOR, ISD::BUILD_VECTOR, ISD::CONCAT_VECTORS,
+         ISD::EXPERIMENTAL_VP_REVERSE, ISD::MUL, ISD::INSERT_VECTOR_ELT});
   if (Subtarget.hasVendorXTHeadMemPair())
     setTargetDAGCombine({ISD::LOAD, ISD::STORE});
   if (Subtarget.useRVVForFixedLengthVectors())
@@ -1949,7 +1986,6 @@ bool RISCVTargetLowering::canSplatOperand(unsigned Opcode, int Operand) const {
   }
 }
 
-
 bool RISCVTargetLowering::canSplatOperand(Instruction *I, int Operand) const {
   if (!I->getType()->isVectorTy() || !Subtarget.hasVInstructions())
     return false;
@@ -2170,8 +2206,8 @@ bool RISCVTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
 }
 
 MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
-                                                      CallingConv::ID CC,
-                                                      EVT VT) const {
+                                                       CallingConv::ID CC,
+                                                       EVT VT) const {
   // Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled.
   // We might still end up using a GPR but that will be decided based on ABI.
   if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
@@ -2186,9 +2222,8 @@ MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
   return PartVT;
 }
 
-unsigned RISCVTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
-                                                           CallingConv::ID CC,
-                                                           EVT VT) const {
+unsigned RISCVTargetLowering::getNumRegistersForCallingConv(
+    LLVMContext &Context, CallingConv::ID CC, EVT VT) const {
   // Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled.
   // We might still end up using a GPR but that will be decided based on ABI.
   if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
@@ -2245,7 +2280,8 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
   if (auto *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
     int64_t C = RHSC->getSExtValue();
     switch (CC) {
-    default: break;
+    default:
+      break;
     case ISD::SETGT:
       // Convert X > -1 to X >= 0.
       if (C == -1) {
@@ -2325,10 +2361,8 @@ unsigned RISCVTargetLowering::getRegClassIDForLMUL(RISCVII::VLMUL LMul) {
 
 unsigned RISCVTargetLowering::getSubregIndexByMVT(MVT VT, unsigned Index) {
   RISCVII::VLMUL LMUL = getLMUL(VT);
-  if (LMUL == RISCVII::VLMUL::LMUL_F8 ||
-      LMUL == RISCVII::VLMUL::LMUL_F4 ||
-      LMUL == RISCVII::VLMUL::LMUL_F2 ||
-      LMUL == RISCVII::VLMUL::LMUL_1) {
+  if (LMUL == RISCVII::VLMUL::LMUL_F8 || LMUL == RISCVII::VLMUL::LMUL_F4 ||
+      LMUL == RISCVII::VLMUL::LMUL_F2 || LMUL == RISCVII::VLMUL::LMUL_1) {
     static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
                   "Unexpected subreg numbering");
     return RISCV::sub_vrm1_0 + Index;
@@ -2418,7 +2452,6 @@ bool RISCVTargetLowering::isLegalElementTypeForRVV(EVT ScalarTy) const {
   }
 }
 
-
 unsigned RISCVTargetLowering::combineRepeatedFPDivisors() const {
   return NumRepeatedDivisors;
 }
@@ -2693,12 +2726,12 @@ InstructionCost RISCVTargetLowering::getLMULCost(MVT VT) const {
     else
       Cost = (LMul * DLenFactor);
   } else {
-    Cost = divideCeil(VT.getSizeInBits(), Subtarget.getRealMinVLen() / DLenFactor);
+    Cost =
+        divideCeil(VT.getSizeInBits(), Subtarget.getRealMinVLen() / DLenFactor);
   }
   return Cost;
 }
 
-
 /// Return the cost of a vrgather.vv instruction for the type VT.  vrgather.vv
 /// is generally quadratic in the number of vreg implied by LMUL.  Note that
 /// operand (index and possibly mask) are handled separately.
@@ -2809,7 +2842,8 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG,
   // Need to widen by more than 1 step, promote the FP type, then do a widening
   // convert.
   if (DstEltSize > (2 * SrcEltSize)) {
-    assert(SrcContainerVT.getVectorElementType() == MVT::f16 && "Unexpected VT!");
+    assert(SrcContainerVT.getVectorElementType() == MVT::f16 &&
+           "Unexpected VT!");
     MVT InterVT = SrcContainerVT.changeVectorElementType(MVT::f32);
     Src = DAG.getNode(RISCVISD::FP_EXTEND_VL, DL, InterVT, Src, Mask, VL);
   }
@@ -2911,10 +2945,9 @@ lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(SDValue Op, SelectionDAG &DAG,
 
   // If abs(Src) was larger than MaxVal or nan, keep it.
   MVT SetccVT = MVT::getVectorVT(MVT::i1, ContainerVT.getVectorElementCount());
-  Mask =
-      DAG.getNode(RISCVISD::SETCC_VL, DL, SetccVT,
-                  {Abs, MaxValSplat, DAG.getCondCode(ISD::SETOLT),
-                   Mask, Mask, VL});
+  Mask = DAG.getNode(
+      RISCVISD::SETCC_VL, DL, SetccVT,
+      {Abs, MaxValSplat, DAG.getCondCode(ISD::SETOLT), Mask, Mask, VL});
 
   // Truncate to integer and convert back to FP.
   MVT IntVT = ContainerVT.changeVectorElementTypeToInteger();
@@ -2940,8 +2973,8 @@ lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(SDValue Op, SelectionDAG &DAG,
     break;
   }
   case ISD::FTRUNC:
-    Truncated = DAG.getNode(RISCVISD::VFCVT_RTZ_X_F_VL, DL, IntVT, Src,
-                            Mask, VL);
+    Truncated =
+        DAG.getNode(RISCVISD::VFCVT_RTZ_X_F_VL, DL, IntVT, Src, Mask, VL);
     break;
   case ISD::FRINT:
   case ISD::VP_FRINT:
@@ -3331,7 +3364,6 @@ static SDValue matchSplatAsGather(SDValue SplatVal, MVT VT, const SDLoc &DL,
   return convertFromScalableVector(VT, Gather, DAG, Subtarget);
 }
 
-
 /// Try and optimize BUILD_VECTORs with "dominant values" - these are values
 /// which constitute a large proportion of the elements. In such cases we can
 /// splat a vector with the dominant element and make up the shortfall with
@@ -3340,8 +3372,9 @@ static SDValue matchSplatAsGather(SDValue SplatVal, MVT VT, const SDLoc &DL,
 /// upper-most element is the "dominant" one, allowing us to use a splat to
 /// "insert" the upper element, and an insert of the lower element at position
 /// 0, which improves codegen.
-static SDValue lowerBuildVectorViaDominantValues(SDValue Op, SelectionDAG &DAG,
-                                                 const RISCVSubtarget &Subtarget) {
+static SDValue
+lowerBuildVectorViaDominantValues(SDValue Op, SelectionDAG &DAG,
+                                  const RISCVSubtarget &Subtarget) {
   MVT VT = Op.getSimpleValueType();
   assert(VT.isFixedLengthVector() && "Unexpected vector!");
 
@@ -3409,8 +3442,8 @@ static SDValue lowerBuildVectorViaDominantValues(SDValue Op, SelectionDAG &DAG,
         !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
         LastOp != DominantValue) {
       Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget);
-      auto OpCode =
-        VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
+      auto OpCode = VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL
+                                         : RISCVISD::VSLIDE1DOWN_VL;
       if (!VT.isFloatingPoint())
         LastOp = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, LastOp);
       Vec = DAG.getNode(OpCode, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Vec,
@@ -3489,9 +3522,8 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
     // Now we can create our integer vector type. Note that it may be larger
     // than the resulting mask type: v4i1 would use v1i8 as its integer type.
     unsigned IntegerViaVecElts = divideCeil(NumElts, NumViaIntegerBits);
-    MVT IntegerViaVecVT =
-      MVT::getVectorVT(MVT::getIntegerVT(NumViaIntegerBits),
-                       IntegerViaVecElts);
+    MVT IntegerViaVecVT = MVT::getVectorVT(MVT::getIntegerVT(NumViaIntegerBits),
+                                           IntegerViaVecElts);
 
     uint64_t Bits = 0;
     unsigned BitPos = 0, IntegerEltIdx = 0;
@@ -3538,8 +3570,8 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
   }
 
   if (SDValue Splat = cast<BuildVectorSDNode>(Op)->getSplatValue()) {
-    unsigned Opc = VT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL
-                                        : RISCVISD::VMV_V_X_VL;
+    unsigned Opc =
+        VT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL : RISCVISD::VMV_V_X_VL;
     if (!VT.isFloatingPoint())
       Splat = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Splat);
     Splat =
@@ -3621,7 +3653,8 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
     // means we only have a VTYPE toggle, not a VL toggle.  TODO: Should this
     // be moved into InsertVSETVLI?
     unsigned ViaVecLen =
-      (Subtarget.getRealMinVLen() >= VT.getSizeInBits() * NumElts) ? NumElts : 1;
+        (Subtarget.getRealMinVLen() >= VT.getSizeInBits() * NumElts) ? NumElts
+                                                                     : 1;
     MVT ViaVecVT = MVT::getVectorVT(ViaIntVT, ViaVecLen);
 
     uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
@@ -3644,13 +3677,12 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
                               DAG.getConstant(SplatValue, DL, XLenVT),
                               DAG.getConstant(0, DL, XLenVT));
     if (ViaVecLen != 1)
-      Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL,
-                        MVT::getVectorVT(ViaIntVT, 1), Vec,
-                        DAG.getConstant(0, DL, XLenVT));
+      Vec =
+          DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::getVectorVT(ViaIntVT, 1),
+                      Vec, DAG.getConstant(0, DL, XLenVT));
     return DAG.getBitcast(VT, Vec);
   }
 
-
   // Attempt to detect "hidden" splats, which only reveal themselves as splats
   // when re-interpreted as a vector with a larger element type. For example,
   //   v4i16 = build_vector i16 0, i16 1, i16 0, i16 1
@@ -3675,8 +3707,9 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
     // be moved into InsertVSETVLI?
     const unsigned RequiredVL = NumElts / SeqLen;
     const unsigned ViaVecLen =
-      (Subtarget.getRealMinVLen() >= ViaIntVT.getSizeInBits() * NumElts) ?
-      NumElts : RequiredVL;
+        (Subtarget.getRealMinVLen() >= ViaIntVT.getSizeInBits() * NumElts)
+            ? NumElts
+            : RequiredVL;
     MVT ViaVecVT = MVT::getVectorVT(ViaIntVT, ViaVecLen);
 
     unsigned EltIdx = 0;
@@ -3732,9 +3765,10 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
     if (EltBitSize - SignBits < 8) {
       SDValue Source = DAG.getBuildVector(VT.changeVectorElementType(MVT::i8),
                                           DL, Op->ops());
-      Source = convertToScalableVector(ContainerVT.changeVectorElementType(MVT::i8),
-                                       Source, DAG, Subtarget);
-      SDValue Res = DAG.getNode(RISCVISD::VSEXT_VL, DL, ContainerVT, Source, Mask, VL);
+      Source = convertToScalableVector(
+          ContainerVT.changeVectorElementType(MVT::i8), Source, DAG, Subtarget);
+      SDValue Res =
+          DAG.getNode(RISCVISD::VSEXT_VL, DL, ContainerVT, Source, Mask, VL);
       return convertFromScalableVector(VT, Res, DAG, Subtarget);
     }
   }
@@ -3791,8 +3825,8 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
   if (SDValue Splat = cast<BuildVectorSDNode>(Op)->getSplatValue()) {
     if (auto Gather = matchSplatAsGather(Splat, VT, DL, DAG, Subtarget))
       return Gather;
-    unsigned Opc = VT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL
-                                        : RISCVISD::VMV_V_X_VL;
+    unsigned Opc =
+        VT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL : RISCVISD::VMV_V_X_VL;
     if (!VT.isFloatingPoint())
       Splat = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Splat);
     Splat =
@@ -3846,7 +3880,8 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
   // TODO: unify with TTI getSlideCost.
   InstructionCost PerSlideCost = 1;
   switch (RISCVTargetLowering::getLMUL(ContainerVT)) {
-  default: break;
+  default:
+    break;
   case RISCVII::VLMUL::LMUL_2:
     PerSlideCost = 2;
     break;
@@ -3904,22 +3939,26 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
     }
 
     if (UndefCount) {
-      const SDValue Offset = DAG.getConstant(UndefCount, DL, Subtarget.getXLenVT());
-      Vec = getVSlidedown(DAG, Subtarget, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
-                          Vec, Offset, Mask, VL, Policy);
+      const SDValue Offset =
+          DAG.getConstant(UndefCount, DL, Subtarget.getXLenVT());
+      Vec = getVSlidedown(DAG, Subtarget, DL, ContainerVT,
+                          DAG.getUNDEF(ContainerVT), Vec, Offset, Mask, VL,
+                          Policy);
       UndefCount = 0;
     }
-    auto OpCode =
-      VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
+    auto OpCode = VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL
+                                       : RISCVISD::VSLIDE1DOWN_VL;
     if (!VT.isFloatingPoint())
       V = DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getXLenVT(), V);
     Vec = DAG.getNode(OpCode, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Vec,
                       V, Mask, VL);
   }
   if (UndefCount) {
-    const SDValue Offset = DAG.getConstant(UndefCount, DL, Subtarget.getXLenVT());
-    Vec = getVSlidedown(DAG, Subtarget, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
-                        Vec, Offset, Mask, VL, Policy);
+    const SDValue Offset =
+        DAG.getConstant(UndefCount, DL, Subtarget.getXLenVT());
+    Vec =
+        getVSlidedown(DAG, Subtarget, DL, ContainerVT,
+                      DAG.getUNDEF(ContainerVT), Vec, Offset, Mask, VL, Policy);
   }
   return convertFromScalableVector(VT, Vec, DAG, Subtarget);
 }
@@ -4057,27 +4096,26 @@ static SDValue lowerScalarInsert(SDValue Scalar, SDValue VL, MVT VT,
                        DAG.getConstant(0, DL, XLenVT));
   }
 
-
   if (VT.isFloatingPoint())
-    return DAG.getNode(RISCVISD::VFMV_S_F_VL, DL, VT,
-                       DAG.getUNDEF(VT), Scalar, VL);
+    return DAG.getNode(RISCVISD::VFMV_S_F_VL, DL, VT, DAG.getUNDEF(VT), Scalar,
+                       VL);
 
   // Avoid the tricky legalization cases by falling back to using the
   // splat code which already handles it gracefully.
   if (!Scalar.getValueType().bitsLE(XLenVT))
     return lowerScalarSplat(DAG.getUNDEF(VT), Scalar,
-                            DAG.getConstant(1, DL, XLenVT),
-                            VT, DL, DAG, Subtarget);
+                            DAG.getConstant(1, DL, XLenVT), VT, DL, DAG,
+                            Subtarget);
 
   // If the operand is a constant, sign extend to increase our chances
   // of being able to use a .vi instruction. ANY_EXTEND would become a
   // a zero extend and the simm5 check in isel would fail.
   // FIXME: Should we ignore the upper bits in isel instead?
   unsigned ExtOpc =
-    isa<ConstantSDNode>(Scalar) ? ISD::SIGN_EXTEND : ISD::ANY_EXTEND;
+      isa<ConstantSDNode>(Scalar) ? ISD::SIGN_EXTEND : ISD::ANY_EXTEND;
   Scalar = DAG.getNode(ExtOpc, DL, XLenVT, Scalar);
-  return DAG.getNode(RISCVISD::VMV_S_X_VL, DL, VT,
-                     DAG.getUNDEF(VT), Scalar, VL);
+  return DAG.getNode(RISCVISD::VMV_S_X_VL, DL, VT, DAG.getUNDEF(VT), Scalar,
+                     VL);
 }
 
 // Is this a shuffle extracts either the even or odd elements of a vector?
@@ -4398,7 +4436,8 @@ static SDValue lowerVECTOR_SHUFFLEAsVSlideup(const SDLoc &DL, MVT VT,
   auto TrueMask = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget).first;
   // We slide up by the index that the subvector is being inserted at, and set
   // VL to the index + the number of elements being inserted.
-  unsigned Policy = RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED | RISCVII::MASK_AGNOSTIC;
+  unsigned Policy =
+      RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED | RISCVII::MASK_AGNOSTIC;
   // If the we're adding a suffix to the in place vector, i.e. inserting right
   // up to the very end of it, then we don't actually care about the tail.
   if (NumSubElts + Index >= (int)NumElts)
@@ -4422,9 +4461,8 @@ static SDValue lowerVECTOR_SHUFFLEAsVSlideup(const SDLoc &DL, MVT VT,
 
 /// Match v(f)slide1up/down idioms.  These operations involve sliding
 /// N-1 elements to make room for an inserted scalar at one end.
-static SDValue lowerVECTOR_SHUFFLEAsVSlide1(const SDLoc &DL, MVT VT,
-                                            SDValue V1, SDValue V2,
-                                            ArrayRef<int> Mask,
+static SDValue lowerVECTOR_SHUFFLEAsVSlide1(const SDLoc &DL, MVT VT, SDValue V1,
+                                            SDValue V2, ArrayRef<int> Mask,
                                             const RISCVSubtarget &Subtarget,
                                             SelectionDAG &DAG) {
   bool OpsSwapped = false;
@@ -4455,21 +4493,23 @@ static SDValue lowerVECTOR_SHUFFLEAsVSlide1(const SDLoc &DL, MVT VT,
     return SDValue();
 
   const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
-  // Inserted lane must come from splat, undef scalar is legal but not profitable.
+  // Inserted lane must come from splat, undef scalar is legal but not
+  // profitable.
   if (InsertIdx < 0 || InsertIdx / NumElts != (unsigned)OpsSwapped)
     return SDValue();
 
   MVT ContainerVT = getContainerForFixedLengthVector(DAG, VT, Subtarget);
   auto [TrueMask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
-  auto OpCode = IsVSlidedown ?
-    (VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL) :
-    (VT.isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VSLIDE1UP_VL);
+  auto OpCode = IsVSlidedown ? (VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL
+                                                     : RISCVISD::VSLIDE1DOWN_VL)
+                             : (VT.isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL
+                                                     : RISCVISD::VSLIDE1UP_VL);
   if (!VT.isFloatingPoint())
     Splat = DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getXLenVT(), Splat);
-  auto Vec = DAG.getNode(OpCode, DL, ContainerVT,
-                         DAG.getUNDEF(ContainerVT),
-                         convertToScalableVector(ContainerVT, V2, DAG, Subtarget),
-                         Splat, TrueMask, VL);
+  auto Vec =
+      DAG.getNode(OpCode, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
+                  convertToScalableVector(ContainerVT, V2, DAG, Subtarget),
+                  Splat, TrueMask, VL);
   return convertFromScalableVector(VT, Vec, DAG, Subtarget);
 }
 
@@ -4671,7 +4711,8 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
     V1 = DAG.getNode(ISD::ZERO_EXTEND, DL, WidenVT, V1);
     V2 = V2.isUndef() ? DAG.getUNDEF(WidenVT)
                       : DAG.getNode(ISD::ZERO_EXTEND, DL, WidenVT, V2);
-    SDValue Shuffled = DAG.getVectorShuffle(WidenVT, DL, V1, V2, SVN->getMask());
+    SDValue Shuffled =
+        DAG.getVectorShuffle(WidenVT, DL, V1, V2, SVN->getMask());
     return DAG.getSetCC(DL, VT, Shuffled, DAG.getConstant(0, DL, WidenVT),
                         ISD::SETNE);
   }
@@ -5779,8 +5820,7 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
       SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::f16, NewOp0);
       return FPConv;
     }
-    if (VT == MVT::bf16 && Op0VT == MVT::i16 &&
-        Subtarget.hasStdExtZfbfmin()) {
+    if (VT == MVT::bf16 && Op0VT == MVT::i16 && Subtarget.hasStdExtZfbfmin()) {
       SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Op0);
       SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::bf16, NewOp0);
       return FPConv;
@@ -6159,7 +6199,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
 
     MVT ContainerVT = getContainerForFixedLengthVector(VT);
     MVT SrcContainerVT = getContainerForFixedLengthVector(SrcVT);
-    assert(ContainerVT.getVectorElementCount() == SrcContainerVT.getVectorElementCount() &&
+    assert(ContainerVT.getVectorElementCount() ==
+               SrcContainerVT.getVectorElementCount() &&
            "Expected same element count");
 
     auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
@@ -6681,8 +6722,8 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
 }
 
 template <class NodeTy>
-SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
-                                     bool IsLocal, bool IsExternWeak) const {
+SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal,
+                                     bool IsExternWeak) const {
   SDLoc DL(N);
   EVT Ty = getPointerTy(DAG.getDataLayout());
 
@@ -6900,8 +6941,8 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op,
     break;
   case TLSModel::LocalDynamic:
   case TLSModel::GeneralDynamic:
-    Addr =
-        EnableRISCVTLSDESC ? getTLSDescAddr(N, DAG) : getDynamicTLSAddr(N, DAG);
+    Addr = DAG.getTarget().useTLSDESC() ? getTLSDescAddr(N, DAG)
+                                        : getDynamicTLSAddr(N, DAG);
     break;
   }
 
@@ -6950,15 +6991,15 @@ static SDValue combineSelectToBinOp(SDNode *N, SelectionDAG &DAG,
     }
     // (select c, y, -1) -> (c-1) | y
     if (isAllOnesConstant(FalseV)) {
-      SDValue Neg = DAG.getNode(ISD::ADD, DL, VT, CondV,
-                                DAG.getAllOnesConstant(DL, VT));
+      SDValue Neg =
+          DAG.getNode(ISD::ADD, DL, VT, CondV, DAG.getAllOnesConstant(DL, VT));
       return DAG.getNode(ISD::OR, DL, VT, Neg, TrueV);
     }
 
     // (select c, 0, y) -> (c-1) & y
     if (isNullConstant(TrueV)) {
-      SDValue Neg = DAG.getNode(ISD::ADD, DL, VT, CondV,
-                                DAG.getAllOnesConstant(DL, VT));
+      SDValue Neg =
+          DAG.getNode(ISD::ADD, DL, VT, CondV, DAG.getAllOnesConstant(DL, VT));
       return DAG.getNode(ISD::AND, DL, VT, Neg, FalseV);
     }
     // (select c, y, 0) -> -c & y
@@ -7814,8 +7855,8 @@ SDValue RISCVTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
   if (auto *IdxC = dyn_cast<ConstantSDNode>(Idx)) {
     const unsigned OrigIdx = IdxC->getZExtValue();
     // Do we know an upper bound on LMUL?
-    if (auto ShrunkVT = getSmallestVTForIndex(ContainerVT, OrigIdx,
-                                              DL, DAG, Subtarget)) {
+    if (auto ShrunkVT =
+            getSmallestVTForIndex(ContainerVT, OrigIdx, DL, DAG, Subtarget)) {
       ContainerVT = *ShrunkVT;
       AlignedIdx = DAG.getVectorIdxConstant(0, DL);
     }
@@ -7839,8 +7880,8 @@ SDValue RISCVTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
     }
 
     if (AlignedIdx)
-      Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ContainerVT, Vec,
-                        AlignedIdx);
+      Vec =
+          DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ContainerVT, Vec, AlignedIdx);
   }
 
   MVT XLenVT = Subtarget.getXLenVT();
@@ -7895,20 +7936,19 @@ SDValue RISCVTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
     if (isNullConstant(Idx)) {
       // First slide in the lo value, then the hi in above it. We use slide1down
       // to avoid the register group overlap constraint of vslide1up.
-      ValInVec = DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT,
-                             Vec, Vec, ValLo, I32Mask, InsertI64VL);
+      ValInVec = DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT, Vec,
+                             Vec, ValLo, I32Mask, InsertI64VL);
       // If the source vector is undef don't pass along the tail elements from
       // the previous slide1down.
       SDValue Tail = Vec.isUndef() ? Vec : ValInVec;
-      ValInVec = DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT,
-                             Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
+      ValInVec = DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT, Tail,
+                             ValInVec, ValHi, I32Mask, InsertI64VL);
       // Bitcast back to the right container type.
       ValInVec = DAG.getBitcast(ContainerVT, ValInVec);
 
       if (AlignedIdx)
-        ValInVec =
-            DAG.getNode(ISD::INSERT_SUBVECTOR, DL, OrigContainerVT, OrigVec,
-                        ValInVec, AlignedIdx);
+        ValInVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, OrigContainerVT,
+                               OrigVec, ValInVec, AlignedIdx);
       if (!VecVT.isFixedLengthVector())
         return ValInVec;
       return convertFromScalableVector(VecVT, ValInVec, DAG, Subtarget);
@@ -7916,10 +7956,10 @@ SDValue RISCVTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
 
     // First slide in the lo value, then the hi in above it. We use slide1down
     // to avoid the register group overlap constraint of vslide1up.
-    ValInVec = DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT,
-                           DAG.getUNDEF(I32ContainerVT),
-                           DAG.getUNDEF(I32ContainerVT), ValLo,
-                           I32Mask, InsertI64VL);
+    ValInVec =
+        DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT,
+                    DAG.getUNDEF(I32ContainerVT), DAG.getUNDEF(I32ContainerVT),
+                    ValLo, I32Mask, InsertI64VL);
     ValInVec = DAG.getNode(RISCVISD::VSLIDE1DOWN_VL, DL, I32ContainerVT,
                            DAG.getUNDEF(I32ContainerVT), ValInVec, ValHi,
                            I32Mask, InsertI64VL);
@@ -8045,7 +8085,7 @@ SDValue RISCVTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
     unsigned RemIdx = OrigIdx % ElemsPerVReg;
     unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
     unsigned ExtractIdx =
-      SubRegIdx * M1VT.getVectorElementCount().getKnownMinValue();
+        SubRegIdx * M1VT.getVectorElementCount().getKnownMinValue();
     Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, M1VT, Vec,
                       DAG.getVectorIdxConstant(ExtractIdx, DL));
     Idx = DAG.getVectorIdxConstant(RemIdx, DL);
@@ -8203,8 +8243,8 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG,
         SDValue LMUL = DAG.getConstant(Lmul, DL, XLenVT);
         unsigned Sew = RISCVVType::encodeSEW(I32VT.getScalarSizeInBits());
         SDValue SEW = DAG.getConstant(Sew, DL, XLenVT);
-        SDValue SETVLMAX = DAG.getTargetConstant(
-            Intrinsic::riscv_vsetvlimax, DL, MVT::i32);
+        SDValue SETVLMAX =
+            DAG.getTargetConstant(Intrinsic::riscv_vsetvlimax, DL, MVT::i32);
         I32VL = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, XLenVT, SETVLMAX, SEW,
                             LMUL);
       } else {
@@ -8352,8 +8392,8 @@ static void getVCIXOperands(SDValue &Op, SelectionDAG &DAG,
 // LMUL * VLEN should be greater than or equal to EGS * SEW
 static inline bool isValidEGW(int EGS, EVT VT,
                               const RISCVSubtarget &Subtarget) {
-  return (Subtarget.getRealMinVLen() *
-             VT.getSizeInBits().getKnownMinValue()) / RISCV::RVVBitsPerBlock >=
+  return (Subtarget.getRealMinVLen() * VT.getSizeInBits().getKnownMinValue()) /
+             RISCV::RVVBitsPerBlock >=
          EGS * VT.getScalarSizeInBits();
 }
 
@@ -8380,14 +8420,30 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
   case Intrinsic::riscv_sm3p1: {
     unsigned Opc;
     switch (IntNo) {
-    case Intrinsic::riscv_orc_b:      Opc = RISCVISD::ORC_B;      break;
-    case Intrinsic::riscv_brev8:      Opc = RISCVISD::BREV8;      break;
-    case Intrinsic::riscv_sha256sig0: Opc = RISCVISD::SHA256SIG0; break;
-    case Intrinsic::riscv_sha256sig1: Opc = RISCVISD::SHA256SIG1; break;
-    case Intrinsic::riscv_sha256sum0: Opc = RISCVISD::SHA256SUM0; break;
-    case Intrinsic::riscv_sha256sum1: Opc = RISCVISD::SHA256SUM1; break;
-    case Intrinsic::riscv_sm3p0:      Opc = RISCVISD::SM3P0;      break;
-    case Intrinsic::riscv_sm3p1:      Opc = RISCVISD::SM3P1;      break;
+    case Intrinsic::riscv_orc_b:
+      Opc = RISCVISD::ORC_B;
+      break;
+    case Intrinsic::riscv_brev8:
+      Opc = RISCVISD::BREV8;
+      break;
+    case Intrinsic::riscv_sha256sig0:
+      Opc = RISCVISD::SHA256SIG0;
+      break;
+    case Intrinsic::riscv_sha256sig1:
+      Opc = RISCVISD::SHA256SIG1;
+      break;
+    case Intrinsic::riscv_sha256sum0:
+      Opc = RISCVISD::SHA256SUM0;
+      break;
+    case Intrinsic::riscv_sha256sum1:
+      Opc = RISCVISD::SHA256SUM1;
+      break;
+    case Intrinsic::riscv_sm3p0:
+      Opc = RISCVISD::SM3P0;
+      break;
+    case Intrinsic::riscv_sm3p1:
+      Opc = RISCVISD::SM3P1;
+      break;
     }
 
     if (RV64LegalI32 && Subtarget.is64Bit() && Op.getValueType() == MVT::i32) {
@@ -8501,7 +8557,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
     SDValue Vec = Op.getOperand(1);
     SDValue VL = getVLOperand(Op);
 
-    SDValue SplattedVal = splatSplitI64WithVL(DL, VT, SDValue(), Scalar, VL, DAG);
+    SDValue SplattedVal =
+        splatSplitI64WithVL(DL, VT, SDValue(), Scalar, VL, DAG);
     if (Op.getOperand(1).isUndef())
       return SplattedVal;
     SDValue SplattedIdx =
@@ -8628,7 +8685,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
       MVT MaskVT = getMaskTypeFor(ContainerVT);
       if (VT.isFixedLengthVector()) {
         Mask = convertToScalableVector(MaskVT, Mask, DAG, Subtarget);
-        PassThru = convertToScalableVector(ContainerVT, PassThru, DAG, Subtarget);
+        PassThru =
+            convertToScalableVector(ContainerVT, PassThru, DAG, Subtarget);
       }
     }
 
@@ -8698,8 +8756,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
     MVT VT = Op->getSimpleValueType(0);
     MVT ContainerVT = getContainerForFixedLengthVector(VT);
 
-    SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
-                         Subtarget);
+    SDValue VL =
+        getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
     SDValue IntID = DAG.getTargetConstant(VlsegInts[NF - 2], DL, XLenVT);
     auto *Load = cast<MemIntrinsicSDNode>(Op);
     SmallVector<EVT, 9> ContainerVTs(NF, ContainerVT);
@@ -8834,8 +8892,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
     MVT VT = Op->getOperand(2).getSimpleValueType();
     MVT ContainerVT = getContainerForFixedLengthVector(VT);
 
-    SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
-                         Subtarget);
+    SDValue VL =
+        getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
     SDValue IntID = DAG.getTargetConstant(VssegInts[NF - 2], DL, XLenVT);
     SDValue Ptr = Op->getOperand(NF + 2);
 
@@ -8959,7 +9017,6 @@ static unsigned getRVVReductionOp(unsigned ISDOpcode) {
   case ISD::VP_REDUCE_FMIN:
     return RISCVISD::VECREDUCE_FMIN_VL;
   }
-
 }
 
 SDValue RISCVTargetLowering::lowerVectorMaskVecReduction(SDValue Op,
@@ -9069,12 +9126,12 @@ static SDValue lowerReductionSeq(unsigned RVVOpcode, MVT ResVT,
   // prove it is non-zero.  For the AVL=0 case, we need the scalar to
   // be the result of the reduction operation.
   auto InnerVL = NonZeroAVL ? VL : DAG.getConstant(1, DL, XLenVT);
-  SDValue InitialValue = lowerScalarInsert(StartValue, InnerVL, InnerVT, DL,
-                                           DAG, Subtarget);
+  SDValue InitialValue =
+      lowerScalarInsert(StartValue, InnerVL, InnerVT, DL, DAG, Subtarget);
   if (M1VT != InnerVT)
-    InitialValue = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, M1VT,
-                               DAG.getUNDEF(M1VT),
-                               InitialValue, DAG.getConstant(0, DL, XLenVT));
+    InitialValue =
+        DAG.getNode(ISD::INSERT_SUBVECTOR, DL, M1VT, DAG.getUNDEF(M1VT),
+                    InitialValue, DAG.getConstant(0, DL, XLenVT));
   SDValue PassThru = NonZeroAVL ? DAG.getUNDEF(M1VT) : InitialValue;
   SDValue Policy = DAG.getTargetConstant(RISCVII::TAIL_AGNOSTIC, DL, XLenVT);
   SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
@@ -9621,10 +9678,10 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
       DAG.getNode(ISD::ADD, DL, IdxVT, EvenIdx, DAG.getConstant(1, DL, IdxVT));
 
   // Gather the even and odd elements into two separate vectors
-  SDValue EvenWide = DAG.getNode(RISCVISD::VRGATHER_VV_VL, DL, ConcatVT,
-                                 Concat, EvenIdx, Passthru, Mask, VL);
-  SDValue OddWide = DAG.getNode(RISCVISD::VRGATHER_VV_VL, DL, ConcatVT,
-                                Concat, OddIdx, Passthru, Mask, VL);
+  SDValue EvenWide = DAG.getNode(RISCVISD::VRGATHER_VV_VL, DL, ConcatVT, Concat,
+                                 EvenIdx, Passthru, Mask, VL);
+  SDValue OddWide = DAG.getNode(RISCVISD::VRGATHER_VV_VL, DL, ConcatVT, Concat,
+                                OddIdx, Passthru, Mask, VL);
 
   // Extract the result half of the gather for even and odd
   SDValue Even = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VecVT, EvenWide,
@@ -9651,7 +9708,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_INTERLEAVE(SDValue Op,
   SDValue VL = DAG.getRegister(RISCV::X0, XLenVT);
 
   // If the VT is LMUL=8, we need to split and reassemble.
-  if (VecVT.getSizeInBits().getKnownMinValue() == (8 * RISCV::RVVBitsPerBlock)) {
+  if (VecVT.getSizeInBits().getKnownMinValue() ==
+      (8 * RISCV::RVVBitsPerBlock)) {
     auto [Op0Lo, Op0Hi] = DAG.SplitVectorOperand(Op.getNode(), 0);
     auto [Op1Lo, Op1Hi] = DAG.SplitVectorOperand(Op.getNode(), 1);
     EVT SplitVT = Op0Lo.getValueType();
@@ -9661,10 +9719,10 @@ SDValue RISCVTargetLowering::lowerVECTOR_INTERLEAVE(SDValue Op,
     SDValue ResHi = DAG.getNode(ISD::VECTOR_INTERLEAVE, DL,
                                 DAG.getVTList(SplitVT, SplitVT), Op0Hi, Op1Hi);
 
-    SDValue Lo = DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT,
-                             ResLo.getValue(0), ResLo.getValue(1));
-    SDValue Hi = DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT,
-                             ResHi.getValue(0), ResHi.getValue(1));
+    SDValue Lo = DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, ResLo.getValue(0),
+                             ResLo.getValue(1));
+    SDValue Hi = DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, ResHi.getValue(0),
+                             ResHi.getValue(1));
     return DAG.getMergeValues({Lo, Hi}, DL);
   }
 
@@ -9677,9 +9735,9 @@ SDValue RISCVTargetLowering::lowerVECTOR_INTERLEAVE(SDValue Op,
                                         DAG, Subtarget);
   } else {
     // Otherwise, fallback to using vrgathere16.vv
-    MVT ConcatVT =
-      MVT::getVectorVT(VecVT.getVectorElementType(),
-                       VecVT.getVectorElementCount().multiplyCoefficientBy(2));
+    MVT ConcatVT = MVT::getVectorVT(
+        VecVT.getVectorElementType(),
+        VecVT.getVectorElementCount().multiplyCoefficientBy(2));
     SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT,
                                  Op.getOperand(0), Op.getOperand(1));
 
@@ -9689,7 +9747,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_INTERLEAVE(SDValue Op,
     SDValue StepVec = DAG.getStepVector(DL, IdxVT);
 
     // 1 1 1 1 1 1 1 1 ...
-    SDValue Ones = DAG.getSplatVector(IdxVT, DL, DAG.getConstant(1, DL, XLenVT));
+    SDValue Ones =
+        DAG.getSplatVector(IdxVT, DL, DAG.getConstant(1, DL, XLenVT));
 
     // 1 0 1 0 1 0 1 0 ...
     SDValue OddMask = DAG.getNode(ISD::AND, DL, IdxVT, StepVec, Ones);
@@ -9710,8 +9769,9 @@ SDValue RISCVTargetLowering::lowerVECTOR_INTERLEAVE(SDValue Op,
     // Then perform the interleave
     //   v[0]   v[n]   v[1] v[n+1]   v[2] v[n+2]   v[3] v[n+3] ...
     SDValue TrueMask = getAllOnesMask(IdxVT, VL, DL, DAG);
-    Interleaved = DAG.getNode(RISCVISD::VRGATHEREI16_VV_VL, DL, ConcatVT,
-                              Concat, Idx, DAG.getUNDEF(ConcatVT), TrueMask, VL);
+    Interleaved =
+        DAG.getNode(RISCVISD::VRGATHEREI16_VV_VL, DL, ConcatVT, Concat, Idx,
+                    DAG.getUNDEF(ConcatVT), TrueMask, VL);
   }
 
   // Extract the two halves from the interleaved result
@@ -9770,7 +9830,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_REVERSE(SDValue Op,
   unsigned MinSize = VecVT.getSizeInBits().getKnownMinValue();
   unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
   unsigned MaxVLMAX =
-    RISCVTargetLowering::computeVLMAX(VectorBitsMax, EltSize, MinSize);
+      RISCVTargetLowering::computeVLMAX(VectorBitsMax, EltSize, MinSize);
 
   unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
   MVT IntVT = VecVT.changeVectorElementTypeToInteger();
@@ -9808,9 +9868,9 @@ SDValue RISCVTargetLowering::lowerVECTOR_REVERSE(SDValue Op,
   auto [Mask, VL] = getDefaultScalableVLOps(VecVT, DL, DAG, Subtarget);
 
   // Calculate VLMAX-1 for the desired SEW.
-  SDValue VLMinus1 = DAG.getNode(ISD::SUB, DL, XLenVT,
-                                 computeVLMax(VecVT, DL, DAG),
-                                 DAG.getConstant(1, DL, XLenVT));
+  SDValue VLMinus1 =
+      DAG.getNode(ISD::SUB, DL, XLenVT, computeVLMax(VecVT, DL, DAG),
+                  DAG.getConstant(1, DL, XLenVT));
 
   // Splat VLMAX-1 taking care to handle SEW==64 on RV32.
   bool IsRV32E64 =
@@ -9885,14 +9945,14 @@ RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
       RISCVTargetLowering::computeVLMAXBounds(ContainerVT, Subtarget);
   if (MinVLMAX == MaxVLMAX && MinVLMAX == VT.getVectorNumElements() &&
       getLMUL1VT(ContainerVT).bitsLE(ContainerVT)) {
-    SDValue NewLoad =
-        DAG.getLoad(ContainerVT, DL, Load->getChain(), Load->getBasePtr(),
-                    Load->getMemOperand());
+    SDValue NewLoad = DAG.getLoad(ContainerVT, DL, Load->getChain(),
+                                  Load->getBasePtr(), Load->getMemOperand());
     SDValue Result = convertFromScalableVector(VT, NewLoad, DAG, Subtarget);
     return DAG.getMergeValues({Result, NewLoad.getValue(1)}, DL);
   }
 
-  SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
+  SDValue VL =
+      getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
 
   bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
   SDValue IntID = DAG.getTargetConstant(
@@ -9929,9 +9989,9 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
   // If the size less than a byte, we need to pad with zeros to make a byte.
   if (VT.getVectorElementType() == MVT::i1 && VT.getVectorNumElements() < 8) {
     VT = MVT::v8i1;
-    StoreVal = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
-                           DAG.getConstant(0, DL, VT), StoreVal,
-                           DAG.getIntPtrConstant(0, DL));
+    StoreVal =
+        DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getConstant(0, DL, VT),
+                    StoreVal, DAG.getIntPtrConstant(0, DL));
   }
 
   MVT ContainerVT = getContainerForFixedLengthVector(VT);
@@ -9939,7 +9999,6 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
   SDValue NewValue =
       convertToScalableVector(ContainerVT, StoreVal, DAG, Subtarget);
 
-
   // If we know the exact VLEN and our fixed length vector completely fills
   // the container, use a whole register store instead.
   const auto [MinVLMAX, MaxVLMAX] =
@@ -9949,8 +10008,8 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
     return DAG.getStore(Store->getChain(), DL, NewValue, Store->getBasePtr(),
                         Store->getMemOperand());
 
-  SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
-                       Subtarget);
+  SDValue VL =
+      getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
 
   bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
   SDValue IntID = DAG.getTargetConstant(
@@ -11512,8 +11571,8 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
     // based on the opcode.
     unsigned ExtOpc = ISD::ANY_EXTEND;
     if (VT != MVT::i32)
-      ExtOpc = N->getOpcode() == ISD::SDIV ? ISD::SIGN_EXTEND
-                                           : ISD::ZERO_EXTEND;
+      ExtOpc =
+          N->getOpcode() == ISD::SDIV ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
 
     Results.push_back(customLegalizeToWOp(N, DAG, ExtOpc));
     break;
@@ -11620,8 +11679,8 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
       // Emit a special ABSW node that will be expanded to NEGW+MAX at isel.
       // This allows us to remember that the result is sign extended. Expanding
       // to NEGW+MAX here requires a Freeze which breaks ComputeNumSignBits.
-      SDValue Src = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64,
-                                N->getOperand(0));
+      SDValue Src =
+          DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(0));
       SDValue Abs = DAG.getNode(RISCVISD::ABSW, DL, MVT::i64, Src);
       Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Abs));
       return;
@@ -11784,14 +11843,30 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
         return;
       unsigned Opc;
       switch (IntNo) {
-      case Intrinsic::riscv_orc_b:      Opc = RISCVISD::ORC_B;      break;
-      case Intrinsic::riscv_brev8:      Opc = RISCVISD::BREV8;      break;
-      case Intrinsic::riscv_sha256sig0: Opc = RISCVISD::SHA256SIG0; break;
-      case Intrinsic::riscv_sha256sig1: Opc = RISCVISD::SHA256SIG1; break;
-      case Intrinsic::riscv_sha256sum0: Opc = RISCVISD::SHA256SUM0; break;
-      case Intrinsic::riscv_sha256sum1: Opc = RISCVISD::SHA256SUM1; break;
-      case Intrinsic::riscv_sm3p0:      Opc = RISCVISD::SM3P0;      break;
-      case Intrinsic::riscv_sm3p1:      Opc = RISCVISD::SM3P1;      break;
+      case Intrinsic::riscv_orc_b:
+        Opc = RISCVISD::ORC_B;
+        break;
+      case Intrinsic::riscv_brev8:
+        Opc = RISCVISD::BREV8;
+        break;
+      case Intrinsic::riscv_sha256sig0:
+        Opc = RISCVISD::SHA256SIG0;
+        break;
+      case Intrinsic::riscv_sha256sig1:
+        Opc = RISCVISD::SHA256SIG1;
+        break;
+      case Intrinsic::riscv_sha256sum0:
+        Opc = RISCVISD::SHA256SUM0;
+        break;
+      case Intrinsic::riscv_sha256sum1:
+        Opc = RISCVISD::SHA256SUM1;
+        break;
+      case Intrinsic::riscv_sm3p0:
+        Opc = RISCVISD::SM3P0;
+        break;
+      case Intrinsic::riscv_sm3p1:
+        Opc = RISCVISD::SM3P1;
+        break;
       }
 
       SDValue NewOp =
@@ -12020,7 +12095,7 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
   if (LHS.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
       LHS.getOperand(0) == SrcVec && isa<ConstantSDNode>(LHS.getOperand(1))) {
     uint64_t LHSIdx =
-      cast<ConstantSDNode>(LHS.getOperand(1))->getLimitedValue();
+        cast<ConstantSDNode>(LHS.getOperand(1))->getLimitedValue();
     if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
       EVT ReduceVT = EVT::getVectorVT(*DAG.getContext(), VT, 2);
       SDValue Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ReduceVT, SrcVec,
@@ -12055,7 +12130,6 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
   return SDValue();
 }
 
-
 // Try to fold (<bop> x, (reduction.<bop> vec, start))
 static SDValue combineBinOpToReduce(SDNode *N, SelectionDAG &DAG,
                                     const RISCVSubtarget &Subtarget) {
@@ -12115,8 +12189,7 @@ static SDValue combineBinOpToReduce(SDNode *N, SelectionDAG &DAG,
   SDValue ScalarV = Reduce.getOperand(2);
   EVT ScalarVT = ScalarV.getValueType();
   if (ScalarV.getOpcode() == ISD::INSERT_SUBVECTOR &&
-      ScalarV.getOperand(0)->isUndef() &&
-      isNullConstant(ScalarV.getOperand(2)))
+      ScalarV.getOperand(0)->isUndef() && isNullConstant(ScalarV.getOperand(2)))
     ScalarV = ScalarV.getOperand(1);
 
   // Make sure that ScalarV is a splat with VL=1.
@@ -12529,9 +12602,10 @@ static SDValue performTRUNCATECombine(SDNode *N, SelectionDAG &DAG,
   // shift amounts larger than 31 would produce poison. If we wait until
   // type legalization, we'll create RISCVISD::SRLW and we can't recover it
   // to use a BEXT instruction.
-  if (!RV64LegalI32 && Subtarget.is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
-      N0.getValueType() == MVT::i32 && N0.getOpcode() == ISD::SRL &&
-      !isa<ConstantSDNode>(N0.getOperand(1)) && N0.hasOneUse()) {
+  if (!RV64LegalI32 && Subtarget.is64Bit() && Subtarget.hasStdExtZbs() &&
+      VT == MVT::i1 && N0.getValueType() == MVT::i32 &&
+      N0.getOpcode() == ISD::SRL && !isa<ConstantSDNode>(N0.getOperand(1)) &&
+      N0.hasOneUse()) {
     SDLoc DL(N0);
     SDValue Op0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N0.getOperand(0));
     SDValue Op1 = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N0.getOperand(1));
@@ -12590,8 +12664,8 @@ static SDValue combineOrOfCZERO(SDNode *N, SDValue N0, SDValue N1,
   assert(N->getOpcode() == ISD::OR && "Unexpected opcode");
 
   if (N0.getOpcode() != RISCVISD::CZERO_EQZ ||
-      N1.getOpcode() != RISCVISD::CZERO_NEZ ||
-      !N0.hasOneUse() || !N1.hasOneUse())
+      N1.getOpcode() != RISCVISD::CZERO_NEZ || !N0.hasOneUse() ||
+      !N1.hasOneUse())
     return SDValue();
 
   // Should have the same condition.
@@ -12604,17 +12678,17 @@ static SDValue combineOrOfCZERO(SDNode *N, SDValue N0, SDValue N1,
 
   if (TrueV.getOpcode() != ISD::XOR || FalseV.getOpcode() != ISD::XOR ||
       TrueV.getOperand(1) != FalseV.getOperand(1) ||
-      !isOneConstant(TrueV.getOperand(1)) ||
-      !TrueV.hasOneUse() || !FalseV.hasOneUse())
+      !isOneConstant(TrueV.getOperand(1)) || !TrueV.hasOneUse() ||
+      !FalseV.hasOneUse())
     return SDValue();
 
   EVT VT = N->getValueType(0);
   SDLoc DL(N);
 
-  SDValue NewN0 = DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV.getOperand(0),
-                              Cond);
-  SDValue NewN1 = DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV.getOperand(0),
-                              Cond);
+  SDValue NewN0 =
+      DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV.getOperand(0), Cond);
+  SDValue NewN1 =
+      DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV.getOperand(0), Cond);
   SDValue NewOr = DAG.getNode(ISD::OR, DL, VT, NewN0, NewN1);
   return DAG.getNode(ISD::XOR, DL, VT, NewOr, TrueV.getOperand(1));
 }
@@ -12669,8 +12743,8 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
   // fold (xor (sllw 1, x), -1) -> (rolw ~1, x)
   // NOTE: Assumes ROL being legal means ROLW is legal.
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-  if (N0.getOpcode() == RISCVISD::SLLW &&
-      isAllOnesConstant(N1) && isOneConstant(N0.getOperand(0)) &&
+  if (N0.getOpcode() == RISCVISD::SLLW && isAllOnesConstant(N1) &&
+      isOneConstant(N0.getOperand(0)) &&
       TLI.isOperationLegal(ISD::ROTL, MVT::i64)) {
     SDLoc DL(N);
     return DAG.getNode(RISCVISD::ROLW, DL, MVT::i64,
@@ -12744,7 +12818,8 @@ static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG) {
 
 /// According to the property that indexed load/store instructions zero-extend
 /// their indices, try to narrow the type of index operand.
-static bool narrowIndex(SDValue &N, ISD::MemIndexType IndexType, SelectionDAG &DAG) {
+static bool narrowIndex(SDValue &N, ISD::MemIndexType IndexType,
+                        SelectionDAG &DAG) {
   if (isIndexTypeSigned(IndexType))
     return false;
 
@@ -12767,8 +12842,8 @@ static bool narrowIndex(SDValue &N, ISD::MemIndexType IndexType, SelectionDAG &D
     LLVMContext &C = *DAG.getContext();
     EVT ResultVT = EVT::getIntegerVT(C, ActiveBits).getRoundIntegerType(C);
     if (ResultVT.bitsLT(VT.getVectorElementType())) {
-      N = DAG.getNode(ISD::TRUNCATE, DL,
-                      VT.changeVectorElementType(ResultVT), N);
+      N = DAG.getNode(ISD::TRUNCATE, DL, VT.changeVectorElementType(ResultVT),
+                      N);
       return true;
     }
   }
@@ -12780,14 +12855,17 @@ static bool narrowIndex(SDValue &N, ISD::MemIndexType IndexType, SelectionDAG &D
   SDValue N0 = N.getOperand(0);
   if (N0.getOpcode() != ISD::ZERO_EXTEND &&
       N0.getOpcode() != RISCVISD::VZEXT_VL)
-    return false;;
+    return false;
+  ;
   if (!N0->hasOneUse())
-    return false;;
+    return false;
+  ;
 
   APInt ShAmt;
   SDValue N1 = N.getOperand(1);
   if (!ISD::isConstantSplatVector(N1.getNode(), ShAmt))
-    return false;;
+    return false;
+  ;
 
   SDValue Src = N0.getOperand(0);
   EVT SrcVT = Src.getValueType();
@@ -12855,8 +12933,8 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG,
 
   SDValue SExtOp = DAG.getNode(ISD::SIGN_EXTEND_INREG, N, OpVT,
                                N0.getOperand(0), DAG.getValueType(MVT::i32));
-  return DAG.getSetCC(dl, VT, SExtOp, DAG.getConstant(C1.trunc(32).sext(64),
-                                                      dl, OpVT), Cond);
+  return DAG.getSetCC(dl, VT, SExtOp,
+                      DAG.getConstant(C1.trunc(32).sext(64), dl, OpVT), Cond);
 }
 
 static SDValue
@@ -13727,8 +13805,8 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
 //   (fp_to_int_sat (fround X))     -> (select X == nan, 0, (fcvt X, rmm))
 //   (fp_to_int_sat (frint X))      -> (select X == nan, 0, (fcvt X, dyn))
 static SDValue performFP_TO_INT_SATCombine(SDNode *N,
-                                       TargetLowering::DAGCombinerInfo &DCI,
-                                       const RISCVSubtarget &Subtarget) {
+                                           TargetLowering::DAGCombinerInfo &DCI,
+                                           const RISCVSubtarget &Subtarget) {
   SelectionDAG &DAG = DCI.DAG;
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
   MVT XLenVT = Subtarget.getXLenVT();
@@ -13773,8 +13851,8 @@ static SDValue performFP_TO_INT_SATCombine(SDNode *N,
   Src = Src.getOperand(0);
 
   SDLoc DL(N);
-  SDValue FpToInt = DAG.getNode(Opc, DL, XLenVT, Src,
-                                DAG.getTargetConstant(FRM, DL, XLenVT));
+  SDValue FpToInt =
+      DAG.getNode(Opc, DL, XLenVT, Src, DAG.getTargetConstant(FRM, DL, XLenVT));
 
   // fcvt.wu.* sign extends bit 31 on RV64. FP_TO_UINT_SAT expects to zero
   // extend.
@@ -14065,17 +14143,17 @@ static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
   // Combine (sra (sext_inreg (shl X, C1), i32), C2) ->
   // (sra (shl X, C1+32), C2+32) so it gets selected as SLLI+SRAI instead of
   // SLLIW+SRAIW. SLLI+SRAI have compressed forms.
-  if (ShAmt < 32 &&
-      N0.getOpcode() == ISD::SIGN_EXTEND_INREG && N0.hasOneUse() &&
-      cast<VTSDNode>(N0.getOperand(1))->getVT() == MVT::i32 &&
-      N0.getOperand(0).getOpcode() == ISD::SHL && N0.getOperand(0).hasOneUse() &&
+  if (ShAmt < 32 && N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
+      N0.hasOneUse() && cast<VTSDNode>(N0.getOperand(1))->getVT() == MVT::i32 &&
+      N0.getOperand(0).getOpcode() == ISD::SHL &&
+      N0.getOperand(0).hasOneUse() &&
       isa<ConstantSDNode>(N0.getOperand(0).getOperand(1))) {
     uint64_t LShAmt = N0.getOperand(0).getConstantOperandVal(1);
     if (LShAmt < 32) {
       SDLoc ShlDL(N0.getOperand(0));
-      SDValue Shl = DAG.getNode(ISD::SHL, ShlDL, MVT::i64,
-                                N0.getOperand(0).getOperand(0),
-                                DAG.getConstant(LShAmt + 32, ShlDL, MVT::i64));
+      SDValue Shl =
+          DAG.getNode(ISD::SHL, ShlDL, MVT::i64, N0.getOperand(0).getOperand(0),
+                      DAG.getConstant(LShAmt + 32, ShlDL, MVT::i64));
       SDLoc DL(N);
       return DAG.getNode(ISD::SRA, DL, MVT::i64, Shl,
                          DAG.getConstant(ShAmt + 32, DL, MVT::i64));
@@ -14150,9 +14228,8 @@ static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
   if (ShAmt == 32)
     return SExt;
 
-  return DAG.getNode(
-      ISD::SHL, DL, MVT::i64, SExt,
-      DAG.getConstant(32 - ShAmt, DL, MVT::i64));
+  return DAG.getNode(ISD::SHL, DL, MVT::i64, SExt,
+                     DAG.getConstant(32 - ShAmt, DL, MVT::i64));
 }
 
 // Invert (and/or (set cc X, Y), (xor Z, 1)) to (or/and (set !cc X, Y)), Z) if
@@ -14207,8 +14284,7 @@ static SDValue tryDemorganOfBooleanCondition(SDValue Cond, SelectionDAG &DAG) {
                          DAG.getConstant(1, SDLoc(Setcc), VT), CCVal);
   } else if (CCVal == ISD::SETLT && isOneConstant(Setcc.getOperand(1))) {
     // (setlt X, 1) by converting to (setlt 0, X).
-    Setcc = DAG.getSetCC(SDLoc(Setcc), VT,
-                         DAG.getConstant(0, SDLoc(Setcc), VT),
+    Setcc = DAG.getSetCC(SDLoc(Setcc), VT, DAG.getConstant(0, SDLoc(Setcc), VT),
                          Setcc.getOperand(0), CCVal);
   } else
     return SDValue();
@@ -14464,9 +14540,10 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
 
   SDValue TrueVal = N->getOperand(1);
   SDValue FalseVal = N->getOperand(2);
-  if (SDValue V = tryFoldSelectIntoOp(N, DAG, TrueVal, FalseVal, /*Swapped*/false))
+  if (SDValue V =
+          tryFoldSelectIntoOp(N, DAG, TrueVal, FalseVal, /*Swapped*/ false))
     return V;
-  return tryFoldSelectIntoOp(N, DAG, FalseVal, TrueVal, /*Swapped*/true);
+  return tryFoldSelectIntoOp(N, DAG, FalseVal, TrueVal, /*Swapped*/ true);
 }
 
 /// If we have a build_vector where each lane is binop X, C, where C
@@ -14558,12 +14635,13 @@ static SDValue performINSERT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG,
       return SDValue();
     // FIXME: Return failure if the RHS type doesn't match the LHS. Shifts may
     // have different LHS and RHS types.
-    if (InVec.getOperand(0).getValueType() != InVec.getOperand(1).getValueType())
+    if (InVec.getOperand(0).getValueType() !=
+        InVec.getOperand(1).getValueType())
       return SDValue();
-    SDValue LHS = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT,
-                              InVecLHS, InValLHS, EltNo);
-    SDValue RHS = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT,
-                              InVecRHS, InValRHS, EltNo);
+    SDValue LHS =
+        DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, InVecLHS, InValLHS, EltNo);
+    SDValue RHS =
+        DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, InVecRHS, InValRHS, EltNo);
     return DAG.getNode(InVecOpcode, DL, VT, LHS, RHS);
   }
 
@@ -14581,13 +14659,13 @@ static SDValue performINSERT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG,
   if (ConcatVT.getVectorElementType() != InVal.getValueType())
     return SDValue();
   unsigned ConcatNumElts = ConcatVT.getVectorNumElements();
-  SDValue NewIdx = DAG.getConstant(Elt % ConcatNumElts, DL,
-                                   EltNo.getValueType());
+  SDValue NewIdx =
+      DAG.getConstant(Elt % ConcatNumElts, DL, EltNo.getValueType());
 
   unsigned ConcatOpIdx = Elt / ConcatNumElts;
   SDValue ConcatOp = InVec.getOperand(ConcatOpIdx);
-  ConcatOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ConcatVT,
-                         ConcatOp, InVal, NewIdx);
+  ConcatOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ConcatVT, ConcatOp, InVal,
+                         NewIdx);
 
   SmallVector<SDValue> ConcatOps;
   ConcatOps.append(InVec->op_begin(), InVec->op_end());
@@ -14695,13 +14773,11 @@ static SDValue performCONCAT_VECTORSCombine(SDNode *N, SelectionDAG &DAG,
     Stride = DAG.getNegative(Stride, DL, Stride.getValueType());
 
   SDVTList VTs = DAG.getVTList({WideVecVT, MVT::Other});
-  SDValue IntID =
-    DAG.getTargetConstant(Intrinsic::riscv_masked_strided_load, DL,
-                          Subtarget.getXLenVT());
+  SDValue IntID = DAG.getTargetConstant(Intrinsic::riscv_masked_strided_load,
+                                        DL, Subtarget.getXLenVT());
 
-  SDValue AllOneMask =
-    DAG.getSplat(WideVecVT.changeVectorElementType(MVT::i1), DL,
-                 DAG.getConstant(1, DL, MVT::i1));
+  SDValue AllOneMask = DAG.getSplat(WideVecVT.changeVectorElementType(MVT::i1),
+                                    DL, DAG.getConstant(1, DL, MVT::i1));
 
   SDValue Ops[] = {BaseLd->getChain(),   IntID,  DAG.getUNDEF(WideVecVT),
                    BaseLd->getBasePtr(), Stride, AllOneMask};
@@ -14786,15 +14862,16 @@ static SDValue combineToVWMACC(SDNode *N, SelectionDAG &DAG,
   return DAG.getNode(Opc, DL, VT, Ops);
 }
 
-static bool legalizeScatterGatherIndexType(SDLoc DL, SDValue &Index,
-                                           ISD::MemIndexType &IndexType,
-                                           RISCVTargetLowering::DAGCombinerInfo &DCI) {
+static bool
+legalizeScatterGatherIndexType(SDLoc DL, SDValue &Index,
+                               ISD::MemIndexType &IndexType,
+                               RISCVTargetLowering::DAGCombinerInfo &DCI) {
   if (!DCI.isBeforeLegalize())
     return false;
 
   SelectionDAG &DAG = DCI.DAG;
   const MVT XLenVT =
-    DAG.getMachineFunction().getSubtarget<RISCVSubtarget>().getXLenVT();
+      DAG.getMachineFunction().getSubtarget<RISCVSubtarget>().getXLenVT();
 
   const EVT IndexVT = Index.getValueType();
 
@@ -14869,7 +14946,7 @@ static bool matchIndexAsWiderOp(EVT VT, SDValue Index, SDValue Mask,
 
   const unsigned ElementSize = VT.getScalarStoreSize();
   const unsigned WiderElementSize = ElementSize * 2;
-  if (WiderElementSize > ST.getELen()/8)
+  if (WiderElementSize > ST.getELen() / 8)
     return false;
 
   if (!ST.hasFastUnalignedAccess() && BaseAlign < WiderElementSize)
@@ -14888,14 +14965,13 @@ static bool matchIndexAsWiderOp(EVT VT, SDValue Index, SDValue Mask,
         return false;
       continue;
     }
-    uint64_t Last = Index->getConstantOperandVal(i-1);
+    uint64_t Last = Index->getConstantOperandVal(i - 1);
     if (C != Last + ElementSize)
       return false;
   }
   return true;
 }
 
-
 SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
   SelectionDAG &DAG = DCI.DAG;
@@ -15245,8 +15321,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     // FIXME: Generalize to other binary ops with identical operand?
     if (TrueV.getOpcode() == ISD::XOR && FalseV.getOpcode() == ISD::XOR &&
         TrueV.getOperand(1) == FalseV.getOperand(1) &&
-        isOneConstant(TrueV.getOperand(1)) &&
-        TrueV.hasOneUse() && FalseV.hasOneUse()) {
+        isOneConstant(TrueV.getOperand(1)) && TrueV.hasOneUse() &&
+        FalseV.hasOneUse()) {
       SDValue NewSel = DAG.getNode(RISCVISD::SELECT_CC, DL, VT, LHS, RHS, CC,
                                    TrueV.getOperand(0), FalseV.getOperand(0));
       return DAG.getNode(ISD::XOR, DL, VT, NewSel, TrueV.getOperand(1));
@@ -15340,27 +15416,28 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
                                       DAG.getConstant(Addend, DL, PtrVT));
 
         SDVTList VTs = DAG.getVTList({VT, MVT::Other});
-        SDValue IntID =
-          DAG.getTargetConstant(Intrinsic::riscv_masked_strided_load, DL,
-                                XLenVT);
-        SDValue Ops[] =
-          {MGN->getChain(), IntID, MGN->getPassThru(), BasePtr,
-           DAG.getConstant(StepNumerator, DL, XLenVT), MGN->getMask()};
-        return DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, DL, VTs,
-                                       Ops, VT, MGN->getMemOperand());
+        SDValue IntID = DAG.getTargetConstant(
+            Intrinsic::riscv_masked_strided_load, DL, XLenVT);
+        SDValue Ops[] = {MGN->getChain(),
+                         IntID,
+                         MGN->getPassThru(),
+                         BasePtr,
+                         DAG.getConstant(StepNumerator, DL, XLenVT),
+                         MGN->getMask()};
+        return DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, DL, VTs, Ops, VT,
+                                       MGN->getMemOperand());
       }
     }
 
     SmallVector<int> ShuffleMask;
     if (MGN->getExtensionType() == ISD::NON_EXTLOAD &&
         matchIndexAsShuffle(VT, Index, MGN->getMask(), ShuffleMask)) {
-      SDValue Load = DAG.getMaskedLoad(VT, DL, MGN->getChain(),
-                                       MGN->getBasePtr(), DAG.getUNDEF(XLenVT),
-                                       MGN->getMask(), DAG.getUNDEF(VT),
-                                       MGN->getMemoryVT(), MGN->getMemOperand(),
-                                       ISD::UNINDEXED, ISD::NON_EXTLOAD);
+      SDValue Load = DAG.getMaskedLoad(
+          VT, DL, MGN->getChain(), MGN->getBasePtr(), DAG.getUNDEF(XLenVT),
+          MGN->getMask(), DAG.getUNDEF(VT), MGN->getMemoryVT(),
+          MGN->getMemOperand(), ISD::UNINDEXED, ISD::NON_EXTLOAD);
       SDValue Shuffle =
-        DAG.getVectorShuffle(VT, DL, Load, DAG.getUNDEF(VT), ShuffleMask);
+          DAG.getVectorShuffle(VT, DL, Load, DAG.getUNDEF(VT), ShuffleMask);
       return DAG.getMergeValues({Shuffle, Load.getValue(1)}, DL);
     }
 
@@ -15370,8 +15447,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
       SmallVector<SDValue> NewIndices;
       for (unsigned i = 0; i < Index->getNumOperands(); i += 2)
         NewIndices.push_back(Index.getOperand(i));
-      EVT IndexVT = Index.getValueType()
-        .getHalfNumVectorElementsVT(*DAG.getContext());
+      EVT IndexVT =
+          Index.getValueType().getHalfNumVectorElementsVT(*DAG.getContext());
       Index = DAG.getBuildVector(IndexVT, DL, NewIndices);
 
       unsigned ElementSize = VT.getScalarStoreSize();
@@ -15385,17 +15462,16 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
                                     EltCnt.divideCoefficientBy(2));
       SDValue Mask = DAG.getSplat(MaskVT, DL, DAG.getConstant(1, DL, MVT::i1));
 
-      SDValue Gather =
-        DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other), WideVT, DL,
-                            {MGN->getChain(), Passthru, Mask, MGN->getBasePtr(),
-                             Index, ScaleOp},
-                            MGN->getMemOperand(), IndexType, ISD::NON_EXTLOAD);
+      SDValue Gather = DAG.getMaskedGather(
+          DAG.getVTList(WideVT, MVT::Other), WideVT, DL,
+          {MGN->getChain(), Passthru, Mask, MGN->getBasePtr(), Index, ScaleOp},
+          MGN->getMemOperand(), IndexType, ISD::NON_EXTLOAD);
       SDValue Result = DAG.getBitcast(VT, Gather.getValue(0));
       return DAG.getMergeValues({Result, Gather.getValue(1)}, DL);
     }
     break;
   }
-  case ISD::MSCATTER:{
+  case ISD::MSCATTER: {
     const auto *MSN = dyn_cast<MaskedScatterSDNode>(N);
     SDValue Index = MSN->getIndex();
     SDValue ScaleOp = MSN->getScale();
@@ -15985,7 +16061,8 @@ bool RISCVTargetLowering::targetShrinkDemandedConstant(
   APInt NewMask = ShrunkMask;
   if (MinSignedBits <= 12)
     NewMask.setBitsFrom(11);
-  else if (!C->isOpaque() && MinSignedBits <= 32 && !ShrunkMask.isSignedIntN(32))
+  else if (!C->isOpaque() && MinSignedBits <= 32 &&
+           !ShrunkMask.isSignedIntN(32))
     NewMask.setBitsFrom(31);
   else
     return false;
@@ -16014,23 +16091,20 @@ static uint64_t computeGREVOrGORC(uint64_t x, unsigned ShAmt, bool IsGORC) {
   return x;
 }
 
-void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
-                                                        KnownBits &Known,
-                                                        const APInt &DemandedElts,
-                                                        const SelectionDAG &DAG,
-                                                        unsigned Depth) const {
+void RISCVTargetLowering::computeKnownBitsForTargetNode(
+    const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
+    const SelectionDAG &DAG, unsigned Depth) const {
   unsigned BitWidth = Known.getBitWidth();
   unsigned Opc = Op.getOpcode();
-  assert((Opc >= ISD::BUILTIN_OP_END ||
-          Opc == ISD::INTRINSIC_WO_CHAIN ||
-          Opc == ISD::INTRINSIC_W_CHAIN ||
-          Opc == ISD::INTRINSIC_VOID) &&
+  assert((Opc >= ISD::BUILTIN_OP_END || Opc == ISD::INTRINSIC_WO_CHAIN ||
+          Opc == ISD::INTRINSIC_W_CHAIN || Opc == ISD::INTRINSIC_VOID) &&
          "Should use MaskedValueIsZero if you don't know whether Op"
          " is a target node!");
 
   Known.resetAll();
   switch (Opc) {
-  default: break;
+  default:
+    break;
   case RISCVISD::SELECT_CC: {
     Known = DAG.computeKnownBits(Op.getOperand(4), Depth + 1);
     // If we don't know any bits, early out.
@@ -16099,8 +16173,7 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
     Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
     bool IsGORC = Op.getOpcode() == RISCVISD::ORC_B;
     // To compute zeros, we need to invert the value and invert it back after.
-    Known.Zero =
-        ~computeGREVOrGORC(~Known.Zero.getZExtValue(), 7, IsGORC);
+    Known.Zero = ~computeGREVOrGORC(~Known.Zero.getZExtValue(), 7, IsGORC);
     Known.One = computeGREVOrGORC(Known.One.getZExtValue(), 7, IsGORC);
     break;
   }
@@ -16111,7 +16184,7 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
     const unsigned MaxVLenB = Subtarget.getRealMaxVLen() / 8;
     assert(MinVLenB > 0 && "READ_VLENB without vector extension enabled?");
     Known.Zero.setLowBits(Log2_32(MinVLenB));
-    Known.Zero.setBitsFrom(Log2_32(MaxVLenB)+1);
+    Known.Zero.setBitsFrom(Log2_32(MaxVLenB) + 1);
     if (MaxVLenB == MinVLenB)
       Known.One.setBit(Log2_32(MinVLenB));
     break;
@@ -16164,7 +16237,8 @@ unsigned RISCVTargetLowering::ComputeNumSignBitsForTargetNode(
   case RISCVISD::SELECT_CC: {
     unsigned Tmp =
         DAG.ComputeNumSignBits(Op.getOperand(3), DemandedElts, Depth + 1);
-    if (Tmp == 1) return 1;  // Early out.
+    if (Tmp == 1)
+      return 1; // Early out.
     unsigned Tmp2 =
         DAG.ComputeNumSignBits(Op.getOperand(4), DemandedElts, Depth + 1);
     return std::min(Tmp, Tmp2);
@@ -16179,7 +16253,8 @@ unsigned RISCVTargetLowering::ComputeNumSignBitsForTargetNode(
     // if the input has at least 33 sign bits.
     unsigned Tmp =
         DAG.ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1);
-    if (Tmp < 33) return 1;
+    if (Tmp < 33)
+      return 1;
     return 33;
   }
   case RISCVISD::SLLW:
@@ -16276,8 +16351,8 @@ RISCVTargetLowering::getTargetConstantFromLoad(LoadSDNode *Ld) const {
   auto *CNodeLo = GetSupportedConstantPool(Ptr.getOperand(1));
   auto *CNodeHi = GetSupportedConstantPool(Ptr.getOperand(0).getOperand(0));
 
-  if (!CNodeLo || CNodeLo->getTargetFlags() != RISCVII::MO_LO ||
-      !CNodeHi || CNodeHi->getTargetFlags() != RISCVII::MO_HI)
+  if (!CNodeLo || CNodeLo->getTargetFlags() != RISCVII::MO_LO || !CNodeHi ||
+      CNodeHi->getTargetFlags() != RISCVII::MO_HI)
     return nullptr;
 
   if (CNodeLo->getConstVal() != CNodeHi->getConstVal())
@@ -16387,9 +16462,9 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
   return BB;
 }
 
-static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
-                                                 MachineBasicBlock *BB,
-                                                 const RISCVSubtarget &Subtarget) {
+static MachineBasicBlock *
+emitBuildPairF64Pseudo(MachineInstr &MI, MachineBasicBlock *BB,
+                       const RISCVSubtarget &Subtarget) {
   assert((MI.getOpcode() == RISCV::BuildPairF64Pseudo ||
           MI.getOpcode() == RISCV::BuildPairF64Pseudo_INX) &&
          "Unexpected instruction");
@@ -16687,9 +16762,9 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
 
   // Insert appropriate branch.
   BuildMI(HeadMBB, DL, TII.getBrCond(CC))
-    .addReg(LHS)
-    .addReg(RHS)
-    .addMBB(TailMBB);
+      .addReg(LHS)
+      .addReg(RHS)
+      .addMBB(TailMBB);
 
   // IfFalseMBB just falls through to TailMBB.
   IfFalseMBB->addSuccessor(TailMBB);
@@ -17041,18 +17116,15 @@ void RISCVTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
 // register-size fields in the same situations they would be for fixed
 // arguments.
 
-static const MCPhysReg ArgFPR16s[] = {
-  RISCV::F10_H, RISCV::F11_H, RISCV::F12_H, RISCV::F13_H,
-  RISCV::F14_H, RISCV::F15_H, RISCV::F16_H, RISCV::F17_H
-};
-static const MCPhysReg ArgFPR32s[] = {
-  RISCV::F10_F, RISCV::F11_F, RISCV::F12_F, RISCV::F13_F,
-  RISCV::F14_F, RISCV::F15_F, RISCV::F16_F, RISCV::F17_F
-};
-static const MCPhysReg ArgFPR64s[] = {
-  RISCV::F10_D, RISCV::F11_D, RISCV::F12_D, RISCV::F13_D,
-  RISCV::F14_D, RISCV::F15_D, RISCV::F16_D, RISCV::F17_D
-};
+static const MCPhysReg ArgFPR16s[] = {RISCV::F10_H, RISCV::F11_H, RISCV::F12_H,
+                                      RISCV::F13_H, RISCV::F14_H, RISCV::F15_H,
+                                      RISCV::F16_H, RISCV::F17_H};
+static const MCPhysReg ArgFPR32s[] = {RISCV::F10_F, RISCV::F11_F, RISCV::F12_F,
+                                      RISCV::F13_F, RISCV::F14_F, RISCV::F15_F,
+                                      RISCV::F16_F, RISCV::F17_F};
+static const MCPhysReg ArgFPR64s[] = {RISCV::F10_D, RISCV::F11_D, RISCV::F12_D,
+                                      RISCV::F13_D, RISCV::F14_D, RISCV::F15_D,
+                                      RISCV::F16_D, RISCV::F17_D};
 // This is an interim calling convention and it may be changed in the future.
 static const MCPhysReg ArgVRs[] = {
     RISCV::V8,  RISCV::V9,  RISCV::V10, RISCV::V11, RISCV::V12, RISCV::V13,
@@ -17405,8 +17477,8 @@ void RISCVTargetLowering::analyzeInputArgs(
     if (Fn(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
            ArgFlags, CCInfo, /*IsFixed=*/true, IsRet, ArgTy, *this,
            FirstMaskArgument)) {
-      LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type "
-                        << ArgVT << '\n');
+      LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type " << ArgVT
+                        << '\n');
       llvm_unreachable(nullptr);
     }
   }
@@ -17431,8 +17503,8 @@ void RISCVTargetLowering::analyzeOutputArgs(
     if (Fn(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
            ArgFlags, CCInfo, Outs[i].IsFixed, IsRet, OrigTy, *this,
            FirstMaskArgument)) {
-      LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type "
-                        << ArgVT << "\n");
+      LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type " << ArgVT
+                        << "\n");
       llvm_unreachable(nullptr);
     }
   }
@@ -17729,8 +17801,8 @@ bool RISCV::CC_RISCV_FastCC(const DataLayout &DL, RISCVABI::ABI ABI,
 }
 
 bool RISCV::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
-                         CCValAssign::LocInfo LocInfo,
-                         ISD::ArgFlagsTy ArgFlags, CCState &State) {
+                         CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
+                         CCState &State) {
   if (ArgFlags.isNest()) {
     report_fatal_error(
         "Attribute 'nest' is not supported in GHC calling convention");
@@ -17755,7 +17827,7 @@ bool RISCV::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
   if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) {
     // Pass in STG registers: F1, ..., F6
     //                        fs0 ... fs5
-    static const MCPhysReg FPR32List[] = {RISCV::F8_F, RISCV::F9_F,
+    static const MCPhysReg FPR32List[] = {RISCV::F8_F,  RISCV::F9_F,
                                           RISCV::F18_F, RISCV::F19_F,
                                           RISCV::F20_F, RISCV::F21_F};
     if (unsigned Reg = State.AllocateReg(FPR32List)) {
@@ -17815,14 +17887,14 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
   if (Func.hasFnAttribute("interrupt")) {
     if (!Func.arg_empty())
       report_fatal_error(
-        "Functions with the interrupt attribute cannot have arguments!");
+          "Functions with the interrupt attribute cannot have arguments!");
 
     StringRef Kind =
-      MF.getFunction().getFnAttribute("interrupt").getValueAsString();
+        MF.getFunction().getFnAttribute("interrupt").getValueAsString();
 
     if (!(Kind == "user" || Kind == "supervisor" || Kind == "machine"))
       report_fatal_error(
-        "Function interrupt attribute argument not supported!");
+          "Function interrupt attribute argument not supported!");
   }
 
   EVT PtrVT = getPointerTy(DAG.getDataLayout());
@@ -18236,7 +18308,8 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
     const GlobalValue *GV = S->getGlobal();
     Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, RISCVII::MO_CALL);
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
-    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, RISCVII::MO_CALL);
+    Callee =
+        DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, RISCVII::MO_CALL);
   }
 
   // The first call operand is the chain and the second is the target address.
@@ -18334,8 +18407,8 @@ bool RISCVTargetLowering::CanLowerReturn(
     ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
     RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
     if (RISCV::CC_RISCV(MF.getDataLayout(), ABI, i, VT, VT, CCValAssign::Full,
-                 ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr,
-                 *this, FirstMaskArgument))
+                        ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true,
+                        nullptr, *this, FirstMaskArgument))
       return false;
   }
   return true;
@@ -18432,7 +18505,7 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
 
     MachineFunction &MF = DAG.getMachineFunction();
     StringRef Kind =
-      MF.getFunction().getFnAttribute("interrupt").getValueAsString();
+        MF.getFunction().getFnAttribute("interrupt").getValueAsString();
 
     if (Kind == "supervisor")
       RetOpc = RISCVISD::SRET_GLUE;
@@ -19223,8 +19296,8 @@ bool RISCVTargetLowering::shouldRemoveExtendFromGSIndex(SDValue Extend,
   // We have indexed loads for all legal index types.  Indices are always
   // zero extended
   return Extend.getOpcode() == ISD::ZERO_EXTEND &&
-    isTypeLegal(Extend.getValueType()) &&
-    isTypeLegal(Extend.getOperand(0).getValueType());
+         isTypeLegal(Extend.getValueType()) &&
+         isTypeLegal(Extend.getOperand(0).getValueType());
 }
 
 bool RISCVTargetLowering::shouldConvertFpToSat(unsigned Op, EVT FPVT,
@@ -19401,7 +19474,8 @@ bool RISCVTargetLowering::shouldExtendTypeInLibCall(EVT Type) const {
   return true;
 }
 
-bool RISCVTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
+bool RISCVTargetLowering::shouldSignExtendTypeInLibCall(EVT Type,
+                                                        bool IsSigned) const {
   if (Subtarget.is64Bit() && Type == MVT::i32)
     return true;
 
@@ -19497,9 +19571,8 @@ bool RISCVTargetLowering::allowsMisalignedMemoryAccesses(
   return Subtarget.hasFastUnalignedAccess();
 }
 
-
-EVT RISCVTargetLowering::getOptimalMemOpType(const MemOp &Op,
-                                             const AttributeList &FuncAttributes) const {
+EVT RISCVTargetLowering::getOptimalMemOpType(
+    const MemOp &Op, const AttributeList &FuncAttributes) const {
   if (!Subtarget.hasVInstructions())
     return MVT::Other;
 
@@ -19514,7 +19587,7 @@ EVT RISCVTargetLowering::getOptimalMemOpType(const MemOp &Op,
   // combining will typically form larger LMUL operations from the LMUL1
   // operations emitted here, and that's okay because combining isn't
   // introducing new memory operations; it's just merging existing ones.
-  const unsigned MinVLenInBytes = Subtarget.getRealMinVLen()/8;
+  const unsigned MinVLenInBytes = Subtarget.getRealMinVLen() / 8;
   if (Op.size() < MinVLenInBytes)
     // TODO: Figure out short memops.  For the moment, do the default thing
     // which ends up using scalar sequences.
@@ -19537,7 +19610,8 @@ EVT RISCVTargetLowering::getOptimalMemOpType(const MemOp &Op,
       RequiredAlign = std::min(RequiredAlign, Op.getSrcAlign());
     PreferredVT = MVT::getIntegerVT(RequiredAlign.value() * 8);
   }
-  return MVT::getVectorVT(PreferredVT, MinVLenInBytes/PreferredVT.getStoreSize());
+  return MVT::getVectorVT(PreferredVT,
+                          MinVLenInBytes / PreferredVT.getStoreSize());
 }
 
 bool RISCVTargetLowering::splitValueIntoRegisterParts(
@@ -19714,7 +19788,8 @@ bool RISCVTargetLowering::isLegalStridedLoadStore(EVT DataType,
     return false;
 
   // Only support fixed vectors if we know the minimum vector size.
-  if (DataType.isFixedLengthVector() && !Subtarget.useRVVForFixedLengthVectors())
+  if (DataType.isFixedLengthVector() &&
+      !Subtarget.useRVVForFixedLengthVectors())
     return false;
 
   EVT ScalarType = DataType.getScalarType();
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 867a9378501f8cb..3abdb6003659fa2 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -80,11 +80,6 @@ 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);
-
 static cl::opt<bool>
     EnableSinkFold("riscv-enable-sink-fold",
                    cl::desc("Enable sinking and folding of instruction copies"),
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 2a4383314e4656a..62fe22af7c37975 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -215,6 +215,7 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
 }
 
 bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }
+bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }
 
 TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
   bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
diff --git a/llvm/test/CodeGen/RISCV/tls-models.ll b/llvm/test/CodeGen/RISCV/tls-models.ll
index 7be08fc16f3a614..b99896e35019117 100644
--- a/llvm/test/CodeGen/RISCV/tls-models.ll
+++ b/llvm/test/CodeGen/RISCV/tls-models.ll
@@ -1,16 +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: llc -mtriple=riscv32 -relocation-model=pic < %s -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: llc -mtriple=riscv64 -relocation-model=pic -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=riscv32 < %s -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
+; RUN: llc -mtriple=riscv64 < %s -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



More information about the flang-commits mailing list