Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit d8bb9ec

Browse files
author
Artem Tamazov
committed
[AMDGPU][llvm-mc] Fixes to support buffer atomics.
Fixes for MUBUF_Atomic instructions to make operand list valid: - For RTN insns, make a copy of $vdata_in operand as $vdata. - Do not add operand for GLC, it is hardcoded and comes as a token. Workaround to avoid adding multiple default optional operands. Tests added. Differential Revision: http://reviews.llvm.org/D20257 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270049 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 785d7f7 commit d8bb9ec

File tree

5 files changed

+413
-12
lines changed

5 files changed

+413
-12
lines changed

lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ const char* const OpGsSymbolic[] = {
8787

8888
using namespace llvm;
8989

90+
// In some cases (e.g. buffer atomic instructions) MatchOperandParserImpl()
91+
// may invoke tryCustomParseOperand() multiple times with the same MCK value.
92+
// That leads to adding of the same "default" operand multiple times in a row,
93+
// which is wrong. The workaround adds only the 1st default operand, while for
94+
// the rest the "dummy" operands being added. The reason for dummies is that if
95+
// we just skip adding an operand, then parser would get stuck in endless loop.
96+
// Dummies shall be removed prior matching & emitting MCInsts.
97+
//
98+
// Comment out this macro to disable the workaround.
99+
#define WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
100+
90101
namespace {
91102

92103
struct OptionalOperand;
@@ -99,6 +110,9 @@ class AMDGPUOperand : public MCParsedAsmOperand {
99110
Immediate,
100111
Register,
101112
Expression
113+
#ifdef WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
114+
,Dummy
115+
#endif
102116
} Kind;
103117

104118
SMLoc StartLoc, EndLoc;
@@ -204,6 +218,12 @@ class AMDGPUOperand : public MCParsedAsmOperand {
204218
}
205219
}
206220

221+
#ifdef WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
222+
bool isDummy() const {
223+
return Kind == Dummy;
224+
}
225+
#endif
226+
207227
bool isToken() const override {
208228
return Kind == Token;
209229
}
@@ -440,6 +460,11 @@ class AMDGPUOperand : public MCParsedAsmOperand {
440460
case Expression:
441461
OS << "<expr " << *Expr << '>';
442462
break;
463+
#ifdef WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
464+
case Dummy:
465+
OS << "<dummy>";
466+
break;
467+
#endif
443468
}
444469
}
445470

@@ -490,6 +515,15 @@ class AMDGPUOperand : public MCParsedAsmOperand {
490515
return Op;
491516
}
492517

518+
#ifdef WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
519+
static AMDGPUOperand::Ptr CreateDummy(SMLoc S) {
520+
auto Op = llvm::make_unique<AMDGPUOperand>(Dummy);
521+
Op->StartLoc = S;
522+
Op->EndLoc = S;
523+
return Op;
524+
}
525+
#endif
526+
493527
bool isSWaitCnt() const;
494528
bool isHwreg() const;
495529
bool isSendMsg() const;
@@ -545,6 +579,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
545579
bool ParseSectionDirectiveHSARodataReadonlyAgent();
546580
bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth, RegisterKind RegKind, unsigned Reg1, unsigned RegNum);
547581
bool ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg, unsigned& RegNum, unsigned& RegWidth);
582+
void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands, bool IsAtomic, bool IsAtomicReturn);
548583

549584
public:
550585
enum AMDGPUMatchResultTy {
@@ -633,8 +668,9 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
633668
OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
634669
AMDGPUOperand::Ptr defaultHwreg() const;
635670

636-
637-
void cvtMubuf(MCInst &Inst, const OperandVector &Operands);
671+
void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
672+
void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); }
673+
void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); }
638674
AMDGPUOperand::Ptr defaultMubufOffset() const;
639675
AMDGPUOperand::Ptr defaultGLC() const;
640676
AMDGPUOperand::Ptr defaultSLC() const;
@@ -926,6 +962,17 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
926962
bool MatchingInlineAsm) {
927963
MCInst Inst;
928964

965+
#ifdef WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
966+
// Remove dummies prior matching. Iterate backwards becase vector::erase()
967+
// invalidates all iterators which refer after erase point.
968+
for (auto I = Operands.rbegin(), E = Operands.rend(); I != E; ) {
969+
auto X = I++;
970+
if (static_cast<AMDGPUOperand*>(X->get())->isDummy()) {
971+
Operands.erase(X.base() -1);
972+
}
973+
}
974+
#endif
975+
929976
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
930977
default: break;
931978
case Match_Success:
@@ -1430,6 +1477,25 @@ AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
14301477
}
14311478

14321479
Operands.push_back(AMDGPUOperand::CreateImm(Value, S, ImmTy));
1480+
1481+
#ifdef WORKAROUND_USE_DUMMY_OPERANDS_INSTEAD_MUTIPLE_DEFAULT_OPERANDS
1482+
if (Value == Default && AddDefault) {
1483+
// Reverse lookup in previously added operands (skip just added one)
1484+
// for the first non-dummy operand. If it is of the same type,
1485+
// then replace just added default operand with dummy.
1486+
for (auto I = Operands.rbegin(), E = Operands.rend(); I != E; ++I) {
1487+
if (I == Operands.rbegin())
1488+
continue;
1489+
if (static_cast<AMDGPUOperand*>(I->get())->isDummy())
1490+
continue;
1491+
if (static_cast<AMDGPUOperand*>(I->get())->isImmTy(ImmTy)) {
1492+
Operands.pop_back();
1493+
Operands.push_back(AMDGPUOperand::CreateDummy(S)); // invalidates iterators
1494+
break;
1495+
}
1496+
}
1497+
}
1498+
#endif
14331499
return MatchOperand_Success;
14341500
}
14351501

@@ -2047,9 +2113,11 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultTFE() const {
20472113
return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyTFE);
20482114
}
20492115

2050-
void AMDGPUAsmParser::cvtMubuf(MCInst &Inst,
2051-
const OperandVector &Operands) {
2116+
void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
2117+
const OperandVector &Operands,
2118+
bool IsAtomic, bool IsAtomicReturn) {
20522119
OptionalImmIndexMap OptionalIdx;
2120+
assert(IsAtomicReturn ? IsAtomic : true);
20532121

20542122
for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
20552123
AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
@@ -2077,8 +2145,16 @@ void AMDGPUAsmParser::cvtMubuf(MCInst &Inst,
20772145
OptionalIdx[Op.getImmTy()] = i;
20782146
}
20792147

2148+
// Copy $vdata_in operand and insert as $vdata for MUBUF_Atomic RTN insns.
2149+
if (IsAtomicReturn) {
2150+
MCInst::iterator I = Inst.begin(); // $vdata_in is always at the beginning.
2151+
Inst.insert(I, *I);
2152+
}
2153+
20802154
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
2081-
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
2155+
if (!IsAtomic) { // glc is hard-coded.
2156+
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
2157+
}
20822158
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
20832159
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
20842160
}

lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2836,7 +2836,7 @@ multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
28362836
let mayStore = 1, mayLoad = 1, hasPostISelHook = 1, hasSideEffects = 1 in {
28372837

28382838
// No return variants
2839-
let glc = 0 in {
2839+
let glc = 0, AsmMatchConverter = "cvtMubufAtomic" in {
28402840

28412841
defm _ADDR64 : MUBUFAtomicAddr64_m <
28422842
op, name#"_addr64", (outs),
@@ -2883,13 +2883,14 @@ multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
28832883

28842884
// Variant that return values
28852885
let glc = 1, Constraints = "$vdata = $vdata_in",
2886+
AsmMatchConverter = "cvtMubufAtomicReturn",
28862887
DisableEncoding = "$vdata_in" in {
28872888

28882889
defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
28892890
op, name#"_rtn_addr64", (outs rc:$vdata),
28902891
(ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc,
28912892
SCSrc_32:$soffset, offset:$offset, slc:$slc),
2892-
name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2893+
name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset glc$slc",
28932894
[(set vt:$vdata,
28942895
(atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
28952896
i16:$offset, i1:$slc), vt:$vdata_in))], 1
@@ -2899,7 +2900,7 @@ multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
28992900
op, name#"_rtn_offset", (outs rc:$vdata),
29002901
(ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
29012902
offset:$offset, slc:$slc),
2902-
name#" $vdata, off, $srsrc, $soffset $offset glc$slc",
2903+
name#" $vdata, off, $srsrc, $soffset$offset glc$slc",
29032904
[(set vt:$vdata,
29042905
(atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
29052906
i1:$slc), vt:$vdata_in))], 1
@@ -2910,7 +2911,7 @@ multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
29102911
op, name#"_rtn_offen", (outs rc:$vdata),
29112912
(ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
29122913
offset:$offset, slc:$slc),
2913-
name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#" glc"#"$slc",
2914+
name#" $vdata, $vaddr, $srsrc, $soffset offen$offset glc$slc",
29142915
[], 1
29152916
>;
29162917
}
@@ -2920,7 +2921,7 @@ multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
29202921
op, name#"_rtn_idxen", (outs rc:$vdata),
29212922
(ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
29222923
offset:$offset, slc:$slc),
2923-
name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#" glc"#"$slc",
2924+
name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset glc$slc",
29242925
[], 1
29252926
>;
29262927
}
@@ -2930,7 +2931,7 @@ multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
29302931
op, name#"_rtn_bothen", (outs rc:$vdata),
29312932
(ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
29322933
offset:$offset, slc:$slc),
2933-
name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#" glc"#"$slc",
2934+
name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset glc$slc",
29342935
[], 1
29352936
>;
29362937
}

0 commit comments

Comments
 (0)