Skip to content

Commit d6e1a94

Browse files
committedFeb 21, 2018
[AMDGPU][MC] Added lds support for MUBUF instructions
See bug 28234: https://bugs.llvm.org/show_bug.cgi?id=28234 Differential Revision: https://reviews.llvm.org/D43472 Reviewers: vpykhtin, artem.tamazov, arsenm llvm-svn: 325676
1 parent b21518a commit d6e1a94

File tree

6 files changed

+280
-57
lines changed

6 files changed

+280
-57
lines changed
 

‎llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

+28-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
1313
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
1414
#include "SIDefines.h"
15+
#include "SIInstrInfo.h"
1516
#include "Utils/AMDGPUAsmUtils.h"
1617
#include "Utils/AMDGPUBaseInfo.h"
1718
#include "Utils/AMDKernelCodeTUtils.h"
@@ -128,6 +129,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
128129
enum ImmTy {
129130
ImmTyNone,
130131
ImmTyGDS,
132+
ImmTyLDS,
131133
ImmTyOffen,
132134
ImmTyIdxen,
133135
ImmTyAddr64,
@@ -303,6 +305,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
303305
bool isOffsetU12() const { return (isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset)) && isUInt<12>(getImm()); }
304306
bool isOffsetS13() const { return (isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset)) && isInt<13>(getImm()); }
305307
bool isGDS() const { return isImmTy(ImmTyGDS); }
308+
bool isLDS() const { return isImmTy(ImmTyLDS); }
306309
bool isGLC() const { return isImmTy(ImmTyGLC); }
307310
bool isSLC() const { return isImmTy(ImmTySLC); }
308311
bool isTFE() const { return isImmTy(ImmTyTFE); }
@@ -649,6 +652,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
649652
switch (Type) {
650653
case ImmTyNone: OS << "None"; break;
651654
case ImmTyGDS: OS << "GDS"; break;
655+
case ImmTyLDS: OS << "LDS"; break;
652656
case ImmTyOffen: OS << "Offen"; break;
653657
case ImmTyIdxen: OS << "Idxen"; break;
654658
case ImmTyAddr64: OS << "Addr64"; break;
@@ -4078,6 +4082,7 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultTFE() const {
40784082
void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
40794083
const OperandVector &Operands,
40804084
bool IsAtomic, bool IsAtomicReturn) {
4085+
bool HasLdsModifier = false;
40814086
OptionalImmIndexMap OptionalIdx;
40824087
assert(IsAtomicReturn ? IsAtomic : true);
40834088

@@ -4096,6 +4101,8 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
40964101
continue;
40974102
}
40984103

4104+
HasLdsModifier = Op.isLDS();
4105+
40994106
// Handle tokens like 'offen' which are sometimes hard-coded into the
41004107
// asm string. There are no MCInst operands for these.
41014108
if (Op.isToken()) {
@@ -4107,6 +4114,20 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
41074114
OptionalIdx[Op.getImmTy()] = i;
41084115
}
41094116

4117+
// This is a workaround for an llvm quirk which may result in an
4118+
// incorrect instruction selection. Lds and non-lds versions of
4119+
// MUBUF instructions are identical except that lds versions
4120+
// have mandatory 'lds' modifier. However this modifier follows
4121+
// optional modifiers and llvm asm matcher regards this 'lds'
4122+
// modifier as an optional one. As a result, an lds version
4123+
// of opcode may be selected even if it has no 'lds' modifier.
4124+
if (!HasLdsModifier) {
4125+
int NoLdsOpcode = AMDGPU::getMUBUFNoLdsInst(Inst.getOpcode());
4126+
if (NoLdsOpcode != -1) { // Got lds version - correct it.
4127+
Inst.setOpcode(NoLdsOpcode);
4128+
}
4129+
}
4130+
41104131
// Copy $vdata_in operand and insert as $vdata for MUBUF_Atomic RTN insns.
41114132
if (IsAtomicReturn) {
41124133
MCInst::iterator I = Inst.begin(); // $vdata_in is always at the beginning.
@@ -4118,7 +4139,10 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
41184139
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
41194140
}
41204141
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
4121-
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
4142+
4143+
if (!HasLdsModifier) { // tfe is not legal with lds opcodes
4144+
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
4145+
}
41224146
}
41234147

41244148
void AMDGPUAsmParser::cvtMtbuf(MCInst &Inst, const OperandVector &Operands) {
@@ -4312,6 +4336,7 @@ static const OptionalOperand AMDGPUOptionalOperandTable[] = {
43124336
{"offset0", AMDGPUOperand::ImmTyOffset0, false, nullptr},
43134337
{"offset1", AMDGPUOperand::ImmTyOffset1, false, nullptr},
43144338
{"gds", AMDGPUOperand::ImmTyGDS, true, nullptr},
4339+
{"lds", AMDGPUOperand::ImmTyLDS, true, nullptr},
43154340
{"offset", AMDGPUOperand::ImmTyOffset, false, nullptr},
43164341
{"inst_offset", AMDGPUOperand::ImmTyInstOffset, false, nullptr},
43174342
{"dfmt", AMDGPUOperand::ImmTyDFMT, false, nullptr},
@@ -5022,6 +5047,8 @@ unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
50225047
return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
50235048
case MCK_gds:
50245049
return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
5050+
case MCK_lds:
5051+
return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
50255052
case MCK_glc:
50265053
return Operand.isGLC() ? Match_Success : Match_InvalidOperand;
50275054
case MCK_d16:

0 commit comments

Comments
 (0)
Please sign in to comment.