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

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 6 17:33:22 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-driver

Author: Sam Elliott (lenary)

<details>
<summary>Changes</summary>

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)`.

---
Full diff: https://github.com/llvm/llvm-project/pull/130219.diff


11 Files Affected:

- (modified) clang/include/clang/Basic/AttrDocs.td (+1-1) 
- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1-1) 
- (modified) llvm/docs/RISCVUsage.rst (+1-1) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+1-1) 
- (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+3-4) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+1-1) 
- (modified) llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp (+24) 
- (modified) llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h (+6) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+1-1) 
- (modified) llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll (-12) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+2-2) 


``````````diff
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index fdc58d1c92c0d..02bab407d08fe 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2848,7 +2848,7 @@ https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html
 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 69b76f0c4c4cd..d9335fe502bb6 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 62c6a4fd80fd4..831e8fd5d186b 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -454,7 +454,7 @@ The current vendor extensions supported are:
   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 35db027509d94..544ad14266183 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1351,7 +1351,7 @@ def HasVendorXqcicm
                          "'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 6b61a236cf570..e1314d4fee8a0 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1008,10 +1008,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
     // 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 8e84a01821f56..32cfade8697b9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -568,7 +568,7 @@ let Predicates = [HasVendorXqciint, IsRV32], hasSideEffects = 1 in {
 
   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 a2fdbcc7f4d28..0a3ea9f6e0d6c 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
@@ -100,6 +100,29 @@ RISCVMachineFunctionInfo::getPushPopKind(const MachineFunction &MF) const {
   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;
@@ -113,3 +136,4 @@ void RISCVMachineFunctionInfo::addSExt32Register(Register Reg) {
 bool RISCVMachineFunctionInfo::isSExt32Register(Register Reg) const {
   return is_contained(SExt32Registers, Reg);
 }
+
diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
index f24355650ab22..4d06dea7414f1 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
@@ -166,6 +166,12 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
   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 85e5a71fc7b62..eaf54f879df17 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 a6c90ae9e69c3..76d61eee07eef 100644
--- a/llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll
+++ b/llvm/test/CodeGen/RISCV/qci-interrupt-attr.ll
@@ -65,7 +65,6 @@ define void @test_nest_empty() "interrupt"="qci-nest" {
 ; 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 @@ define void @test_nonest_empty() "interrupt"="qci-nonest" {
 ; 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 @@ define void @test_nest_asm() "interrupt"="qci-nest" {
 ; 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 @@ define void @test_nonest_asm() "interrupt"="qci-nonest" {
 ; 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 @@ define void @test_nest_call() "interrupt"="qci-nest" {
 ; 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 @@ define void @test_nonest_call() "interrupt"="qci-nonest" {
 ; 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 @@ define void @test_spill_nest() "interrupt"="qci-nest" {
 ; 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 @@ define void @test_spill_nonest() "interrupt"="qci-nonest" {
 ; 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 @@ define void @test_spill_call_nest() "interrupt"="qci-nest" {
 ; 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 @@ define void @test_spill_call_nonest() "interrupt"="qci-nonest" {
 ; 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 @@ define void @test_nest_explicit_s11() "interrupt"="qci-nest" {
 ; 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 @@ define void @test_nonest_explicit_s11() "interrupt"="qci-nonest" {
 ; 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 00dc160c39a36..e24b2d47f6bc4 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -656,7 +656,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
   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 @@ Experimental extensions
     xqcicm               0.2
     xqcics               0.2
     xqcicsr              0.2
-    xqciint              0.2
+    xqciint              0.4
     xqcilia              0.2
     xqcilo               0.2
     xqcilsm              0.2

``````````

</details>


https://github.com/llvm/llvm-project/pull/130219


More information about the cfe-commits mailing list