diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index bd3c1b7de743a..7b4f46cdb4443 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -170,6 +170,16 @@
 // CHECK-NEXT:     xmipscmov            1.0       'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov))
 // CHECK-NEXT:     xmipslsp             1.0       'XMIPSLSP' (MIPS optimization for hardware load-store bonding)
 // CHECK-NEXT:     xsfcease             1.0       'XSfcease' (SiFive sf.cease Instruction)
+// CHECK-NEXT:     xsfmm128t            0.6       'XSfmm128t' (TE=128 configuration)
+// CHECK-NEXT:     xsfmm16t             0.6       'XSfmm16t' (TE=16 configuration)
+// CHECK-NEXT:     xsfmm32a16f          0.6       'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF))
+// CHECK-NEXT:     xsfmm32a32f          0.6       'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b)
+// CHECK-NEXT:     xsfmm32a8f           0.6       'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8)
+// CHECK-NEXT:     xsfmm32a8i           0.6       'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b)
+// CHECK-NEXT:     xsfmm32t             0.6       'XSfmm32t' (TE=32 configuration)
+// CHECK-NEXT:     xsfmm64a64f          0.6       'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64)
+// CHECK-NEXT:     xsfmm64t             0.6       'XSfmm64t' (TE=64 configuration)
+// CHECK-NEXT:     xsfmmbase            0.6       'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero)
 // CHECK-NEXT:     xsfvcp               1.0       'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)
 // CHECK-NEXT:     xsfvfnrclipxfqf      1.0       'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions)
 // CHECK-NEXT:     xsfvfwmaccqqq        1.0       'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4))
diff --git a/clang/test/Preprocessor/riscv-target-features-sifive.c b/clang/test/Preprocessor/riscv-target-features-sifive.c
new file mode 100644
index 0000000000000..e4c03876bd94b
--- /dev/null
+++ b/clang/test/Preprocessor/riscv-target-features-sifive.c
@@ -0,0 +1,79 @@
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm128t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM128T %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm128t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM128T %s
+// CHECK-XSFMM128T: __riscv_xsfmm128t  6000{{$}}
+//
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm16t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM16T %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm16t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM16T %s
+// CHECK-XSFMM16T: __riscv_xsfmm16t  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm32a8i -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32a8I %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm32a8i -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32a8I %s
+// CHECK-XSFMM32a8I: __riscv_xsfmm32a8i  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm32a8f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32A8F %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm32a8f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32A8F %s
+// CHECK-XSFMM32A8F: __riscv_xsfmm32a8f  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm32a16f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32a16F %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm32a16f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32a16F %s
+// CHECK-XSFMM32a16F: __riscv_xsfmm32a16f  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm32a32f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32a32F %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm32a32f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32a32F %s
+// CHECK-XSFMM32a32F: __riscv_xsfmm32a32f  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm32t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32T %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm32t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM32T %s
+// CHECK-XSFMM32T: __riscv_xsfmm32t  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm64a64f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM64a64f %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm64a64f -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM64a64f %s
+// CHECK-XSFMM64a64f: __riscv_xsfmm64a64f  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmm64t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM64T %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmm64t -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMM64T %s
+// CHECK-XSFMM64T: __riscv_xsfmm64t  6000{{$}}
+
+// RUN: %clang --target=riscv32 \
+// RUN:   -march=rv32i_zve32x_xsfmmbase -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMMBASE %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_zve32x_xsfmmbase -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-XSFMMBASE %s
+// CHECK-XSFMMBASE: __riscv_xsfmmbase  6000{{$}}
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index cf11d3878a745..b8bec547c06b6 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -392,6 +392,9 @@ The current vendor extensions supported are:
 ``XVentanaCondOps``
   LLVM implements `version 1.0.0 of the VTx-family custom instructions specification <https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf>`__ by Ventana Micro Systems.  All instructions are prefixed with `vt.` as described in the specification, and the riscv-toolchain-convention document linked above.  These instructions are only available for riscv64 at this time.
 
+``Xsfmm*``
+  LLVM implements `version 0.6 of the Xsfmm Family of Attached Matrix Extensions Specification <https://www.sifive.com/document-file/xsfmm-matrix-extensions-specification>`__ by SiFive.  All instructions are prefixed with `sf.` as described in the specification.
+
 ``XSfvcp``
   LLVM implements `version 1.1.0 of the SiFive Vector Coprocessor Interface (VCIX) Software Specification <https://sifive.cdn.prismic.io/sifive/Zn3m1R5LeNNTwnLS_vcix-spec-software-v1p1.pdf>`__ by SiFive.  All instructions are prefixed with `sf.vc.` as described in the specification, and the riscv-toolchain-convention document linked above.
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 590597faaa05f..2f6d90cdc589f 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -197,7 +197,9 @@ Changes to the RISC-V Backend
 * Adds assembler support for the Andes `XAndesvdot` (Andes Vector Dot Product extension).
 * Adds assembler support for the standard `Q` (Quad-Precision Floating Point) 
   extension.
-  
+* Adds experimental assembler support for the SiFive Xsfmm* Attached Matrix
+  Extensions.
+
 Changes to the WebAssembly Backend
 ----------------------------------
 
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index e0105685c210d..a529479b546d9 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -89,6 +89,8 @@ inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
 unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
                      bool MaskAgnostic);
 
+unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt);
+
 inline static VLMUL getVLMUL(unsigned VType) {
   unsigned VLMul = VType & 0x7;
   return static_cast<VLMUL>(VLMul);
@@ -118,10 +120,34 @@ inline static unsigned getSEW(unsigned VType) {
   return decodeVSEW(VSEW);
 }
 
+inline static unsigned decodeTWiden(unsigned TWiden) {
+  assert((TWiden == 1 || TWiden == 2 || TWiden == 3) &&
+         "Unexpected TWiden value");
+  return 1 << (TWiden - 1);
+}
+
+inline static bool hasXSfmmWiden(unsigned VType) {
+  unsigned TWiden = (VType >> 9) & 0x3;
+  return TWiden != 0;
+}
+
+inline static unsigned getXSfmmWiden(unsigned VType) {
+  unsigned TWiden = (VType >> 9) & 0x3;
+  assert(TWiden != 0 && "Invalid widen value");
+  return 1 << (TWiden - 1);
+}
+
+static inline bool isValidXSfmmVType(unsigned VTypeI) {
+  return (VTypeI & ~0x738) == 0 && RISCVVType::hasXSfmmWiden(VTypeI) &&
+         RISCVVType::getSEW(VTypeI) * RISCVVType::getXSfmmWiden(VTypeI) <= 64;
+}
+
 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
 
 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
 
+inline static bool isAltFmt(unsigned VType) { return VType & 0x100; }
+
 void printVType(unsigned VType, raw_ostream &OS);
 
 unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul);
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index f64307babab07..42d6da25805bd 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -125,6 +125,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
                        bool &MaskAgnostic);
   bool generateVTypeError(SMLoc ErrorLoc);
 
+  bool generateXSfmmVTypeError(SMLoc ErrorLoc);
   // Helper to actually emit an instruction to the MCStreamer. Also, when
   // possible, compression of the instruction is performed.
   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
@@ -221,6 +222,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
   }
 
   ParseStatus parseRegReg(OperandVector &Operands);
+  ParseStatus parseXSfmmVType(OperandVector &Operands);
   ParseStatus parseRetval(OperandVector &Operands);
   ParseStatus parseZcmpStackAdj(OperandVector &Operands,
                                 bool ExpectNegative = false);
@@ -634,6 +636,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return isUImm<11>();
   }
 
+  bool isXSfmmVType() const {
+    return Kind == KindTy::VType && RISCVVType::isValidXSfmmVType(VType.Val);
+  }
+
   /// Return true if the operand is a valid for the fence instruction e.g.
   /// ('iorw').
   bool isFenceArg() const { return Kind == KindTy::Fence; }
@@ -2342,6 +2348,65 @@ bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
       "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
 }
 
+ParseStatus RISCVAsmParser::parseXSfmmVType(OperandVector &Operands) {
+  SMLoc S = getLoc();
+
+  unsigned Widen = 0;
+  unsigned SEW = 0;
+  bool AltFmt = false;
+  StringRef Identifier;
+
+  if (getTok().isNot(AsmToken::Identifier))
+    goto Fail;
+
+  Identifier = getTok().getIdentifier();
+
+  if (!Identifier.consume_front("e"))
+    goto Fail;
+
+  if (Identifier.getAsInteger(10, SEW)) {
+    if (Identifier != "16alt")
+      goto Fail;
+
+    AltFmt = true;
+    SEW = 16;
+  }
+  if (!RISCVVType::isValidSEW(SEW))
+    goto Fail;
+
+  Lex();
+
+  if (!parseOptionalToken(AsmToken::Comma))
+    goto Fail;
+
+  if (getTok().isNot(AsmToken::Identifier))
+    goto Fail;
+
+  Identifier = getTok().getIdentifier();
+
+  if (!Identifier.consume_front("w"))
+    goto Fail;
+  if (Identifier.getAsInteger(10, Widen))
+    goto Fail;
+  if (Widen != 1 && Widen != 2 && Widen != 4)
+    goto Fail;
+
+  Lex();
+
+  if (getLexer().is(AsmToken::EndOfStatement)) {
+    Operands.push_back(RISCVOperand::createVType(
+        RISCVVType::encodeXSfmmVType(SEW, Widen, AltFmt), S));
+    return ParseStatus::Success;
+  }
+
+Fail:
+  return generateXSfmmVTypeError(S);
+}
+
+bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
+  return Error(ErrorLoc, "operand must be e[8|16|16alt|32|64],w[1|2|4]");
+}
+
 ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
   if (getLexer().isNot(AsmToken::Identifier))
     return ParseStatus::NoMatch;
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index a5e76668db6b9..4363e5c5176c9 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -344,6 +344,39 @@ static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo,
+                                          uint64_t Address,
+                                          const MCDisassembler *Decoder) {
+  if (RegNo > 15)
+    return MCDisassembler::Fail;
+
+  MCRegister Reg = RISCV::T0 + RegNo;
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  if (RegNo > 15 || RegNo % 2)
+    return MCDisassembler::Fail;
+
+  MCRegister Reg = RISCV::T0 + RegNo;
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  if (RegNo > 15 || RegNo % 4)
+    return MCDisassembler::Fail;
+
+  MCRegister Reg = RISCV::T0 + RegNo;
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
@@ -722,9 +755,9 @@ static constexpr FeatureBitset XqciFeatureGroup = {
 };
 
 static constexpr FeatureBitset XSfVectorGroup = {
-    RISCV::FeatureVendorXSfvcp, RISCV::FeatureVendorXSfvqmaccdod,
-    RISCV::FeatureVendorXSfvqmaccqoq, RISCV::FeatureVendorXSfvfwmaccqqq,
-    RISCV::FeatureVendorXSfvfnrclipxfqf};
+    RISCV::FeatureVendorXSfvcp,          RISCV::FeatureVendorXSfvqmaccdod,
+    RISCV::FeatureVendorXSfvqmaccqoq,    RISCV::FeatureVendorXSfvfwmaccqqq,
+    RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase};
 static constexpr FeatureBitset XSfSystemGroup = {
     RISCV::FeatureVendorXSiFivecdiscarddlone,
     RISCV::FeatureVendorXSiFivecflushdlone,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index dc6937bb74a3c..1f4a77414db6b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -227,6 +227,20 @@ void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo,
   RISCVVType::printVType(Imm, O);
 }
 
+void RISCVInstPrinter::printXSfmmVType(const MCInst *MI, unsigned OpNo,
+                                       const MCSubtargetInfo &STI,
+                                       raw_ostream &O) {
+  unsigned Imm = MI->getOperand(OpNo).getImm();
+  assert(RISCVVType::isValidXSfmmVType(Imm));
+  unsigned SEW = RISCVVType::getSEW(Imm);
+  O << "e" << SEW;
+  bool AltFmt = RISCVVType::isAltFmt(Imm);
+  if (AltFmt)
+    O << "alt";
+  unsigned Widen = RISCVVType::getXSfmmWiden(Imm);
+  O << ", w" << Widen;
+}
+
 // Print a Zcmp RList. If we are printing architectural register names rather
 // than ABI register names, we need to print "{x1, x8-x9, x18-x27}" for all
 // registers. Otherwise, we print "{ra, s0-s11}".
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index 8a6129926d4f2..f8b8fd34abbb4 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -48,6 +48,8 @@ class RISCVInstPrinter : public MCInstPrinter {
                             const MCSubtargetInfo &STI, raw_ostream &O);
   void printVTypeI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                    raw_ostream &O);
+  void printXSfmmVType(const MCInst *MI, unsigned OpNo,
+                       const MCSubtargetInfo &STI, raw_ostream &O);
   void printVMaskReg(const MCInst *MI, unsigned OpNo,
                      const MCSubtargetInfo &STI, raw_ostream &O);
   void printRegList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index b36d496137400..28b108c21f385 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1205,6 +1205,73 @@ def HasVendorXSfvcp : Predicate<"Subtarget->hasVendorXSfvcp()">,
                       AssemblerPredicate<(all_of FeatureVendorXSfvcp),
                           "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)">;
 
+def FeatureVendorXSfmmbase
+    : RISCVExtension<0, 6,
+                     "All non arithmetic instructions for all TEWs and sf.vtzero",
+                     [FeatureStdExtZve32x]>;
+def HasVendorXSfmmbase : Predicate<"Subtarget->hasVendorXSfmmbase()">,
+                         AssemblerPredicate<(all_of FeatureVendorXSfmmbase),
+                             "'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero)">;
+
+def FeatureVendorXSfmm32a8f
+    : RISCVExtension<0, 6,
+                     "TEW=32-bit accumulation, operands - float: fp8",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZve32f]>;
+def HasVendorXSfmm32a8f : Predicate<"Subtarget->hasVendorXSfmm32a8f()">,
+                          AssemblerPredicate<(all_of FeatureVendorXSfmm32a8f),
+                              "'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8)">;
+
+def FeatureVendorXSfmm32a16f
+    : RISCVExtension<0, 6,
+                     "TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZve32f]>;
+
+def FeatureVendorXSfmm32a32f
+    : RISCVExtension<0, 6,
+                     "TEW=32-bit accumulation, operands - float: 32b",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZve32f]>;
+
+def FeatureVendorXSfmm32a8i
+    : RISCVExtension<0, 6,
+                     "TEW=32-bit accumulation, operands - int: 8b",
+                     [FeatureVendorXSfmmbase]>;
+def HasVendorXSfmm32a8i : Predicate<"Subtarget->hasVendorXSfmm32a8i()">,
+                          AssemblerPredicate<(all_of FeatureVendorXSfmm32a8i),
+                              "'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b)">;
+
+def FeatureVendorXSfmm64a64f
+    : RISCVExtension<0, 6,
+                     "TEW=64-bit accumulation, operands - float: fp64",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZve64d]>;
+def HasVendorXSfmm32a16fOrXSfmm32a32fOrXSfmm64a64f
+    : Predicate<"Subtarget->hasVendorXSfmm32a16fOrXSfmm32a32fOrXSfmm64a64f()">,
+                AssemblerPredicate<(any_of FeatureVendorXSfmm32a16f,
+                                           FeatureVendorXSfmm32a32f,
+                                           FeatureVendorXSfmm64a64f),
+                    "'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)), or "
+                    "'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b), or "
+                    "'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64)">;
+
+def FeatureVendorXSfmm16t
+    : RISCVExtension<0, 6,
+                     "TE=16 configuration",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZvl64b], "XSfmmTE", "16">;
+
+def FeatureVendorXSfmm32t
+    : RISCVExtension<0, 6,
+                     "TE=32 configuration",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZvl128b], "XSfmmTE", "32">;
+
+def FeatureVendorXSfmm64t
+    : RISCVExtension<0, 6,
+                     "TE=64 configuration",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZvl256b], "XSfmmTE", "64">;
+
+def FeatureVendorXSfmm128t
+    : RISCVExtension<0, 6,
+                     "TE=128 configuration",
+                     [FeatureVendorXSfmmbase, FeatureStdExtZvl512b], "XSfmmTE", "128">;
+
 def FeatureVendorXSfvqmaccdod
     : RISCVExtension<1, 0,
                      "SiFive Int8 Matrix Multiplication Instructions (2-by-8 and 8-by-2)",
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 41b3a57315b57..8d76f0f476f23 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2267,6 +2267,7 @@ include "RISCVInstrInfoSFB.td"
 include "RISCVInstrInfoXVentana.td"
 include "RISCVInstrInfoXTHead.td"
 include "RISCVInstrInfoXSf.td"
+include "RISCVInstrInfoXSfmm.td"
 include "RISCVInstrInfoXCV.td"
 include "RISCVInstrInfoXwch.td"
 include "RISCVInstrInfoXqci.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td
new file mode 100644
index 0000000000000..66cb2d53da960
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td
@@ -0,0 +1,274 @@
+//===-- RISCVInstrInfoXsfmm.td - SiFive matrix multiply ----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the Xsfmm* vendor extensions defined by SiFive.
+//
+//===----------------------------------------------------------------------===//
+
+def XSfmmVTypeAsmOperand : AsmOperandClass {
+  let Name = "XSfmmVType";
+  let ParserMethod = "parseXSfmmVType";
+  let DiagnosticType = "InvalidXSfmmVType";
+  let RenderMethod = "addVTypeIOperands";
+}
+
+def XSfmmVTypeOp : RISCVOp {
+  let ParserMatchClass = XSfmmVTypeAsmOperand;
+  let PrintMethod = "printXSfmmVType";
+  let OperandType = "OPERAND_XSFMM_VTYPE";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    if (!isUInt<32>(Imm))
+      return false;
+    return RISCVVType::isValidXSfmmVType(Imm);
+  }];
+}
+
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class SFInstSetSingle<dag outs, dag ins, bits<5> rs2, string opcodestr,
+                      string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
+  bits<5> rs1;
+  bits<5> rd;
+
+  let Inst{31-25} = 0b1000010;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = OPCFG.Value;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Defs = [VTYPE, VL];
+}
+
+class SFInstTileMemOp<dag outs, dag ins, bits<3> nf, RISCVOpcode opcode,
+                      string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> rs2;
+  bits<5> rs1;
+
+  let Inst{31-29} = nf;
+  let Inst{28} = 1;
+  let Inst{27-26} = MOPLDUnitStride.Value;
+  let Inst{25} = 1;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = 0b111;
+  let Inst{11-7} = 0b00000;
+  let Inst{6-0} = opcode.Value;
+
+  let Uses = [VTYPE, VL];
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class SFInstTileLoad<bits<3> nf, string opcodestr>
+    : SFInstTileMemOp<(outs), (ins GPR:$rs2, GPRMemZeroOffset:$rs1), nf,
+                      OPC_LOAD_FP, opcodestr, "$rs2, ${rs1}">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class SFInstTileStore<bits<3> nf, string opcodestr>
+    : SFInstTileMemOp<(outs), (ins GPR:$rs2, GPRMemZeroOffset:$rs1), nf,
+                      OPC_STORE_FP, opcodestr, "$rs2, ${rs1}">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class SFInstTileMoveOp<bits<6> funct6, dag outs, dag ins, string opcodestr,
+                       string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> rs2;
+  bits<5> rs1;
+  bits<5> vd;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = 1;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = OPMVX.Value;
+  let Inst{11-7} = vd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class SFInstMatmulF<dag outs, dag ins, string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> vs2;
+  bits<5> vs1;
+  bits<4> rd;
+
+  let Inst{31-26} = 0b111100;
+  let Inst{25} = 1;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = vs1;
+  let Inst{14-12} = OPFVV.Value;
+  let Inst{11-9} = rd{3-1};
+  let Inst{8-7} = 0b00;
+  let Inst{6-0} = OPC_OP_VE.Value;
+
+  let Uses = [VTYPE, VL];
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class SFInstMatmulF8<bit a, bit b, dag outs, dag ins,
+                     string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> vs2;
+  bits<5> vs1;
+  bits<4> rd;
+
+  let Inst{31-27} = 0b11111;
+  let Inst{26} = a;
+  let Inst{25} = 1;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = vs1;
+  let Inst{14-12} = OPFVV.Value;
+  let Inst{11-10} = rd{3-2};
+  let Inst{9-8} = 0b00;
+  let Inst{7} = b;
+  let Inst{6-0} = OPC_OP_VE.Value;
+
+  let Uses = [VTYPE, VL];
+}
+
+
+class F8Encode<bit encoding, string name> {
+  bit Encoding = encoding;
+  string Name = name;
+}
+
+defvar F8Encodes = [F8Encode<0b0, "e5m2">,
+                    F8Encode<0b1, "e4m3">];
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class SFInstMatmulI8<bit funct6_1, bit a, bit b, dag outs, dag ins,
+                     string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> vs2;
+  bits<5> vs1;
+  bits<4> rd;
+
+  let Inst{31-28} = 0b1111;
+  let Inst{27} = funct6_1;
+  let Inst{26} = a;
+  let Inst{25} = 1;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = vs1;
+  let Inst{14-12} = OPIVV.Value;
+  let Inst{11-10} = rd{3-2};
+  let Inst{9-8} = 0b00;
+  let Inst{7} = b;
+  let Inst{6-0} = OPC_OP_VE.Value;
+
+  let Uses = [VTYPE, VL];
+}
+
+class I8Encode<bit encoding, string name> {
+  bit Encoding = encoding;
+  string Name = name;
+}
+
+defvar I8Encodes = [I8Encode<0, "u">,
+                    I8Encode<1, "s">];
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class SFInstSetZero<dag outs, dag ins, string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> vs2;
+  bits<5> vs1;
+  bits<4> rd;
+
+  let Inst{31-26} = 0b010000;
+  let Inst{25} = 1;
+  let Inst{24-20} = 0b11110;
+  let Inst{19-15} = 0b00000;
+  let Inst{14-12} = OPMVX.Value;
+  let Inst{11-8} = rd;
+  let Inst{7} = 0;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+}
+
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class SFInstVtDiscard<string opcodestr>
+    : RVInst<(outs), (ins), opcodestr, "", [], InstFormatR> {
+  let Inst{31-26} = 0b010000;
+  let Inst{25} = 1;
+  let Inst{24-20} = 0b11100;
+  let Inst{19-15} = 0b00000;
+  let Inst{14-12} = OPMVX.Value;
+  let Inst{11-7} = 0b00000;
+  let Inst{6-0} = OPC_OP_V.Value;
+}
+
+let Predicates = [HasVendorXSfmmbase] in
+def : InstAlias<"sf.vsettnt $rd, $rs1, $vtypei",
+                (VSETVLI GPR:$rd, GPR:$rs1, XSfmmVTypeOp:$vtypei)>;
+
+let DecoderNamespace = "XSfvector" in {
+
+let Predicates = [HasVendorXSfmmbase] in {
+  def SF_VSETTN : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00000,
+                                  "sf.vsettn", "$rd, $rs1">;
+  def SF_VSETTM : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00001,
+                                  "sf.vsettm", "$rd, $rs1">;
+  def SF_VSETTK : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00010,
+                                   "sf.vsettk", "$rd, $rs1">;
+  def SF_VTDISCARD : SFInstVtDiscard<"sf.vtdiscard">;
+
+  def SF_VTMV_V_T : SFInstTileMoveOp<0b010000, (outs VR:$vd), (ins GPR:$rs1),
+                                     "sf.vtmv.v.t", "$vd, $rs1"> {
+    let rs2 = 0b11111;
+  }
+  def SF_VTMV_T_V : SFInstTileMoveOp<0b010111, (outs), (ins GPR:$rs1, VR:$rs2),
+                                     "sf.vtmv.t.v", "$rs1, $rs2"> {
+    let vd = 0b00000;
+  }
+
+  def SF_VTZERO_T : SFInstSetZero<(outs), (ins TR:$rd), "sf.vtzero.t", "$rd">;
+
+  def SF_VLTE8  : SFInstTileLoad<0b000, "sf.vlte8">;
+  def SF_VLTE16 : SFInstTileLoad<0b001, "sf.vlte16">;
+  def SF_VLTE32 : SFInstTileLoad<0b010, "sf.vlte32">;
+  def SF_VLTE64 : SFInstTileLoad<0b011, "sf.vlte64">;
+
+  def SF_VSTE8  : SFInstTileStore<0b000, "sf.vste8">;
+  def SF_VSTE16 : SFInstTileStore<0b001, "sf.vste16">;
+  def SF_VSTE32 : SFInstTileStore<0b010, "sf.vste32">;
+  def SF_VSTE64 : SFInstTileStore<0b011, "sf.vste64">;
+} // Predicates = [HasVendorXSfmmbase]
+
+let Predicates = [HasVendorXSfmm32a16fOrXSfmm32a32fOrXSfmm64a64f] in {
+  let Uses = [FRM], mayRaiseFPException = true in
+  def SF_MM_F_F   : SFInstMatmulF<(outs), (ins TRM2:$rd, VR:$vs2, VR:$vs1),
+                                  "sf.mm.f.f", "$rd, $vs2, $vs1">;
+} // Predicates = [HasVendorXSfmm32a16fOrXSfmm64a32fOrXSfmm64a64f]
+
+let Predicates = [HasVendorXSfmm32a8i] in {
+  foreach a = I8Encodes in
+    foreach b = I8Encodes in
+      def SF_MM_#!toupper(a.Name)#_#!toupper(b.Name)
+          : SFInstMatmulI8<0, a.Encoding, b.Encoding,
+                           (outs), (ins TRM4:$rd, VR:$vs2, VR:$vs1),
+                           "sf.mm."#a.Name#"."#b.Name, "$rd, $vs2, $vs1">;
+} // Predicates = [HasVendorXSfmm32a8i]
+
+let Predicates = [HasVendorXSfmm32a8f] in {
+let Uses = [FRM], mayRaiseFPException = true in {
+  foreach a = F8Encodes in
+    foreach b = F8Encodes in
+      def SF_MM_#!toupper(a.Name)#_#!toupper(b.Name)
+          : SFInstMatmulF8<a.Encoding, b.Encoding,
+                           (outs), (ins TRM4:$rd, VR:$vs2, VR:$vs1),
+                           "sf.mm."#a.Name#"."#b.Name, "$rd, $vs2, $vs1">;
+}
+} // Predicates = [HasVendorXSfmm32a8f]
+
+} // DecoderNamespace = "XSfvector"
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index cd725ca6166e2..80213e1503b0a 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -856,3 +856,16 @@ def : RISCVRegisterClass<[XLenVT], 32, (add SF_VCIX_STATE)> {
   let RegInfos = XLenRI;
   let isAllocatable = 0;
 }
+
+//===----------------------------------------------------------------------===//
+// XSfmmbase tiles
+//===----------------------------------------------------------------------===//
+foreach Index = 0-15 in
+  def T#Index : RISCVReg<Index, "mt"#Index, []>,
+                DwarfRegNum<[!add(Index, 3072)]>;
+
+let RegInfos = XLenRI in {
+  def TR   : RISCVRegisterClass<[untyped], 32, (add (sequence "T%u", 0, 15))>;
+  def TRM2 : RISCVRegisterClass<[untyped], 32, (add (decimate TR, 2))>;
+  def TRM4 : RISCVRegisterClass<[untyped], 32, (add (decimate TR, 4))>;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 035ce4745cfd9..0eef7b1feaf5b 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -99,6 +99,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   bool ATTRIBUTE = DEFAULT;
 #include "RISCVGenSubtargetInfo.inc"
 
+  unsigned XSfmmTE = 0;
   unsigned ZvlLen = 0;
   unsigned RVVVectorBitsMin;
   unsigned RVVVectorBitsMax;
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index 5bd7de1d3ca46..2e5e8f4e50c9c 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -164,6 +164,15 @@ unsigned encodeVTYPE(VLMUL VLMul, unsigned SEW, bool TailAgnostic,
   return VTypeI;
 }
 
+unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt) {
+  assert(isValidSEW(SEW) && "Invalid SEW");
+  assert((Widen == 1 || Widen == 2 || Widen == 4) && "Invalid Widen");
+  unsigned VSEWBits = encodeSEW(SEW);
+  unsigned TWiden = Log2_32(Widen) + 1;
+  unsigned VTypeI = (VSEWBits << 3) | AltFmt << 8 | TWiden << 9;
+  return VTypeI;
+}
+
 std::pair<unsigned, bool> decodeVLMUL(VLMUL VLMul) {
   switch (VLMul) {
   default:
diff --git a/llvm/test/CodeGen/RISCV/attributes-sifive.ll b/llvm/test/CodeGen/RISCV/attributes-sifive.ll
new file mode 100644
index 0000000000000..7afb939d1cf87
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/attributes-sifive.ll
@@ -0,0 +1,50 @@
+;; Generate ELF attributes from llc.
+
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm128t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM128T %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm16t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM16T %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a8i %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A8I %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a8f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A8F %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a16f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A16F %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a32f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A32F %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32T %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm64a64f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM64A64F %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmm64t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM64T %s
+; RUN: llc -mtriple=riscv32 -mattr=+xsfmmbase %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMMBASE %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm128t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM128T %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm16t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM16T %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a8i %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A8I %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a8f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A8F %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a16f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A16F %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a32f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A32F %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32T %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm64a64f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM64A64F %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmm64t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM64T %s
+; RUN: llc -mtriple=riscv64 -mattr=+xsfmmbase %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMMBASE %s
+
+; CHECK: .attribute 4, 16
+
+; RV32XSFMM128T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0_xsfmm128t0p6_xsfmmbase0p6"
+; RV32XSFMM16T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0_xsfmm16t0p6_xsfmmbase0p6" 
+; RV32XSFMM32A8I: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmm32a8i0p6_xsfmmbase0p6"
+; RV32XSFMM32A8F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a8f0p6_xsfmmbase0p6"
+; RV32XSFMM32A16F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a16f0p6_xsfmmbase0p6"
+; RV32XSFMM32A32F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a32f0p6_xsfmmbase0p6"
+; RV32XSFMM32T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfmm32t0p6_xsfmmbase0p6"
+; RV32XSFMM64A64F: .attribute 5, "rv32i2p1_f2p2_d2p2_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_xsfmm64a64f0p6_xsfmmbase0p6"
+; RV32XSFMM64T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfmm64t0p6_xsfmmbase0p6"
+; RV32XSFMMBASE: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmmbase0p6"
+; RV64XSFMM128T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0_xsfmm128t0p6_xsfmmbase0p6"
+; RV64XSFMM16T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0_xsfmm16t0p6_xsfmmbase0p6"
+; RV64XSFMM32A8I: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmm32a8i0p6_xsfmmbase0p6"
+; RV64XSFMM32A8F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a8f0p6_xsfmmbase0p6"
+; RV64XSFMM32A16F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a16f0p6_xsfmmbase0p6"
+; RV64XSFMM32A32F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a32f0p6_xsfmmbase0p6"
+; RV64XSFMM32T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfmm32t0p6_xsfmmbase0p6"
+; RV64XSFMM64A64F: .attribute 5, "rv64i2p1_f2p2_d2p2_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_xsfmm64a64f0p6_xsfmmbase0p6"
+; RV64XSFMM64T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfmm64t0p6_xsfmmbase0p6"
+; RV64XSFMMBASE: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmmbase0p6"
+
+define i32 @addi(i32 %a) {
+  %1 = add i32 %a, 1
+  ret i32 %1
+}
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 00311bab50836..6c2b8af55acce 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -184,6 +184,16 @@
 ; CHECK-NEXT:   xmipscmov                        - 'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov)).
 ; CHECK-NEXT:   xmipslsp                         - 'XMIPSLSP' (MIPS optimization for hardware load-store bonding).
 ; CHECK-NEXT:   xsfcease                         - 'XSfcease' (SiFive sf.cease Instruction).
+; CHECK-NEXT:   xsfmm128t                        - 'XSfmm128t' (TE=128 configuration).
+; CHECK-NEXT:   xsfmm16t                         - 'XSfmm16t' (TE=16 configuration).
+; CHECK-NEXT:   xsfmm32a16f                      - 'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)). 
+; CHECK-NEXT:   xsfmm32a32f                      - 'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b). 
+; CHECK-NEXT:   xsfmm32a8f                       - 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8). 
+; CHECK-NEXT:   xsfmm32a8i                       - 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b). 
+; CHECK-NEXT:   xsfmm32t                         - 'XSfmm32t' (TE=32 configuration). 
+; CHECK-NEXT:   xsfmm64a64f                      - 'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64). 
+; CHECK-NEXT:   xsfmm64t                         - 'XSfmm64t' (TE=64 configuration). 
+; CHECK-NEXT:   xsfmmbase                        - 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero).
 ; CHECK-NEXT:   xsfvcp                           - 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions).
 ; CHECK-NEXT:   xsfvfnrclipxfqf                  - 'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions).
 ; CHECK-NEXT:   xsfvfwmaccqqq                    - 'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4)).
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir
index fc3bb13df77d6..f151569ef4e57 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir
@@ -24,7 +24,7 @@ body:             |
     ; CHECK-NEXT: renamable $v8 = PseudoVLE64_V_M1 undef renamable $v8, [[COPY1]], 1, 6 /* e64 */, 2 /* tu, ma */, implicit $vl, implicit $vtype :: (load unknown-size, align 8)
     ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 8, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
     ; CHECK-NEXT: renamable $v9 = PseudoVLE32_V_M1 undef renamable $v9, [[COPY]], 8, 5 /* e32 */, 2 /* tu, ma */, implicit $vl, implicit $vtype :: (load unknown-size, align 4)
-    ; CHECK-NEXT: INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 3997705 /* reguse:VR */, killed renamable $v10, 3997705 /* reguse:VR */, killed renamable $v11, 3997705 /* reguse:VR */, killed renamable $v8, 3997705 /* reguse:VR */, killed renamable $v9
+    ; CHECK-NEXT: INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 4194313 /* reguse:VR */, killed renamable $v10, 4194313 /* reguse:VR */, killed renamable $v11, 4194313 /* reguse:VR */, killed renamable $v8, 4194313 /* reguse:VR */, killed renamable $v9
     ; CHECK-NEXT: PseudoRET
     %3:gpr = COPY $x12
     %2:gpr = COPY $x11
@@ -34,7 +34,7 @@ body:             |
     renamable $v11 = PseudoVMV_S_X undef renamable $v11, %1, 8, 5 /* e32 */
     renamable $v8 = PseudoVLE64_V_M1 undef renamable $v8, %2, 1, 6 /* e64 */, 2 /* tu, ma */ :: (load unknown-size, align 8)
     renamable $v9 = PseudoVLE32_V_M1 undef renamable $v9, %3, 8, 5 /* e32 */, 2 /* tu, ma */ :: (load unknown-size, align 4)
-    INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 3997705 /* reguse:VR */, killed renamable $v10, 3997705 /* reguse:VR */, killed renamable $v11, 3997705 /* reguse:VR */, killed renamable $v8, 3997705 /* reguse:VR */, killed renamable $v9
+    INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 4194313 /* reguse:VR */, killed renamable $v10, 4194313 /* reguse:VR */, killed renamable $v11, 4194313 /* reguse:VR */, killed renamable $v8, 4194313 /* reguse:VR */, killed renamable $v9
     PseudoRET
 
 ...
diff --git a/llvm/test/MC/RISCV/attribute-arch-sifive.s b/llvm/test/MC/RISCV/attribute-arch-sifive.s
new file mode 100644
index 0000000000000..45eeb722b8d95
--- /dev/null
+++ b/llvm/test/MC/RISCV/attribute-arch-sifive.s
@@ -0,0 +1,34 @@
+## Arch string without version.
+
+# RUN: llvm-mc %s -triple=riscv32 -filetype=asm | FileCheck %s
+# RUN: llvm-mc %s -triple=riscv64 -filetype=asm | FileCheck %s
+
+.attribute arch, "rv32i_xsfmm128t"
+# CHECK: attribute      5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0_xsfmm128t0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm16t"
+# CHECK: attribute      5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0_xsfmm16t0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm32a8i"
+# CHECK: attribute      5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmm32a8i0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm32a8f"
+# CHECK: attribute      5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a8f0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm32a16f"
+# CHECK: attribute      5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a16f0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm32a32f"
+# CHECK: attribute      5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a32f0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm32t"
+# CHECK: attribute      5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfmm32t0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm64a64f"
+# CHECK: attribute      5, "rv32i2p1_f2p2_d2p2_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_xsfmm64a64f0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmm64t"
+# CHECK: attribute      5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfmm64t0p6_xsfmmbase0p6"
+
+.attribute arch, "rv32i_xsfmmbase"
+# CHECK: attribute      5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmmbase0p6"
diff --git a/llvm/test/MC/RISCV/rvv/xsfmm-invalid.s b/llvm/test/MC/RISCV/rvv/xsfmm-invalid.s
new file mode 100644
index 0000000000000..6b17d25b4b903
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/xsfmm-invalid.s
@@ -0,0 +1,30 @@
+# RUN: not llvm-mc -triple=riscv32 --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8f,+xsfmm64a64f %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK
+# RUN: not llvm-mc -triple=riscv64 --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8f,+xsfmm64a64f %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK
+
+sf.vsettnt a0, a1, e128, w1 # CHECK: :[[@LINE]]:20: error: operand must be e[8|16|16alt|32|64],w[1|2|4]
+
+sf.vsettnt a0, a1, e8alt, w1 # CHECK: :[[@LINE]]:20: error: operand must be e[8|16|16alt|32|64],w[1|2|4]
+
+sf.vsettnt a0, a1, e16alt, w1, a2 # CHECK: :[[@LINE]]:20: error: operand must be e[8|16|16alt|32|64],w[1|2|4]
+
+sf.mm.f.f mt1, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+
+sf.mm.e5m2.e5m2 mt2, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+
+sf.mm.e5m2.e4m3 mt6, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+
+sf.mm.e4m3.e5m2 mt10, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+
+sf.mm.e4m3.e4m3 mt14, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+
+sf.mm.u.u mt1, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+
+sf.mm.s.u mt2, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+
+sf.mm.u.s mt3, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+
+sf.mm.s.s mt1, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
diff --git a/llvm/test/MC/RISCV/rvv/xsfmm.s b/llvm/test/MC/RISCV/rvv/xsfmm.s
new file mode 100644
index 0000000000000..8de520aa964b7
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/xsfmm.s
@@ -0,0 +1,200 @@
+# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv32 -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \
+# RUN:        | llvm-objdump -d  --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f --no-print-imm-hex - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \
+# RUN:        | llvm-objdump -d  --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f --no-print-imm-hex - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \
+# RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsfmmbase, \
+# RUN:     --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \
+# RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+# CHECK-INST: sf.vsettnt a0, a1, e8, w1
+# CHECK-ENCODING: [0x57,0xf5,0x05,0x20]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 2005f557 <unknown>
+sf.vsettnt a0, a1, e8, w1
+
+# CHECK-INST: sf.vsettnt a0, a1, e16alt, w1
+# CHECK-ENCODING: [0x57,0xf5,0x85,0x30]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 3085f557 <unknown>
+sf.vsettnt a0, a1, e16alt, w1
+
+# CHECK-INST: sf.vsettnt a0, a1, e8, w1
+# CHECK-ENCODING: [0x57,0xf5,0x05,0x20]
+# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors)
+# CHECK-UNKNOWN: 2005f557 <unknown>
+vsetvli a0, a1, 0x200
+
+# CHECK-INST: sf.vsettnt a0, a1, e16alt, w1
+# CHECK-ENCODING: [0x57,0xf5,0x85,0x30]
+# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors)
+# CHECK-UNKNOWN: 3085f557 <unknown>
+vsetvli a0, a1, 0x308
+
+# CHECK-INST: sf.vsettn a0, a1
+# CHECK-ENCODING: [0x57,0xf5,0x05,0x84]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 8405f557 <unknown>
+sf.vsettn a0, a1
+
+# CHECK-INST: sf.vsettm a0, a1
+# CHECK-ENCODING: [0x57,0xf5,0x15,0x84]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 8415f557 <unknown>
+sf.vsettm a0, a1
+
+# CHECK-INST: sf.vsettk a0, a1
+# CHECK-ENCODING: [0x57,0xf5,0x25,0x84]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 8425f557 <unknown>
+sf.vsettk a0, a1
+
+# CHECK-INST: sf.vlte8  a0, (a1)
+# CHECK-ENCODING: [0x07,0xf0,0xa5,0x12]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 12a5f007 <unknown>
+sf.vlte8  a0, (a1)
+
+# CHECK-INST: sf.vlte16 a0, (a1)
+# CHECK-ENCODING: [0x07,0xf0,0xa5,0x32]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 32a5f007 <unknown>
+sf.vlte16 a0, (a1)
+
+# CHECK-INST: sf.vlte32 a0, (a1)
+# CHECK-ENCODING: [0x07,0xf0,0xa5,0x52]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 52a5f007 <unknown>
+sf.vlte32 a0, (a1)
+
+# CHECK-INST: sf.vlte64 a0, (a1)
+# CHECK-ENCODING: [0x07,0xf0,0xa5,0x72]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 72a5f007 <unknown>
+sf.vlte64 a0, (a1)
+
+# CHECK-INST: sf.vste8  a0, (a1)
+# CHECK-ENCODING: [0x27,0xf0,0xa5,0x12]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 12a5f027 <unknown>
+sf.vste8  a0, (a1)
+
+# CHECK-INST: sf.vste16 a0, (a1)
+# CHECK-ENCODING: [0x27,0xf0,0xa5,0x32]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 32a5f027 <unknown>
+sf.vste16 a0, (a1)
+
+# CHECK-INST: sf.vste32 a0, (a1)
+# CHECK-ENCODING: [0x27,0xf0,0xa5,0x52]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 52a5f027 <unknown>
+sf.vste32 a0, (a1)
+
+# CHECK-INST: sf.vste64 a0, (a1)
+# CHECK-ENCODING: [0x27,0xf0,0xa5,0x72]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 72a5f027 <unknown>
+sf.vste64 a0, (a1)
+
+# CHECK-INST: sf.vtmv.v.t v8, a0
+# CHECK-ENCODING: [0x57,0x64,0xf5,0x43]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 43f56457 <unknown>
+sf.vtmv.v.t v8, a0
+
+# CHECK-INST: sf.vtmv.t.v a0, v8
+# CHECK-ENCODING: [0x57,0x60,0x85,0x5e]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 5e856057 <unknown>
+sf.vtmv.t.v a0, v8
+
+# CHECK-INST: sf.mm.f.f mt2, v8, v9
+# CHECK-ENCODING: [0x77,0x92,0x84,0xf2]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)), or 'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b), or 'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64){{$}}
+# CHECK-UNKNOWN: f2849277 <unknown>
+sf.mm.f.f mt2, v8, v9
+
+# CHECK-INST: sf.mm.e5m2.e5m2 mt0, v8, v9
+# CHECK-ENCODING: [0x77,0x90,0x84,0xfa]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}}
+# CHECK-UNKNOWN: fa849077 <unknown>
+sf.mm.e5m2.e5m2 mt0, v8, v9
+
+# CHECK-INST: sf.mm.e5m2.e4m3 mt4, v8, v9
+# CHECK-ENCODING: [0xf7,0x94,0x84,0xfa]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}}
+# CHECK-UNKNOWN: fa8494f7 <unknown>
+sf.mm.e5m2.e4m3 mt4, v8, v9
+
+# CHECK-INST: sf.mm.e4m3.e5m2 mt8, v8, v9
+# CHECK-ENCODING: [0x77,0x98,0x84,0xfe]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}}
+# CHECK-UNKNOWN: fe849877 <unknown>
+sf.mm.e4m3.e5m2 mt8, v8, v9
+
+# CHECK-INST: sf.mm.e4m3.e4m3 mt12, v8, v9
+# CHECK-ENCODING: [0xf7,0x9c,0x84,0xfe]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}}
+# CHECK-UNKNOWN: fe849cf7 <unknown>
+sf.mm.e4m3.e4m3 mt12, v8, v9
+
+# CHECK-INST: sf.mm.u.u mt0, v8, v9
+# CHECK-ENCODING: [0x77,0x80,0x84,0xf2]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}}
+# CHECK-UNKNOWN: f2848077 <unknown>
+sf.mm.u.u mt0, v8, v9
+
+# CHECK-INST: sf.mm.s.u mt4, v8, v9
+# CHECK-ENCODING: [0x77,0x84,0x84,0xf6]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}}
+# CHECK-UNKNOWN: f6848477 <unknown>
+sf.mm.s.u mt4, v8, v9
+
+# CHECK-INST: sf.mm.u.s mt8, v8, v9
+# CHECK-ENCODING: [0xf7,0x88,0x84,0xf2]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}}
+# CHECK-UNKNOWN: f28488f7 <unknown>
+sf.mm.u.s mt8, v8, v9
+
+# CHECK-INST: sf.mm.s.s mt12, v8, v9
+# CHECK-ENCODING: [0xf7,0x8c,0x84,0xf6]
+# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}}
+# CHECK-UNKNOWN: f6848cf7 <unknown>
+sf.mm.s.s mt12, v8, v9
+
+# CHECK-INST: sf.vtzero.t mt15
+# CHECK-ENCODING: [0x57,0x6f,0xe0,0x43]
+# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}}
+# CHECK-UNKNOWN: 43e06f57 <unknown>
+sf.vtzero.t mt15
+
+# CHECK-INST: vsetvl a2, a0, a1
+# CHECK-ENCODING: [0x57,0x76,0xb5,0x80]
+# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors)
+# CHECK-UNKNOWN: 80b57657 <unknown>
+vsetvl a2, a0, a1
+
+# CHECK-INST:  vsetvli a0, a1, e8, m1, tu, mu
+# CHECK-ENCODING: [0x57,0xf5,0x05,0x00]
+# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors)
+# CHECK-UNKNOWN: 0005f557 <unknown>
+vsetvli a0, a1, e8, m1, tu, mu
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index fc6854a483f6f..7a2539e80388c 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1141,6 +1141,16 @@ R"(All available -march extensions for RISC-V
     xmipscmov            1.0
     xmipslsp             1.0
     xsfcease             1.0
+    xsfmm128t            0.6
+    xsfmm16t             0.6
+    xsfmm32a16f          0.6
+    xsfmm32a32f          0.6
+    xsfmm32a8f           0.6
+    xsfmm32a8i           0.6
+    xsfmm32t             0.6
+    xsfmm64a64f          0.6
+    xsfmm64t             0.6
+    xsfmmbase            0.6
     xsfvcp               1.0
     xsfvfnrclipxfqf      1.0
     xsfvfwmaccqqq        1.0