[llvm] [RISCV] Add support for handling one tied operand in the source instruction for compress patterns (PR #143660)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 10 23:28:29 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: quic_hchandel (hchandel)
<details>
<summary>Changes</summary>
This update enables compress patterns to handle one tied operand in source instructions, which was previously unsupported. Qualcomm's uC extension Xqci includes several instructions with tied operands that can be compressed into smaller forms. This change adds the necessary support to enable such compression. Additionally, a compress pattern for the qc.muliadd instruction has been implemented.
---
Full diff: https://github.com/llvm/llvm-project/pull/143660.diff
3 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+5)
- (modified) llvm/test/MC/RISCV/xqciac-valid.s (+16-5)
- (modified) llvm/utils/TableGen/CompressInstEmitter.cpp (+30-9)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index dba035bab928c..ce5de3291a672 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1556,6 +1556,11 @@ def : CompressPat<(QC_E_ADDI X2, X2, simm10_lsb0000nonzero:$imm),
(C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
} // let isCompressOnly = true, Predicates = [HasVendorXqcilia, IsRV32]
+let Predicates = [HasVendorXqciac, IsRV32] in {
+def : CompressPat<(QC_MULIADD GPRC:$rd, GPRC:$rs1, uimm5:$imm5),
+ (QC_C_MULIADD GPRC:$rd, GPRC:$rs1, uimm5:$imm5)>;
+}
+
let isCompressOnly = true, Predicates = [HasVendorXqcibi, IsRV32] in {
def : CompressPat<(QC_E_BEQI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12),
(QC_BEQI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;
diff --git a/llvm/test/MC/RISCV/xqciac-valid.s b/llvm/test/MC/RISCV/xqciac-valid.s
index 438c4cafe0dfe..1afebc75cb45a 100644
--- a/llvm/test/MC/RISCV/xqciac-valid.s
+++ b/llvm/test/MC/RISCV/xqciac-valid.s
@@ -1,24 +1,27 @@
# Xqciac - Qualcomm uC Load-Store Address Calculation Extension
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -M no-aliases -show-encoding \
-# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST,CHECK-NOALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \
# RUN: | llvm-objdump --mattr=+experimental-xqciac -M no-aliases --no-print-imm-hex -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -show-encoding \
-# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST,CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \
# RUN: | llvm-objdump --mattr=+experimental-xqciac --no-print-imm-hex -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
-# CHECK-INST: qc.c.muliadd a0, a1, 0
+# CHECK-NOALIAS: qc.c.muliadd a0, a1, 0
+# CHECK-ALIAS: qc.muliadd a0, a1, 0
# CHECK-ENC: encoding: [0x8a,0x21]
qc.c.muliadd x10, x11, 0
-# CHECK-INST: qc.c.muliadd a0, a1, 31
+# CHECK-NOALIAS: qc.c.muliadd a0, a1, 31
+# CHECK-ALIAS: qc.muliadd a0, a1, 31
# CHECK-ENC: encoding: [0xea,0x3d]
qc.c.muliadd x10, x11, 31
-# CHECK-INST: qc.c.muliadd a0, a1, 16
+# CHECK-NOALIAS: qc.c.muliadd a0, a1, 16
+# CHECK-ALIAS: qc.muliadd a0, a1, 16
# CHECK-ENC: encoding: [0xaa,0x21]
qc.c.muliadd x10, x11, 16
@@ -47,3 +50,11 @@ qc.shladd x10, x11, x12, 4
# CHECK-INST: qc.shladd a0, a1, a2, 31
# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x7e]
qc.shladd x10, x11, x12, 31
+
+# Check that compress pattern for qc.muliadd works
+
+# CHECK-NOALIAS: qc.c.muliadd a0, a1, 16
+# CHECK-ALIAS: qc.muliadd a0, a1, 16
+# CHECK-ENC: encoding: [0xaa,0x21]
+qc.muliadd x10, x11, 16
+
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 4a0b6d79c53d9..515d27c04158a 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -75,6 +75,7 @@
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
+#include <limits>
#include <set>
#include <vector>
using namespace llvm;
@@ -123,7 +124,7 @@ class CompressInstEmitter {
const RecordKeeper &Records;
const CodeGenTarget Target;
std::vector<CompressPat> CompressPatterns;
-
+ unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
void addDagOperandMapping(const Record *Rec, const DagInit *Dag,
const CodeGenInstruction &Inst,
IndexedMap<OpData> &OperandMap, bool IsSourceInst);
@@ -219,12 +220,16 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
// are represented.
unsigned TiedCount = 0;
unsigned OpNo = 0;
+ if (IsSourceInst)
+ SourceLastTiedOp = std::numeric_limits<unsigned int>::max();
for (const auto &Opnd : Inst.Operands) {
int TiedOpIdx = Opnd.getTiedRegister();
if (-1 != TiedOpIdx) {
// Set the entry in OperandMap for the tied operand we're skipping.
OperandMap[OpNo].Kind = OperandMap[TiedOpIdx].Kind;
OperandMap[OpNo].Data = OperandMap[TiedOpIdx].Data;
+ if (IsSourceInst)
+ SourceLastTiedOp = OpNo;
++OpNo;
++TiedCount;
continue;
@@ -289,15 +294,23 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
bool IsSource) {
unsigned NumMIOperands = 0;
- for (const auto &Op : Inst.Operands)
+
+ // Use this to count number of tied Operands in Source Inst in this function.
+ // This counter is required here to error out when there is a Source
+ // Inst with two or more tied operands.
+ unsigned SourceInstTiedOpCount = 0;
+ for (const auto &Op : Inst.Operands) {
NumMIOperands += Op.MINumOperands;
+ if (Op.getTiedRegister() != -1)
+ SourceInstTiedOpCount++;
+ }
if (Dag->getNumArgs() == NumMIOperands)
return true;
- // Source instructions are non compressed instructions and don't have tied
- // operands.
- if (IsSource)
+ // Source instructions are non compressed instructions and have atmost one
+ // tied operand.
+ if (IsSource && (SourceInstTiedOpCount >= 2))
PrintFatalError(Inst.TheDef->getLoc(),
"Input operands for Inst '" + Inst.TheDef->getName() +
"' and input Dag operand count mismatch");
@@ -422,10 +435,18 @@ void CompressInstEmitter::createInstOperandMapping(
assert(DestDag->getArgNameStr(DagArgIdx) ==
SourceDag->getArgNameStr(SourceOp->getValue()) &&
"Incorrect operand mapping detected!\n");
- DestOperandMap[OpNo].Data.Operand = SourceOp->getValue();
- SourceOperandMap[SourceOp->getValue()].Data.Operand = OpNo;
- LLVM_DEBUG(dbgs() << " " << SourceOp->getValue() << " ====> " << OpNo
- << "\n");
+
+ // Following four lines ensure the correct handling of a single tied
+ // operand in the Source Inst. SourceDagOp points to the position of
+ // appropriate Dag argument which is not correct in presence of tied
+ // operand in the Source Inst and must be incremented by 1 to reflect
+ // correct position of the operand in Source Inst
+ unsigned SourceDagOp = SourceOp->getValue();
+ if (SourceDagOp >= SourceLastTiedOp)
+ SourceDagOp++;
+ DestOperandMap[OpNo].Data.Operand = SourceDagOp;
+ SourceOperandMap[SourceDagOp].Data.Operand = OpNo;
+ LLVM_DEBUG(dbgs() << " " << SourceDagOp << " ====> " << OpNo << "\n");
}
}
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/143660
More information about the llvm-commits
mailing list