[RISCV][MC] Emit `x8` as `fp` instead of `s0` (#135500)

When emphasizing `X8`'s functionality related to Frame Pointer, this option can be passed.
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index 83ecf80..972bee5 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -34,6 +34,10 @@
               cl::desc("Disable the emission of assembler pseudo instructions"),
               cl::init(false), cl::Hidden);
 
+static cl::opt<bool> EmitX8AsFP("riscv-emit-x8-as-fp",
+                                cl::desc("Emit x8 as fp instead of s0"),
+                                cl::init(false), cl::Hidden);
+
 // Print architectural register names rather than the ABI names (such as x2
 // instead of sp).
 // TODO: Make RISCVInstPrinter::getRegisterName non-static so that this can a
@@ -54,6 +58,11 @@
     ArchRegNames = true;
     return true;
   }
+  if (Opt == "emit-x8-as-fp") {
+    if (!ArchRegNames)
+      EmitX8AsFP = true;
+    return true;
+  }
 
   return false;
 }
@@ -311,6 +320,13 @@
 }
 
 const char *RISCVInstPrinter::getRegisterName(MCRegister Reg) {
+  // When PrintAliases is enabled, and EmitX8AsFP is enabled, x8 will be printed
+  // as fp instead of s0. Note that these similar registers are not replaced:
+  // - X8_H: used for f16 register in zhinx
+  // - X8_W: used for f32 register in zfinx
+  // - X8_X9: used for GPR Pair
+  if (!ArchRegNames && EmitX8AsFP && Reg == RISCV::X8)
+    return "fp";
   return getRegisterName(Reg, ArchRegNames ? RISCV::NoRegAltName
                                            : RISCV::ABIRegAltName);
 }
diff --git a/llvm/test/CodeGen/RISCV/emit-x8-as-fp.ll b/llvm/test/CodeGen/RISCV/emit-x8-as-fp.ll
new file mode 100644
index 0000000..0c9ef21
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/emit-x8-as-fp.ll
@@ -0,0 +1,121 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=RV32I-DEFAULT %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=RV64I-DEFAULT %s
+; RUN: llc -mtriple=riscv32 -M emit-x8-as-fp -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=RV32I-EMIT-FP %s
+; RUN: llc -mtriple=riscv64 -M emit-x8-as-fp -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=RV64I-EMIT-FP %s
+; RUN: llc -mtriple=riscv32 -M numeric -M emit-x8-as-fp -verify-machineinstrs \
+; RUN:   < %s | FileCheck -check-prefix=RV32I-NUMERIC %s
+; RUN: llc -mtriple=riscv64 -M numeric -M emit-x8-as-fp -verify-machineinstrs \
+; RUN:   < %s | FileCheck -check-prefix=RV64I-NUMERIC %s
+
+define signext i32 @add(i32 %0, i32 %1) #0 {
+; RV32I-DEFAULT-LABEL: add:
+; RV32I-DEFAULT:       # %bb.0:
+; RV32I-DEFAULT-NEXT:    addi sp, sp, -16
+; RV32I-DEFAULT-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-DEFAULT-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32I-DEFAULT-NEXT:    addi s0, sp, 16
+; RV32I-DEFAULT-NEXT:    sw a0, -12(s0)
+; RV32I-DEFAULT-NEXT:    sw a1, -16(s0)
+; RV32I-DEFAULT-NEXT:    lw a0, -12(s0)
+; RV32I-DEFAULT-NEXT:    lw a1, -16(s0)
+; RV32I-DEFAULT-NEXT:    add a0, a0, a1
+; RV32I-DEFAULT-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-DEFAULT-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32I-DEFAULT-NEXT:    addi sp, sp, 16
+; RV32I-DEFAULT-NEXT:    ret
+;
+; RV64I-DEFAULT-LABEL: add:
+; RV64I-DEFAULT:       # %bb.0:
+; RV64I-DEFAULT-NEXT:    addi sp, sp, -32
+; RV64I-DEFAULT-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-DEFAULT-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
+; RV64I-DEFAULT-NEXT:    addi s0, sp, 32
+; RV64I-DEFAULT-NEXT:    sw a0, -20(s0)
+; RV64I-DEFAULT-NEXT:    sw a1, -24(s0)
+; RV64I-DEFAULT-NEXT:    lw a0, -20(s0)
+; RV64I-DEFAULT-NEXT:    lw a1, -24(s0)
+; RV64I-DEFAULT-NEXT:    addw a0, a0, a1
+; RV64I-DEFAULT-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-DEFAULT-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
+; RV64I-DEFAULT-NEXT:    addi sp, sp, 32
+; RV64I-DEFAULT-NEXT:    ret
+;
+; RV32I-EMIT-FP-LABEL: add:
+; RV32I-EMIT-FP:       # %bb.0:
+; RV32I-EMIT-FP-NEXT:    addi sp, sp, -16
+; RV32I-EMIT-FP-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-EMIT-FP-NEXT:    sw fp, 8(sp) # 4-byte Folded Spill
+; RV32I-EMIT-FP-NEXT:    addi fp, sp, 16
+; RV32I-EMIT-FP-NEXT:    sw a0, -12(fp)
+; RV32I-EMIT-FP-NEXT:    sw a1, -16(fp)
+; RV32I-EMIT-FP-NEXT:    lw a0, -12(fp)
+; RV32I-EMIT-FP-NEXT:    lw a1, -16(fp)
+; RV32I-EMIT-FP-NEXT:    add a0, a0, a1
+; RV32I-EMIT-FP-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-EMIT-FP-NEXT:    lw fp, 8(sp) # 4-byte Folded Reload
+; RV32I-EMIT-FP-NEXT:    addi sp, sp, 16
+; RV32I-EMIT-FP-NEXT:    ret
+;
+; RV64I-EMIT-FP-LABEL: add:
+; RV64I-EMIT-FP:       # %bb.0:
+; RV64I-EMIT-FP-NEXT:    addi sp, sp, -32
+; RV64I-EMIT-FP-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-EMIT-FP-NEXT:    sd fp, 16(sp) # 8-byte Folded Spill
+; RV64I-EMIT-FP-NEXT:    addi fp, sp, 32
+; RV64I-EMIT-FP-NEXT:    sw a0, -20(fp)
+; RV64I-EMIT-FP-NEXT:    sw a1, -24(fp)
+; RV64I-EMIT-FP-NEXT:    lw a0, -20(fp)
+; RV64I-EMIT-FP-NEXT:    lw a1, -24(fp)
+; RV64I-EMIT-FP-NEXT:    addw a0, a0, a1
+; RV64I-EMIT-FP-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-EMIT-FP-NEXT:    ld fp, 16(sp) # 8-byte Folded Reload
+; RV64I-EMIT-FP-NEXT:    addi sp, sp, 32
+; RV64I-EMIT-FP-NEXT:    ret
+;
+; RV32I-NUMERIC-LABEL: add:
+; RV32I-NUMERIC:       # %bb.0:
+; RV32I-NUMERIC-NEXT:    addi x2, x2, -16
+; RV32I-NUMERIC-NEXT:    sw x1, 12(x2) # 4-byte Folded Spill
+; RV32I-NUMERIC-NEXT:    sw x8, 8(x2) # 4-byte Folded Spill
+; RV32I-NUMERIC-NEXT:    addi x8, x2, 16
+; RV32I-NUMERIC-NEXT:    sw x10, -12(x8)
+; RV32I-NUMERIC-NEXT:    sw x11, -16(x8)
+; RV32I-NUMERIC-NEXT:    lw x10, -12(x8)
+; RV32I-NUMERIC-NEXT:    lw x11, -16(x8)
+; RV32I-NUMERIC-NEXT:    add x10, x10, x11
+; RV32I-NUMERIC-NEXT:    lw x1, 12(x2) # 4-byte Folded Reload
+; RV32I-NUMERIC-NEXT:    lw x8, 8(x2) # 4-byte Folded Reload
+; RV32I-NUMERIC-NEXT:    addi x2, x2, 16
+; RV32I-NUMERIC-NEXT:    ret
+;
+; RV64I-NUMERIC-LABEL: add:
+; RV64I-NUMERIC:       # %bb.0:
+; RV64I-NUMERIC-NEXT:    addi x2, x2, -32
+; RV64I-NUMERIC-NEXT:    sd x1, 24(x2) # 8-byte Folded Spill
+; RV64I-NUMERIC-NEXT:    sd x8, 16(x2) # 8-byte Folded Spill
+; RV64I-NUMERIC-NEXT:    addi x8, x2, 32
+; RV64I-NUMERIC-NEXT:    sw x10, -20(x8)
+; RV64I-NUMERIC-NEXT:    sw x11, -24(x8)
+; RV64I-NUMERIC-NEXT:    lw x10, -20(x8)
+; RV64I-NUMERIC-NEXT:    lw x11, -24(x8)
+; RV64I-NUMERIC-NEXT:    addw x10, x10, x11
+; RV64I-NUMERIC-NEXT:    ld x1, 24(x2) # 8-byte Folded Reload
+; RV64I-NUMERIC-NEXT:    ld x8, 16(x2) # 8-byte Folded Reload
+; RV64I-NUMERIC-NEXT:    addi x2, x2, 32
+; RV64I-NUMERIC-NEXT:    ret
+  %3 = alloca i32, align 4
+  %4 = alloca i32, align 4
+  store i32 %0, ptr %3, align 4
+  store i32 %1, ptr %4, align 4
+  %5 = load i32, ptr %3, align 4
+  %6 = load i32, ptr %4, align 4
+  %7 = add nsw i32 %5, %6
+  ret i32 %7
+}
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all" }
diff --git a/llvm/test/MC/Disassembler/RISCV/emit-x8-as-fp.txt b/llvm/test/MC/Disassembler/RISCV/emit-x8-as-fp.txt
new file mode 100644
index 0000000..23d3f72
--- /dev/null
+++ b/llvm/test/MC/Disassembler/RISCV/emit-x8-as-fp.txt
@@ -0,0 +1,22 @@
+# RUN: llvm-mc --disassemble -triple=riscv32 --show-encoding < %s \
+# RUN:   | FileCheck --check-prefixes=DEFAULT %s
+# RUN: llvm-mc --disassemble -triple=riscv64 --show-encoding < %s \
+# RUN:   | FileCheck --check-prefixes=DEFAULT %s
+# RUN: llvm-mc --disassemble -triple=riscv32 -M emit-x8-as-fp \
+# RUN:   --show-encoding < %s | FileCheck --check-prefixes=EMIT-FP %s
+# RUN: llvm-mc --disassemble -triple=riscv64 -M emit-x8-as-fp \
+# RUN:   --show-encoding < %s | FileCheck --check-prefixes=EMIT-FP %s
+# RUN: llvm-mc --disassemble -triple=riscv32 -M numeric -M emit-x8-as-fp \
+# RUN:   --show-encoding < %s | FileCheck --check-prefixes=NUMERIC %s
+# RUN: llvm-mc --disassemble -triple=riscv64 -M numeric -M emit-x8-as-fp \
+# RUN:   --show-encoding < %s | FileCheck --check-prefixes=NUMERIC %s
+
+# DEFAULT: sw a0, -12(s0)  # encoding: [0x23,0x2a,0xa4,0xfe]
+# EMIT-FP: sw a0, -12(fp)  # encoding: [0x23,0x2a,0xa4,0xfe]
+# NUMERIC: sw x10, -12(x8) # encoding: [0x23,0x2a,0xa4,0xfe]
+0x23 0x2a 0xa4 0xfe
+
+# DEFAULT: lw a0, -12(s0)  # encoding: [0x03,0x25,0x44,0xff]
+# EMIT-FP: lw a0, -12(fp)  # encoding: [0x03,0x25,0x44,0xff]
+# NUMERIC: lw x10, -12(x8) # encoding: [0x03,0x25,0x44,0xff]
+0x03 0x25 0x44 0xff
diff --git a/llvm/test/MC/RISCV/emit-x8-as-fp.s b/llvm/test/MC/RISCV/emit-x8-as-fp.s
new file mode 100644
index 0000000..ea5143f
--- /dev/null
+++ b/llvm/test/MC/RISCV/emit-x8-as-fp.s
@@ -0,0 +1,42 @@
+# RUN: llvm-mc --triple=riscv32 --show-encoding < %s 2>&1 \
+# RUN:   | FileCheck --check-prefix=DEFAULT %s
+# RUN: llvm-mc --triple=riscv64 --show-encoding < %s 2>&1 \
+# RUN:   | FileCheck --check-prefix=DEFAULT %s
+# RUN: llvm-mc --triple=riscv32 -M emit-x8-as-fp --show-encoding < %s 2>&1 \
+# RUN:   | FileCheck --check-prefix=EMIT-FP %s
+# RUN: llvm-mc --triple=riscv64 -M emit-x8-as-fp --show-encoding < %s 2>&1 \
+# RUN:   | FileCheck --check-prefix=EMIT-FP %s
+# RUN: llvm-mc --triple=riscv32 -M numeric -M emit-x8-as-fp --show-encoding \
+# RUN:   < %s 2>&1 | FileCheck --check-prefix=NUMERIC %s
+# RUN: llvm-mc --triple=riscv64 -M numeric -M emit-x8-as-fp --show-encoding \
+# RUN:   < %s 2>&1 | FileCheck --check-prefix=NUMERIC %s
+
+# DEFAULT: sw      a0, -12(s0)                     # encoding: [0x23,0x2a,0xa4,0xfe]
+# EMIT-FP: sw      a0, -12(fp)                     # encoding: [0x23,0x2a,0xa4,0xfe]
+# NUMERIC: sw      x10, -12(x8)                    # encoding: [0x23,0x2a,0xa4,0xfe]
+sw a0, -12(s0)
+
+# DEFAULT: lw      a0, -12(s0)                     # encoding: [0x03,0x25,0x44,0xff]
+# EMIT-FP: lw      a0, -12(fp)                     # encoding: [0x03,0x25,0x44,0xff]
+# NUMERIC: lw      x10, -12(x8)                    # encoding: [0x03,0x25,0x44,0xff]
+lw a0, -12(s0)
+
+# DEFAULT: sw      a0, -12(s0)                     # encoding: [0x23,0x2a,0xa4,0xfe]
+# EMIT-FP: sw      a0, -12(fp)                     # encoding: [0x23,0x2a,0xa4,0xfe]
+# NUMERIC: sw      x10, -12(x8)                    # encoding: [0x23,0x2a,0xa4,0xfe]
+sw a0, -12(fp)
+
+# DEFAULT: lw      a0, -12(s0)                     # encoding: [0x03,0x25,0x44,0xff]
+# EMIT-FP: lw      a0, -12(fp)                     # encoding: [0x03,0x25,0x44,0xff]
+# NUMERIC: lw      x10, -12(x8)                    # encoding: [0x03,0x25,0x44,0xff]
+lw a0, -12(fp)
+
+# DEFAULT: sw      a0, -12(s0)                     # encoding: [0x23,0x2a,0xa4,0xfe]
+# EMIT-FP: sw      a0, -12(fp)                     # encoding: [0x23,0x2a,0xa4,0xfe]
+# NUMERIC: sw      x10, -12(x8)                    # encoding: [0x23,0x2a,0xa4,0xfe]
+sw a0, -12(x8)
+
+# DEFAULT: lw      a0, -12(s0)                     # encoding: [0x03,0x25,0x44,0xff]
+# EMIT-FP: lw      a0, -12(fp)                     # encoding: [0x03,0x25,0x44,0xff]
+# NUMERIC: lw      x10, -12(x8)                    # encoding: [0x03,0x25,0x44,0xff]
+lw a0, -12(x8)