[llvm] 408e550 - [RISCV] Add support for handling one tied operand in the source instruction for compress patterns (#143660)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 19 00:06:23 PDT 2025
Author: quic_hchandel
Date: 2025-06-19T12:36:20+05:30
New Revision: 408e55098d7d8f7064d7a288b5e3fe6fdbbc2ad4
URL: https://github.com/llvm/llvm-project/commit/408e55098d7d8f7064d7a288b5e3fe6fdbbc2ad4
DIFF: https://github.com/llvm/llvm-project/commit/408e55098d7d8f7064d7a288b5e3fe6fdbbc2ad4.diff
LOG: [RISCV] Add support for handling one tied operand in the source instruction for compress patterns (#143660)
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.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
llvm/test/MC/RISCV/xqciac-valid.s
llvm/utils/TableGen/CompressInstEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 09852c6fd5969..2856df47f7043 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1570,6 +1570,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..2dfeea36e2134 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,10 +124,10 @@ class CompressInstEmitter {
const RecordKeeper &Records;
const CodeGenTarget Target;
std::vector<CompressPat> CompressPatterns;
-
void addDagOperandMapping(const Record *Rec, const DagInit *Dag,
const CodeGenInstruction &Inst,
- IndexedMap<OpData> &OperandMap, bool IsSourceInst);
+ IndexedMap<OpData> &OperandMap, bool IsSourceInst,
+ unsigned *SourceLastTiedOpPtr);
void evaluateCompressPat(const Record *Compress);
void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType);
bool validateTypes(const Record *DagOpType, const Record *InstOpType,
@@ -143,7 +144,8 @@ class CompressInstEmitter {
IndexedMap<OpData> &SourceOperandMap,
IndexedMap<OpData> &DestOperandMap,
StringMap<unsigned> &SourceOperands,
- const CodeGenInstruction &DestInst);
+ const CodeGenInstruction &DestInst,
+ unsigned SourceLastTiedOp);
public:
CompressInstEmitter(const RecordKeeper &R) : Records(R), Target(R) {}
@@ -206,7 +208,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
const DagInit *Dag,
const CodeGenInstruction &Inst,
IndexedMap<OpData> &OperandMap,
- bool IsSourceInst) {
+ bool IsSourceInst,
+ unsigned *SourceLastTiedOpPtr) {
unsigned NumMIOperands = 0;
for (const auto &Op : Inst.Operands)
NumMIOperands += Op.MINumOperands;
@@ -219,12 +222,16 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
// are represented.
unsigned TiedCount = 0;
unsigned OpNo = 0;
+ if (IsSourceInst)
+ *SourceLastTiedOpPtr = 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)
+ *SourceLastTiedOpPtr = OpNo;
++OpNo;
++TiedCount;
continue;
@@ -289,15 +296,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 at most one
+ // tied operand.
+ if (IsSource && (SourceInstTiedOpCount >= 2))
PrintFatalError(Inst.TheDef->getLoc(),
"Input operands for Inst '" + Inst.TheDef->getName() +
"' and input Dag operand count mismatch");
@@ -381,7 +396,8 @@ void CompressInstEmitter::createDagOperandMapping(
void CompressInstEmitter::createInstOperandMapping(
const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
- StringMap<unsigned> &SourceOperands, const CodeGenInstruction &DestInst) {
+ StringMap<unsigned> &SourceOperands, const CodeGenInstruction &DestInst,
+ unsigned SourceLastTiedOp) {
// TiedCount keeps track of the number of operands skipped in Inst
// operands list to get to the corresponding Dag operand.
unsigned TiedCount = 0;
@@ -422,10 +438,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");
}
}
}
@@ -484,15 +508,16 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
// Fill the mapping from the source to destination instructions.
IndexedMap<OpData> SourceOperandMap;
+ unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
// Create a mapping between source Dag operands and source Inst operands.
addDagOperandMapping(Rec, SourceDag, SourceInst, SourceOperandMap,
- /*IsSourceInst*/ true);
+ /*IsSourceInst*/ true, &SourceLastTiedOp);
IndexedMap<OpData> DestOperandMap;
// Create a mapping between destination Dag operands and destination Inst
// operands.
addDagOperandMapping(Rec, DestDag, DestInst, DestOperandMap,
- /*IsSourceInst*/ false);
+ /*IsSourceInst*/ false, nullptr);
StringMap<unsigned> SourceOperands;
StringMap<unsigned> DestOperands;
@@ -500,7 +525,8 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
SourceOperandMap);
// Create operand mapping between the source and destination instructions.
createInstOperandMapping(Rec, SourceDag, DestDag, SourceOperandMap,
- DestOperandMap, SourceOperands, DestInst);
+ DestOperandMap, SourceOperands, DestInst,
+ SourceLastTiedOp);
// Get the target features for the CompressPat.
std::vector<const Record *> PatReqFeatures;
More information about the llvm-commits
mailing list