Skip to content

Commit 408e550

Browse files
authored
[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.
1 parent 9ee55e7 commit 408e550

File tree

3 files changed

+63
-21
lines changed

3 files changed

+63
-21
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,11 @@ def : CompressPat<(QC_E_ADDI X2, X2, simm10_lsb0000nonzero:$imm),
15701570
(C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
15711571
} // let isCompressOnly = true, Predicates = [HasVendorXqcilia, IsRV32]
15721572

1573+
let Predicates = [HasVendorXqciac, IsRV32] in {
1574+
def : CompressPat<(QC_MULIADD GPRC:$rd, GPRC:$rs1, uimm5:$imm5),
1575+
(QC_C_MULIADD GPRC:$rd, GPRC:$rs1, uimm5:$imm5)>;
1576+
}
1577+
15731578
let isCompressOnly = true, Predicates = [HasVendorXqcibi, IsRV32] in {
15741579
def : CompressPat<(QC_E_BEQI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12),
15751580
(QC_BEQI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;

llvm/test/MC/RISCV/xqciac-valid.s

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
# Xqciac - Qualcomm uC Load-Store Address Calculation Extension
22
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -M no-aliases -show-encoding \
3-
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
3+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST,CHECK-NOALIAS %s
44
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \
55
# RUN: | llvm-objdump --mattr=+experimental-xqciac -M no-aliases --no-print-imm-hex -d - \
66
# RUN: | FileCheck -check-prefix=CHECK-INST %s
77
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -show-encoding \
8-
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
8+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST,CHECK-ALIAS %s
99
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \
1010
# RUN: | llvm-objdump --mattr=+experimental-xqciac --no-print-imm-hex -d - \
1111
# RUN: | FileCheck -check-prefix=CHECK-INST %s
1212

13-
# CHECK-INST: qc.c.muliadd a0, a1, 0
13+
# CHECK-NOALIAS: qc.c.muliadd a0, a1, 0
14+
# CHECK-ALIAS: qc.muliadd a0, a1, 0
1415
# CHECK-ENC: encoding: [0x8a,0x21]
1516
qc.c.muliadd x10, x11, 0
1617

17-
# CHECK-INST: qc.c.muliadd a0, a1, 31
18+
# CHECK-NOALIAS: qc.c.muliadd a0, a1, 31
19+
# CHECK-ALIAS: qc.muliadd a0, a1, 31
1820
# CHECK-ENC: encoding: [0xea,0x3d]
1921
qc.c.muliadd x10, x11, 31
2022

21-
# CHECK-INST: qc.c.muliadd a0, a1, 16
23+
# CHECK-NOALIAS: qc.c.muliadd a0, a1, 16
24+
# CHECK-ALIAS: qc.muliadd a0, a1, 16
2225
# CHECK-ENC: encoding: [0xaa,0x21]
2326
qc.c.muliadd x10, x11, 16
2427

@@ -47,3 +50,11 @@ qc.shladd x10, x11, x12, 4
4750
# CHECK-INST: qc.shladd a0, a1, a2, 31
4851
# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x7e]
4952
qc.shladd x10, x11, x12, 31
53+
54+
# Check that compress pattern for qc.muliadd works
55+
56+
# CHECK-NOALIAS: qc.c.muliadd a0, a1, 16
57+
# CHECK-ALIAS: qc.muliadd a0, a1, 16
58+
# CHECK-ENC: encoding: [0xaa,0x21]
59+
qc.muliadd x10, x11, 16
60+

llvm/utils/TableGen/CompressInstEmitter.cpp

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include "llvm/TableGen/Error.h"
7676
#include "llvm/TableGen/Record.h"
7777
#include "llvm/TableGen/TableGenBackend.h"
78+
#include <limits>
7879
#include <set>
7980
#include <vector>
8081
using namespace llvm;
@@ -123,10 +124,10 @@ class CompressInstEmitter {
123124
const RecordKeeper &Records;
124125
const CodeGenTarget Target;
125126
std::vector<CompressPat> CompressPatterns;
126-
127127
void addDagOperandMapping(const Record *Rec, const DagInit *Dag,
128128
const CodeGenInstruction &Inst,
129-
IndexedMap<OpData> &OperandMap, bool IsSourceInst);
129+
IndexedMap<OpData> &OperandMap, bool IsSourceInst,
130+
unsigned *SourceLastTiedOpPtr);
130131
void evaluateCompressPat(const Record *Compress);
131132
void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType);
132133
bool validateTypes(const Record *DagOpType, const Record *InstOpType,
@@ -143,7 +144,8 @@ class CompressInstEmitter {
143144
IndexedMap<OpData> &SourceOperandMap,
144145
IndexedMap<OpData> &DestOperandMap,
145146
StringMap<unsigned> &SourceOperands,
146-
const CodeGenInstruction &DestInst);
147+
const CodeGenInstruction &DestInst,
148+
unsigned SourceLastTiedOp);
147149

148150
public:
149151
CompressInstEmitter(const RecordKeeper &R) : Records(R), Target(R) {}
@@ -206,7 +208,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
206208
const DagInit *Dag,
207209
const CodeGenInstruction &Inst,
208210
IndexedMap<OpData> &OperandMap,
209-
bool IsSourceInst) {
211+
bool IsSourceInst,
212+
unsigned *SourceLastTiedOpPtr) {
210213
unsigned NumMIOperands = 0;
211214
for (const auto &Op : Inst.Operands)
212215
NumMIOperands += Op.MINumOperands;
@@ -219,12 +222,16 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
219222
// are represented.
220223
unsigned TiedCount = 0;
221224
unsigned OpNo = 0;
225+
if (IsSourceInst)
226+
*SourceLastTiedOpPtr = std::numeric_limits<unsigned int>::max();
222227
for (const auto &Opnd : Inst.Operands) {
223228
int TiedOpIdx = Opnd.getTiedRegister();
224229
if (-1 != TiedOpIdx) {
225230
// Set the entry in OperandMap for the tied operand we're skipping.
226231
OperandMap[OpNo].Kind = OperandMap[TiedOpIdx].Kind;
227232
OperandMap[OpNo].Data = OperandMap[TiedOpIdx].Data;
233+
if (IsSourceInst)
234+
*SourceLastTiedOpPtr = OpNo;
228235
++OpNo;
229236
++TiedCount;
230237
continue;
@@ -289,15 +296,23 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
289296
static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
290297
bool IsSource) {
291298
unsigned NumMIOperands = 0;
292-
for (const auto &Op : Inst.Operands)
299+
300+
// Use this to count number of tied Operands in Source Inst in this function.
301+
// This counter is required here to error out when there is a Source
302+
// Inst with two or more tied operands.
303+
unsigned SourceInstTiedOpCount = 0;
304+
for (const auto &Op : Inst.Operands) {
293305
NumMIOperands += Op.MINumOperands;
306+
if (Op.getTiedRegister() != -1)
307+
SourceInstTiedOpCount++;
308+
}
294309

295310
if (Dag->getNumArgs() == NumMIOperands)
296311
return true;
297312

298-
// Source instructions are non compressed instructions and don't have tied
299-
// operands.
300-
if (IsSource)
313+
// Source instructions are non compressed instructions and have at most one
314+
// tied operand.
315+
if (IsSource && (SourceInstTiedOpCount >= 2))
301316
PrintFatalError(Inst.TheDef->getLoc(),
302317
"Input operands for Inst '" + Inst.TheDef->getName() +
303318
"' and input Dag operand count mismatch");
@@ -381,7 +396,8 @@ void CompressInstEmitter::createDagOperandMapping(
381396
void CompressInstEmitter::createInstOperandMapping(
382397
const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
383398
IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
384-
StringMap<unsigned> &SourceOperands, const CodeGenInstruction &DestInst) {
399+
StringMap<unsigned> &SourceOperands, const CodeGenInstruction &DestInst,
400+
unsigned SourceLastTiedOp) {
385401
// TiedCount keeps track of the number of operands skipped in Inst
386402
// operands list to get to the corresponding Dag operand.
387403
unsigned TiedCount = 0;
@@ -422,10 +438,18 @@ void CompressInstEmitter::createInstOperandMapping(
422438
assert(DestDag->getArgNameStr(DagArgIdx) ==
423439
SourceDag->getArgNameStr(SourceOp->getValue()) &&
424440
"Incorrect operand mapping detected!\n");
425-
DestOperandMap[OpNo].Data.Operand = SourceOp->getValue();
426-
SourceOperandMap[SourceOp->getValue()].Data.Operand = OpNo;
427-
LLVM_DEBUG(dbgs() << " " << SourceOp->getValue() << " ====> " << OpNo
428-
<< "\n");
441+
442+
// Following four lines ensure the correct handling of a single tied
443+
// operand in the Source Inst. SourceDagOp points to the position of
444+
// appropriate Dag argument which is not correct in presence of tied
445+
// operand in the Source Inst and must be incremented by 1 to reflect
446+
// correct position of the operand in Source Inst
447+
unsigned SourceDagOp = SourceOp->getValue();
448+
if (SourceDagOp >= SourceLastTiedOp)
449+
SourceDagOp++;
450+
DestOperandMap[OpNo].Data.Operand = SourceDagOp;
451+
SourceOperandMap[SourceDagOp].Data.Operand = OpNo;
452+
LLVM_DEBUG(dbgs() << " " << SourceDagOp << " ====> " << OpNo << "\n");
429453
}
430454
}
431455
}
@@ -484,23 +508,25 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
484508
// Fill the mapping from the source to destination instructions.
485509

486510
IndexedMap<OpData> SourceOperandMap;
511+
unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
487512
// Create a mapping between source Dag operands and source Inst operands.
488513
addDagOperandMapping(Rec, SourceDag, SourceInst, SourceOperandMap,
489-
/*IsSourceInst*/ true);
514+
/*IsSourceInst*/ true, &SourceLastTiedOp);
490515

491516
IndexedMap<OpData> DestOperandMap;
492517
// Create a mapping between destination Dag operands and destination Inst
493518
// operands.
494519
addDagOperandMapping(Rec, DestDag, DestInst, DestOperandMap,
495-
/*IsSourceInst*/ false);
520+
/*IsSourceInst*/ false, nullptr);
496521

497522
StringMap<unsigned> SourceOperands;
498523
StringMap<unsigned> DestOperands;
499524
createDagOperandMapping(Rec, SourceOperands, DestOperands, SourceDag, DestDag,
500525
SourceOperandMap);
501526
// Create operand mapping between the source and destination instructions.
502527
createInstOperandMapping(Rec, SourceDag, DestDag, SourceOperandMap,
503-
DestOperandMap, SourceOperands, DestInst);
528+
DestOperandMap, SourceOperands, DestInst,
529+
SourceLastTiedOp);
504530

505531
// Get the target features for the CompressPat.
506532
std::vector<const Record *> PatReqFeatures;

0 commit comments

Comments
 (0)