[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 08:59:19 PDT 2025


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

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.

>From e4ecc21a7ab5aa6f0b7dee469a767926a4033075 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Tue, 24 Jun 2025 12:54:21 +0530
Subject: [PATCH 1/2] [RISCV] Add Tied operands in Xqcicm instructions

This is required for adding codegen patterns for 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.

Change-Id: I945255ecacec8b8ac0f4c5356fdefdd14269d396
---
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 15 +++++++++------
 llvm/test/MC/RISCV/xqcicm-valid.s           |  7 +++++++
 2 files changed, 16 insertions(+), 6 deletions(-)

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..82237db00398c 100644
--- a/llvm/test/MC/RISCV/xqcicm-valid.s
+++ b/llvm/test/MC/RISCV/xqcicm-valid.s
@@ -135,3 +135,10 @@ qc.mveqi x9, x9, 0, x12
 # CHECK-ENC: encoding: [0x06,0xae]
 qc.mvltui x9, x9, 1, x12
 
+# Following instruction should not be compressed
+
+# CHECK-NOALIAS: qc.c.mveqz s1, a2
+# CHECK-ALIAS: qc.mveqi s1, s1, 0, a2
+# CHECK-ENC: encoding: [0x06,0xae]
+qc.mveqi x10, x9, 0, x12
+

>From bf3aa59944634a71f26deec5d5ef30f6ad7eb976 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Tue, 24 Jun 2025 13:09:42 +0530
Subject: [PATCH 2/2] [RISCV] Add changes to handle a single tied operand in
 source DAG and instruction

This case was not covered in #143660. Added changes to correctly handle this case.

Change-Id: I40006a35e505c1e09b8ca4eadf4a85451d4e769b
---
 llvm/test/MC/RISCV/xqcicm-valid.s           |  5 ++---
 llvm/utils/TableGen/CompressInstEmitter.cpp | 15 +++++++++++----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/llvm/test/MC/RISCV/xqcicm-valid.s b/llvm/test/MC/RISCV/xqcicm-valid.s
index 82237db00398c..a9ce30e150482 100644
--- a/llvm/test/MC/RISCV/xqcicm-valid.s
+++ b/llvm/test/MC/RISCV/xqcicm-valid.s
@@ -137,8 +137,7 @@ qc.mvltui x9, x9, 1, x12
 
 # Following instruction should not be compressed
 
-# CHECK-NOALIAS: qc.c.mveqz s1, a2
-# CHECK-ALIAS: qc.mveqi s1, s1, 0, a2
-# CHECK-ENC: encoding: [0x06,0xae]
+# 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,



More information about the llvm-commits mailing list