[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
Wed Jun 18 00:18:34 PDT 2025
https://github.com/hchandel updated https://github.com/llvm/llvm-project/pull/143660
>From 4e7fe3810563fa963e62604dadb7f6d5c288c6c8 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Wed, 11 Jun 2025 11:19:11 +0530
Subject: [PATCH 1/3] [RISCV] Add support for handling one tied operand in the
source instruction for compress patterns
Change-Id: I69b8aac8fcf674d214cd00691b428555b61d4ebe
---
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 5 +++
llvm/test/MC/RISCV/xqciac-valid.s | 21 ++++++++---
llvm/utils/TableGen/CompressInstEmitter.cpp | 41 ++++++++++++++++-----
3 files changed, 53 insertions(+), 14 deletions(-)
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..6e22526546935 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,18 @@ 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 +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 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 +437,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");
}
}
}
>From 7b9401860572f0d73783345e7452b073bf83a16d Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Wed, 11 Jun 2025 11:45:14 +0530
Subject: [PATCH 2/3] fixup! Minor changes
Change-Id: Iba6ea3a80163c9553dd821668ebe6409302da552
---
llvm/utils/TableGen/CompressInstEmitter.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 6e22526546935..515d27c04158a 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -124,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
+ 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);
@@ -220,18 +220,16 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
// are represented.
unsigned TiedCount = 0;
unsigned OpNo = 0;
- if (IsSourceInst) {
+ 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) {
+ if (IsSourceInst)
SourceLastTiedOp = OpNo;
- }
++OpNo;
++TiedCount;
continue;
>From 9b5fa4eedaf98b113eac4e9683f0c1835f2b1a87 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Wed, 18 Jun 2025 12:47:59 +0530
Subject: [PATCH 3/3] fixup! Address Comments
Change-Id: I190e56d22e85e8ae5b07931840f879b3e8afb4fe
---
llvm/utils/TableGen/CompressInstEmitter.cpp | 27 ++++++++++++---------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 515d27c04158a..2dfeea36e2134 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -124,10 +124,10 @@ 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);
+ 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,
@@ -144,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) {}
@@ -207,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;
@@ -221,7 +223,7 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
unsigned TiedCount = 0;
unsigned OpNo = 0;
if (IsSourceInst)
- SourceLastTiedOp = std::numeric_limits<unsigned int>::max();
+ *SourceLastTiedOpPtr = std::numeric_limits<unsigned int>::max();
for (const auto &Opnd : Inst.Operands) {
int TiedOpIdx = Opnd.getTiedRegister();
if (-1 != TiedOpIdx) {
@@ -229,7 +231,7 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
OperandMap[OpNo].Kind = OperandMap[TiedOpIdx].Kind;
OperandMap[OpNo].Data = OperandMap[TiedOpIdx].Data;
if (IsSourceInst)
- SourceLastTiedOp = OpNo;
+ *SourceLastTiedOpPtr = OpNo;
++OpNo;
++TiedCount;
continue;
@@ -308,7 +310,7 @@ static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
if (Dag->getNumArgs() == NumMIOperands)
return true;
- // Source instructions are non compressed instructions and have atmost one
+ // Source instructions are non compressed instructions and have at most one
// tied operand.
if (IsSource && (SourceInstTiedOpCount >= 2))
PrintFatalError(Inst.TheDef->getLoc(),
@@ -394,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;
@@ -505,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;
@@ -521,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