Skip to content

Commit 0f5ebbc

Browse files
committed
[AMDGPU][MC] Added flag to identify VOP instructions which have a single variant
By convention, VOP1/2/C instructions which can be promoted to VOP3 have _e32 suffix while promoted instructions have _e64 suffix. Instructions which have a single variant should have no _e32/_e64 suffix. Unfortunately there was no simple way to identify single variant instructions - it was implemented by a hack. See bug https://bugs.llvm.org/show_bug.cgi?id=39086. This fix simplifies handling of single VOP instructions by adding a dedicated flag. Differential Revision: https://reviews.llvm.org/D99408
1 parent 6be8662 commit 0f5ebbc

File tree

9 files changed

+92
-54
lines changed

9 files changed

+92
-54
lines changed

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -362,22 +362,30 @@ void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
362362
}
363363

364364
void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
365-
const MCSubtargetInfo &STI, raw_ostream &O) {
365+
const MCSubtargetInfo &STI,
366+
raw_ostream &O) {
367+
auto Opcode = MI->getOpcode();
368+
auto Flags = MII.get(Opcode).TSFlags;
369+
366370
if (OpNo == 0) {
367-
if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
368-
O << "_e64 ";
369-
else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
370-
O << "_dpp ";
371-
else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
372-
O << "_sdwa ";
373-
else
374-
O << "_e32 ";
371+
if (Flags & SIInstrFlags::VOP3) {
372+
if (!getVOP3IsSingle(Opcode))
373+
O << "_e64";
374+
} else if (Flags & SIInstrFlags::DPP) {
375+
O << "_dpp";
376+
} else if (Flags & SIInstrFlags::SDWA) {
377+
O << "_sdwa";
378+
} else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
379+
((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode))) {
380+
O << "_e32";
381+
}
382+
O << " ";
375383
}
376384

377385
printOperand(MI, OpNo, STI, O);
378386

379387
// Print default vcc/vcc_lo operand.
380-
switch (MI->getOpcode()) {
388+
switch (Opcode) {
381389
default: break;
382390

383391
case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:

llvm/lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,7 @@ class getAsm64 <bit HasDst, int NumSrcArgs, bit HasIntClamp, bit HasModifiers,
18601860
// instruction.
18611861
class getAsmVOP3P <bit HasDst, int NumSrcArgs, bit HasModifiers,
18621862
bit HasClamp, ValueType DstVT = i32> {
1863-
string dst = " $vdst";
1863+
string dst = "$vdst";
18641864
string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
18651865
string src1 = !if(!eq(NumSrcArgs, 1), "",
18661866
!if(!eq(NumSrcArgs, 2), " $src1",
@@ -1881,7 +1881,7 @@ class getAsmVOP3OpSel <int NumSrcArgs,
18811881
bit Src0HasMods,
18821882
bit Src1HasMods,
18831883
bit Src2HasMods> {
1884-
string dst = " $vdst";
1884+
string dst = "$vdst";
18851885

18861886
string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
18871887
string isrc1 = !if(!eq(NumSrcArgs, 1), "",
@@ -2147,6 +2147,7 @@ class VOPProfile <list<ValueType> _ArgVT, bit _EnableF32SrcMods = 0,
21472147

21482148
field bit IsMAI = 0;
21492149
field bit IsDOT = 0;
2150+
field bit IsSingle = 0;
21502151

21512152
field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods);
21522153
field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods);

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,23 @@ struct SMInfo {
178178
bool IsBuffer;
179179
};
180180

181+
struct VOPInfo {
182+
uint16_t Opcode;
183+
bool IsSingle;
184+
};
185+
181186
#define GET_MTBUFInfoTable_DECL
182187
#define GET_MTBUFInfoTable_IMPL
183188
#define GET_MUBUFInfoTable_DECL
184189
#define GET_MUBUFInfoTable_IMPL
185190
#define GET_SMInfoTable_DECL
186191
#define GET_SMInfoTable_IMPL
192+
#define GET_VOP1InfoTable_DECL
193+
#define GET_VOP1InfoTable_IMPL
194+
#define GET_VOP2InfoTable_DECL
195+
#define GET_VOP2InfoTable_IMPL
196+
#define GET_VOP3InfoTable_DECL
197+
#define GET_VOP3InfoTable_IMPL
187198
#include "AMDGPUGenSearchableTables.inc"
188199

189200
int getMTBUFBaseOpcode(unsigned Opc) {
@@ -251,6 +262,21 @@ bool getSMEMIsBuffer(unsigned Opc) {
251262
return Info ? Info->IsBuffer : false;
252263
}
253264

265+
bool getVOP1IsSingle(unsigned Opc) {
266+
const VOPInfo *Info = getVOP1OpcodeHelper(Opc);
267+
return Info ? Info->IsSingle : false;
268+
}
269+
270+
bool getVOP2IsSingle(unsigned Opc) {
271+
const VOPInfo *Info = getVOP2OpcodeHelper(Opc);
272+
return Info ? Info->IsSingle : false;
273+
}
274+
275+
bool getVOP3IsSingle(unsigned Opc) {
276+
const VOPInfo *Info = getVOP3OpcodeHelper(Opc);
277+
return Info ? Info->IsSingle : false;
278+
}
279+
254280
// Wrapper for Tablegen'd function. enum Subtarget is not defined in any
255281
// header files, so we need to wrap it in a function that takes unsigned
256282
// instead.

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,15 @@ bool getMUBUFHasSoffset(unsigned Opc);
397397
LLVM_READONLY
398398
bool getSMEMIsBuffer(unsigned Opc);
399399

400+
LLVM_READONLY
401+
bool getVOP1IsSingle(unsigned Opc);
402+
403+
LLVM_READONLY
404+
bool getVOP2IsSingle(unsigned Opc);
405+
406+
LLVM_READONLY
407+
bool getVOP3IsSingle(unsigned Opc);
408+
400409
LLVM_READONLY
401410
const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t BitsPerComp,
402411
uint8_t NumComponents,

llvm/lib/Target/AMDGPU/VOP1Instructions.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class VOP1_Pseudo <string opName, VOPProfile P, list<dag> pattern=[], bit VOP1On
6060
}
6161

6262
class VOP1_Real <VOP1_Pseudo ps, int EncodingFamily> :
63+
VOP_Real <ps>,
6364
InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
6465
SIMCInstr <ps.PseudoInstr, EncodingFamily> {
6566

llvm/lib/Target/AMDGPU/VOP2Instructions.td

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class VOP2_Pseudo <string opName, VOPProfile P, list<dag> pattern=[], string suf
8181
}
8282

8383
class VOP2_Real <VOP2_Pseudo ps, int EncodingFamily> :
84+
VOP_Real <ps>,
8485
InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
8586
SIMCInstr <ps.PseudoInstr, EncodingFamily> {
8687

@@ -268,10 +269,9 @@ class VOP_MADAK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> {
268269
(ins VCSrc_f32:$src0, VGPR_32:$src1, ImmOpType:$imm),
269270
(ins VCSrc_f16:$src0, VGPR_32:$src1, ImmOpType:$imm));
270271
field bit HasExt = 0;
272+
let IsSingle = 1;
271273

272-
// Hack to stop printing _e64
273-
let DstRC = RegisterOperand<VGPR_32>;
274-
field string Asm32 = " $vdst, $src0, $src1, $imm";
274+
field string Asm32 = "$vdst, $src0, $src1, $imm";
275275
}
276276

277277
def VOP_MADAK_F16 : VOP_MADAK <f16>;
@@ -281,10 +281,9 @@ class VOP_MADMK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> {
281281
field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm);
282282
field dag Ins32 = (ins VCSrc_f32:$src0, ImmOpType:$imm, VGPR_32:$src1);
283283
field bit HasExt = 0;
284+
let IsSingle = 1;
284285

285-
// Hack to stop printing _e64
286-
let DstRC = RegisterOperand<VGPR_32>;
287-
field string Asm32 = " $vdst, $src0, $imm, $src1";
286+
field string Asm32 = "$vdst, $src0, $imm, $src1";
288287
}
289288

290289
def VOP_MADMK_F16 : VOP_MADMK <f16>;
@@ -1406,10 +1405,7 @@ multiclass VOP2_Real_e64only_vi <bits<10> op> {
14061405
def _e64_vi :
14071406
VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
14081407
VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> {
1409-
// Hack to stop printing _e64
1410-
VOP3_Pseudo ps = !cast<VOP3_Pseudo>(NAME#"_e64");
1411-
let OutOperandList = (outs VGPR_32:$vdst);
1412-
let AsmString = ps.Mnemonic # " " # ps.AsmOperands;
1408+
let IsSingle = 1;
14131409
}
14141410
}
14151411

llvm/lib/Target/AMDGPU/VOP3Instructions.td

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -184,47 +184,24 @@ class VOP3_Profile<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProf
184184
let IsPacked = !if(Features.IsPacked, 1, P.IsPacked);
185185

186186
let HasModifiers = !if(Features.IsMAI, 0, !or(Features.IsPacked, P.HasModifiers));
187-
188-
// FIXME: Hack to stop printing _e64
189-
let Outs64 = (outs DstRC.RegClass:$vdst);
190-
let Asm64 =
191-
" " # !if(Features.HasOpSel,
192-
getAsmVOP3OpSel<NumSrcArgs,
193-
HasIntClamp,
194-
P.HasOMod,
195-
HasSrc0FloatMods,
196-
HasSrc1FloatMods,
197-
HasSrc2FloatMods>.ret,
198-
!if(Features.HasClamp,
199-
getAsm64<HasDst, NumSrcArgs, HasIntClamp,
200-
HasModifiers, HasOMod, DstVT>.ret,
201-
P.Asm64));
202-
let NeedPatGen = P.NeedPatGen;
187+
let IsSingle = 1;
203188
}
204189

205190
class VOP3b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, vt]> {
206191
let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
207-
let Asm64 = " $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod";
208-
}
209-
210-
def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32> {
211-
// FIXME: Hack to stop printing _e64
212-
let DstRC = RegisterOperand<VGPR_32>;
192+
let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod";
193+
let IsSingle = 1;
213194
}
214195

215-
def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64> {
216-
// FIXME: Hack to stop printing _e64
217-
let DstRC = RegisterOperand<VReg_64>;
218-
}
196+
def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32>;
197+
def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64>;
219198

220199
def VOP3b_I64_I1_I32_I32_I64 : VOPProfile<[i64, i32, i32, i64]> {
221200
let HasClamp = 1;
222-
223-
// FIXME: Hack to stop printing _e64
224-
let DstRC = RegisterOperand<VReg_64>;
201+
let IsSingle = 1;
225202

226203
let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
227-
let Asm64 = " $vdst, $sdst, $src0, $src1, $src2$clamp";
204+
let Asm64 = "$vdst, $sdst, $src0, $src1, $src2$clamp";
228205
}
229206

230207
//===----------------------------------------------------------------------===//

llvm/lib/Target/AMDGPU/VOP3PInstructions.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class VOP3_VOP3PInst<string OpName, VOPProfile P, bit UseTiedOutput = 0,
4444
let Constraints = !if(UseTiedOutput, "$vdst = $vdst_in", "");
4545
let DisableEncoding = !if(UseTiedOutput, "$vdst_in", "");
4646
let AsmOperands =
47-
" $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$op_sel$op_sel_hi$clamp";
47+
"$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$op_sel$op_sel_hi$clamp";
4848
}
4949

5050
let isCommutable = 1 in {
@@ -377,7 +377,7 @@ class VOPProfileMAI<VOPProfile P, RegisterOperand _SrcRC, RegisterOperand _DstRC
377377
let HasIntClamp = 0;
378378
let HasOMod = 0;
379379
let HasModifiers = 0;
380-
let Asm64 = " $vdst, $src0, $src1, $src2$cbsz$abid$blgp";
380+
let Asm64 = "$vdst, $src0, $src1, $src2$cbsz$abid$blgp";
381381
let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, Src2RC64:$src2, cbsz:$cbsz, abid:$abid, blgp:$blgp);
382382
}
383383

llvm/lib/Target/AMDGPU/VOPInstructions.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,13 @@ class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> :
140140
let VOP3P = 1;
141141
}
142142

143+
class VOP_Real<VOP_Pseudo ps> {
144+
Instruction Opcode = !cast<Instruction>(NAME);
145+
bit IsSingle = ps.Pfl.IsSingle;
146+
}
147+
143148
class VOP3_Real <VOP_Pseudo ps, int EncodingFamily> :
149+
VOP_Real <ps>,
144150
InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
145151
SIMCInstr <ps.PseudoInstr, EncodingFamily> {
146152

@@ -797,3 +803,17 @@ include "VOP1Instructions.td"
797803
include "VOP2Instructions.td"
798804
include "VOP3Instructions.td"
799805
include "VOP3PInstructions.td"
806+
807+
808+
class VOPInfoTable <string Format> : GenericTable {
809+
let FilterClass = Format # "_Real";
810+
let CppTypeName = "VOPInfo";
811+
let Fields = ["Opcode", "IsSingle"];
812+
813+
let PrimaryKey = ["Opcode"];
814+
let PrimaryKeyName = "get" # Format # "OpcodeHelper";
815+
}
816+
817+
def VOP1InfoTable : VOPInfoTable<"VOP1">;
818+
def VOP2InfoTable : VOPInfoTable<"VOP2">;
819+
def VOP3InfoTable : VOPInfoTable<"VOP3">;

0 commit comments

Comments
 (0)