[llvm] [RISCV] Add Tied operands in Xqcicm instructions and changes to handle a single tied operand in source DAG and instruction (PR #145538)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 24 09:00:02 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: quic_hchandel (hchandel)

<details>
<summary>Changes</summary>

Tied Operands change is required for adding codegen patterns for Qualcomm uC Xqcicm instructions
which will be done in a follow-up PR. This change leads to one of instructions getting compressed even
when it shouldn't be. This case was not covered in #<!-- -->143660. Added changes to correctly handle this case.

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


3 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+9-6) 
- (modified) llvm/test/MC/RISCV/xqcicm-valid.s (+6) 
- (modified) llvm/utils/TableGen/CompressInstEmitter.cpp (+11-4) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index b52798edbe143..ccd20859c24e6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -596,17 +596,20 @@ class QCILICC<bits<3> funct3, bits<2> funct2, DAGOperand InTyRs2, string opcodes
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
 class QCIMVCC<bits<3> funct3, string opcodestr>
-    : RVInstR4<0b00, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd),
-               (ins GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3),
-               opcodestr, "$rd, $rs1, $rs2, $rs3">;
+    : RVInstR4<0b00, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),
+               (ins GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3),
+               opcodestr, "$rd, $rs1, $rs2, $rs3"> {
+  let Constraints = "$rd = $rd_wb";
+}
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
 class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
-    : RVInstR4<0b10, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd),
-               (ins GPRNoX0:$rs1, immType:$imm, GPRNoX0:$rs3),
+    : RVInstR4<0b10, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),
+               (ins GPRNoX0:$rd, GPRNoX0:$rs1, immType:$imm, GPRNoX0:$rs3),
                opcodestr, "$rd, $rs1, $imm, $rs3"> {
   bits<5> imm;
-
+  
+  let Constraints = "$rd = $rd_wb";
   let rs2 = imm;
 }
 
diff --git a/llvm/test/MC/RISCV/xqcicm-valid.s b/llvm/test/MC/RISCV/xqcicm-valid.s
index 0eb253ff5e434..a9ce30e150482 100644
--- a/llvm/test/MC/RISCV/xqcicm-valid.s
+++ b/llvm/test/MC/RISCV/xqcicm-valid.s
@@ -135,3 +135,9 @@ qc.mveqi x9, x9, 0, x12
 # CHECK-ENC: encoding: [0x06,0xae]
 qc.mvltui x9, x9, 1, x12
 
+# Following instruction should not be compressed
+
+# CHECK-INST: qc.mveqi a0, s1, 0, a2
+# CHECK-ENC: encoding: [0x5b,0x85,0x04,0x64]
+qc.mveqi x10, x9, 0, x12
+
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 2dfeea36e2134..8c850ffc417f1 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -137,7 +137,8 @@ class CompressInstEmitter {
                                StringMap<unsigned> &SourceOperands,
                                StringMap<unsigned> &DestOperands,
                                const DagInit *SourceDag, const DagInit *DestDag,
-                               IndexedMap<OpData> &SourceOperandMap);
+                               IndexedMap<OpData> &SourceOperandMap,
+                               bool HasSourceTiedOp);
 
   void createInstOperandMapping(const Record *Rec, const DagInit *SourceDag,
                                 const DagInit *DestDag,
@@ -349,7 +350,8 @@ static bool validateArgsTypes(const Init *Arg1, const Init *Arg2) {
 void CompressInstEmitter::createDagOperandMapping(
     const Record *Rec, StringMap<unsigned> &SourceOperands,
     StringMap<unsigned> &DestOperands, const DagInit *SourceDag,
-    const DagInit *DestDag, IndexedMap<OpData> &SourceOperandMap) {
+    const DagInit *DestDag, IndexedMap<OpData> &SourceOperandMap,
+    bool HasSourceTiedOp) {
   for (unsigned I = 0; I < DestDag->getNumArgs(); ++I) {
     // Skip fixed immediates and registers, they were handled in
     // addDagOperandMapping.
@@ -368,7 +370,10 @@ void CompressInstEmitter::createDagOperandMapping(
         SourceOperands.find(SourceDag->getArgNameStr(I));
     if (It != SourceOperands.end()) {
       // Operand sharing the same name in the Dag should be mapped as tied.
-      SourceOperandMap[I].TiedOpIdx = It->getValue();
+      if (HasSourceTiedOp)
+        SourceOperandMap[I + 1].TiedOpIdx = It->getValue() + 1;
+      else
+        SourceOperandMap[I].TiedOpIdx = It->getValue();
       if (!validateArgsTypes(SourceDag->getArg(It->getValue()),
                              SourceDag->getArg(I)))
         PrintFatalError(Rec->getLoc(),
@@ -521,8 +526,10 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
 
   StringMap<unsigned> SourceOperands;
   StringMap<unsigned> DestOperands;
+  bool HasSourceTiedOp =
+      SourceLastTiedOp != std::numeric_limits<unsigned int>::max();
   createDagOperandMapping(Rec, SourceOperands, DestOperands, SourceDag, DestDag,
-                          SourceOperandMap);
+                          SourceOperandMap, HasSourceTiedOp);
   // Create operand mapping between the source and destination instructions.
   createInstOperandMapping(Rec, SourceDag, DestDag, SourceOperandMap,
                            DestOperandMap, SourceOperands, DestInst,

``````````

</details>


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


More information about the llvm-commits mailing list