[RISCV] Update to Xqciint v0.4 (#130219)

The Xqci 0.7.0 spec just came out, with some updates to Xqciint,
bringing it to v0.4. The main update of any relevance is that
`qc.c.mienter` and `qc.c.mienter.nest` now update both the stack pointer
and the frame pointer (before, they only updated the stack pointer).
They both remain compatible with the frame pointer convention.

This change bumps the Xqciint version, and ensures that we don't emit
the unneeded frame pointer adjustment instruction after
`qc.c.mienter(.nest)`.
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 1f2f02a..34e7ff9 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2883,7 +2883,7 @@
 https://riscv.org/specifications/privileged-isa/
 The RISC-V Instruction Set Manual Volume II: Privileged Architecture
 Version 1.10.
-https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.6
+https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.7
   }];
 }
 
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 69b76f0..d9335fe 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -201,7 +201,7 @@
 // CHECK-NEXT:     xqcicm               0.2       'Xqcicm' (Qualcomm uC Conditional Move Extension)
 // CHECK-NEXT:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select Extension)
 // CHECK-NEXT:     xqcicsr              0.2       'Xqcicsr' (Qualcomm uC CSR Extension)
-// CHECK-NEXT:     xqciint              0.2       'Xqciint' (Qualcomm uC Interrupts Extension)
+// CHECK-NEXT:     xqciint              0.4       'Xqciint' (Qualcomm uC Interrupts Extension)
 // CHECK-NEXT:     xqcilia              0.2       'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)
 // CHECK-NEXT:     xqcilo               0.2       'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
 // CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 62c6a4f..831e8fd 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -454,7 +454,7 @@
   LLVM implements `version 0.2 of the Qualcomm uC CSR extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
 
 ``experimental-Xqciint``
-  LLVM implements `version 0.2 of the Qualcomm uC Interrupts extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
+  LLVM implements `version 0.4 of the Qualcomm uC Interrupts extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
 
 ``experimental-Xqcilia``
   LLVM implements `version 0.2 of the Qualcomm uC Large Immediate Arithmetic extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 35db027..544ad14 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1351,7 +1351,7 @@
                          "'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
 
 def FeatureVendorXqciint
-    : RISCVExperimentalExtension<0, 2, "Qualcomm uC Interrupts Extension",
+    : RISCVExperimentalExtension<0, 4, "Qualcomm uC Interrupts Extension",
                                  [FeatureStdExtZca]>;
 def HasVendorXqciint
     : Predicate<"Subtarget->hasVendorXqciint()">,
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 6b61a23..e1314d4 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1008,10 +1008,9 @@
     // The frame pointer does need to be reserved from register allocation.
     assert(MF.getRegInfo().isReserved(FPReg) && "FP not reserved");
 
-    // Xqccmp with hasFP will update FP using `qc.cm.pushfp`, so we don't need
-    // to update it again, but we do need to emit the `.cfi_def_cfa` below.
-    if (RVFI->getPushPopKind(MF) !=
-        RISCVMachineFunctionInfo::PushPopKind::VendorXqccmp) {
+    // Some stack management variants automatically keep FP updated, so we don't
+    // need an instruction to do so.
+    if (!RVFI->hasImplicitFPUpdates(MF)) {
       RI->adjustReg(
           MBB, MBBI, DL, FPReg, SPReg,
           StackOffset::getFixed(RealStackSize - RVFI->getVarArgsSaveSize()),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 8e84a01..32cfade 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -568,7 +568,7 @@
 
   let mayLoad = 0, mayStore = 1,
     Uses = [X1, X2, X5, X6, X7, X8, X10, X11, X12, X13, X14, X15, X16, X17, X28, X29, X30, X31],
-    Defs = [X2] in {
+    Defs = [X2, X8] in {
   def QC_C_MIENTER      : QCIRVInst16CI_NONE<0b10000, "qc.c.mienter">;
   def QC_C_MIENTER_NEST : QCIRVInst16CI_NONE<0b10001, "qc.c.mienter.nest">;
   } // mayLoad = 1, mayStore = 1, Uses = [...], Defs = [...]
diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
index a2fdbcc..1c8eda10 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
@@ -100,6 +100,29 @@
   return PushPopKind::None;
 }
 
+bool RISCVMachineFunctionInfo::hasImplicitFPUpdates(
+    const MachineFunction &MF) const {
+  switch (getInterruptStackKind(MF)) {
+  case InterruptStackKind::QCINest:
+  case InterruptStackKind::QCINoNest:
+    // QC.C.MIENTER and QC.C.MIENTER.NEST both update FP on function entry.
+    return true;
+  default:
+    break;
+  }
+
+  switch (getPushPopKind(MF)) {
+  case PushPopKind::VendorXqccmp:
+    // When using Xqccmp, we will use `QC.CM.PUSHFP` when Frame Pointers are
+    // enabled, which will update FP.
+    return true;
+  default:
+    break;
+  }
+
+  return false;
+}
+
 void RISCVMachineFunctionInfo::initializeBaseYamlFields(
     const yaml::RISCVMachineFunctionInfo &YamlMFI) {
   VarArgsFrameIndex = YamlMFI.VarArgsFrameIndex;
diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
index f243556..4d06dea 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
@@ -166,6 +166,12 @@
   unsigned getQCIInterruptStackSize() const { return QCIInterruptStackSize; }
   void setQCIInterruptStackSize(unsigned Size) { QCIInterruptStackSize = Size; }
 
+  // Some Stack Management Variants automatically update FP in a frame-pointer
+  // convention compatible way - which means we don't need to manually update
+  // the FP, but we still need to emit the correct CFI information for
+  // calculating the CFA based on FP.
+  bool hasImplicitFPUpdates(const MachineFunction &MF) const;
+
   void initializeBaseYamlFields(const yaml::RISCVMachineFunctionInfo &YamlMFI);
 
   void addSExt32Register(Register Reg);
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 85e5a71..eaf54f8 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -411,7 +411,7 @@
 ; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
 ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
-; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p2"
+; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4"
 ; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
 ; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2"
 ; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
diff --git a/llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll b/llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll
index a6c90ae..76d61ee 100644
--- a/llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll
+++ b/llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll
@@ -65,7 +65,6 @@
 ; QCI-FP-NEXT:    .cfi_offset t4, -72
 ; QCI-FP-NEXT:    .cfi_offset t5, -76
 ; QCI-FP-NEXT:    .cfi_offset t6, -80
-; QCI-FP-NEXT:    addi s0, sp, 96
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    .cfi_def_cfa sp, 96
 ; QCI-FP-NEXT:    qc.c.mileaveret
@@ -140,7 +139,6 @@
 ; QCI-FP-NEXT:    .cfi_offset t4, -72
 ; QCI-FP-NEXT:    .cfi_offset t5, -76
 ; QCI-FP-NEXT:    .cfi_offset t6, -80
-; QCI-FP-NEXT:    addi s0, sp, 96
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    .cfi_def_cfa sp, 96
 ; QCI-FP-NEXT:    qc.c.mileaveret
@@ -223,7 +221,6 @@
 ; QCI-FP-NEXT:    .cfi_offset t4, -72
 ; QCI-FP-NEXT:    .cfi_offset t5, -76
 ; QCI-FP-NEXT:    .cfi_offset t6, -80
-; QCI-FP-NEXT:    addi s0, sp, 96
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    li a0, 1
 ; QCI-FP-NEXT:    #APP
@@ -315,7 +312,6 @@
 ; QCI-FP-NEXT:    .cfi_offset t4, -72
 ; QCI-FP-NEXT:    .cfi_offset t5, -76
 ; QCI-FP-NEXT:    .cfi_offset t6, -80
-; QCI-FP-NEXT:    addi s0, sp, 96
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    li a0, 1
 ; QCI-FP-NEXT:    #APP
@@ -423,7 +419,6 @@
 ; QCI-FP-NEXT:    .cfi_offset t6, -80
 ; QCI-FP-NEXT:    addi sp, sp, -16
 ; QCI-FP-NEXT:    .cfi_def_cfa_offset 112
-; QCI-FP-NEXT:    addi s0, sp, 112
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    li a0, 4
 ; QCI-FP-NEXT:    li a2, 1
@@ -548,7 +543,6 @@
 ; QCI-FP-NEXT:    .cfi_offset t6, -80
 ; QCI-FP-NEXT:    addi sp, sp, -16
 ; QCI-FP-NEXT:    .cfi_def_cfa_offset 112
-; QCI-FP-NEXT:    addi s0, sp, 112
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    li a0, 4
 ; QCI-FP-NEXT:    li a2, 1
@@ -807,7 +801,6 @@
 ; QCI-FP-NEXT:    .cfi_offset s9, -132
 ; QCI-FP-NEXT:    .cfi_offset s10, -136
 ; QCI-FP-NEXT:    .cfi_offset s11, -140
-; QCI-FP-NEXT:    addi s0, sp, 176
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    lui t1, %hi(var)
 ; QCI-FP-NEXT:    lw a0, %lo(var)(t1)
@@ -1264,7 +1257,6 @@
 ; QCI-FP-NEXT:    .cfi_offset s9, -132
 ; QCI-FP-NEXT:    .cfi_offset s10, -136
 ; QCI-FP-NEXT:    .cfi_offset s11, -140
-; QCI-FP-NEXT:    addi s0, sp, 176
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    lui t1, %hi(var)
 ; QCI-FP-NEXT:    lw a0, %lo(var)(t1)
@@ -1765,7 +1757,6 @@
 ; QCI-FP-NEXT:    .cfi_offset s9, -132
 ; QCI-FP-NEXT:    .cfi_offset s10, -136
 ; QCI-FP-NEXT:    .cfi_offset s11, -140
-; QCI-FP-NEXT:    addi s0, sp, 240
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    lui s6, %hi(var)
 ; QCI-FP-NEXT:    lw a0, %lo(var)(s6)
@@ -2356,7 +2347,6 @@
 ; QCI-FP-NEXT:    .cfi_offset s9, -132
 ; QCI-FP-NEXT:    .cfi_offset s10, -136
 ; QCI-FP-NEXT:    .cfi_offset s11, -140
-; QCI-FP-NEXT:    addi s0, sp, 240
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    lui s6, %hi(var)
 ; QCI-FP-NEXT:    lw a0, %lo(var)(s6)
@@ -2768,7 +2758,6 @@
 ; QCI-FP-NEXT:    .cfi_def_cfa_offset 112
 ; QCI-FP-NEXT:    sw s11, 12(sp) # 4-byte Folded Spill
 ; QCI-FP-NEXT:    .cfi_offset s11, -100
-; QCI-FP-NEXT:    addi s0, sp, 112
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    #APP
 ; QCI-FP-NEXT:    li s4, 0
@@ -2877,7 +2866,6 @@
 ; QCI-FP-NEXT:    .cfi_def_cfa_offset 112
 ; QCI-FP-NEXT:    sw s11, 12(sp) # 4-byte Folded Spill
 ; QCI-FP-NEXT:    .cfi_offset s11, -100
-; QCI-FP-NEXT:    addi s0, sp, 112
 ; QCI-FP-NEXT:    .cfi_def_cfa s0, 0
 ; QCI-FP-NEXT:    #APP
 ; QCI-FP-NEXT:    li s11, 0
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 00dc160..e24b2d4 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -656,7 +656,7 @@
   for (StringRef Input :
        {"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "rv64i_xqciac0p3",
         "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
-        "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2",
+        "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
         "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4"}) {
     EXPECT_THAT(
         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
@@ -1132,7 +1132,7 @@
     xqcicm               0.2
     xqcics               0.2
     xqcicsr              0.2
-    xqciint              0.2
+    xqciint              0.4
     xqcilia              0.2
     xqcilo               0.2
     xqcilsm              0.2