Skip to content

Commit 88effbf

Browse files
authored
[AMDGPU] Do not use 64-bit literals with VOP3* encodings (#156602)
Encoding sometimes uses a 64-bit instead of 32-bit literal because it does not know the signedness of the operand: if the value does not fit in both a 32-bit signed and a 32-bit unsigned then it will use a 64-bit literal for safety. However it should never do this for VOP3 and VOP3P encoded instructions, because these encodings do not allow 64-bit literal operands.
1 parent 018dc1b commit 88effbf

File tree

6 files changed

+90
-86
lines changed

6 files changed

+90
-86
lines changed

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ void AMDGPUInstPrinter::printFP64ImmOperand(const MCInst *MI, unsigned OpNo,
8080
const MCSubtargetInfo &STI,
8181
raw_ostream &O) {
8282
// KIMM64
83+
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
8384
uint64_t Imm = MI->getOperand(OpNo).getImm();
84-
printLiteral64(Imm, STI, O, /*IsFP=*/true);
85+
printLiteral64(Desc, Imm, STI, O, /*IsFP=*/true);
8586
}
8687

8788
void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
@@ -590,7 +591,7 @@ void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
590591
O << formatHex(static_cast<uint64_t>(Imm));
591592
}
592593

593-
void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
594+
void AMDGPUInstPrinter::printImmediate64(const MCInstrDesc &Desc, uint64_t Imm,
594595
const MCSubtargetInfo &STI,
595596
raw_ostream &O, bool IsFP) {
596597
int64_t SImm = static_cast<int64_t>(Imm);
@@ -621,20 +622,23 @@ void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
621622
STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
622623
O << "0.15915494309189532";
623624
else
624-
printLiteral64(Imm, STI, O, IsFP);
625+
printLiteral64(Desc, Imm, STI, O, IsFP);
625626
}
626627

627-
void AMDGPUInstPrinter::printLiteral64(uint64_t Imm, const MCSubtargetInfo &STI,
628+
void AMDGPUInstPrinter::printLiteral64(const MCInstrDesc &Desc, uint64_t Imm,
629+
const MCSubtargetInfo &STI,
628630
raw_ostream &O, bool IsFP) {
629631
// This part needs to align with AMDGPUOperand::addLiteralImmOperand.
632+
bool CanUse64BitLiterals =
633+
STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
634+
!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P));
630635
if (IsFP) {
631-
if (STI.hasFeature(AMDGPU::Feature64BitLiterals) && Lo_32(Imm))
636+
if (CanUse64BitLiterals && Lo_32(Imm))
632637
O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
633638
else
634639
O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
635640
} else {
636-
if (STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
637-
(!isInt<32>(Imm) || !isUInt<32>(Imm)))
641+
if (CanUse64BitLiterals && (!isInt<32>(Imm) || !isUInt<32>(Imm)))
638642
O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
639643
else
640644
O << formatHex(static_cast<uint64_t>(Imm));
@@ -749,12 +753,12 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
749753
break;
750754
case AMDGPU::OPERAND_REG_IMM_INT64:
751755
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
752-
printImmediate64(Op.getImm(), STI, O, false);
756+
printImmediate64(Desc, Op.getImm(), STI, O, false);
753757
break;
754758
case AMDGPU::OPERAND_REG_IMM_FP64:
755759
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
756760
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
757-
printImmediate64(Op.getImm(), STI, O, true);
761+
printImmediate64(Desc, Op.getImm(), STI, O, true);
758762
break;
759763
case AMDGPU::OPERAND_REG_INLINE_C_INT16:
760764
case AMDGPU::OPERAND_REG_IMM_INT16:

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ class AMDGPUInstPrinter : public MCInstPrinter {
8787
raw_ostream &O);
8888
void printImmediate32(uint32_t Imm, const MCSubtargetInfo &STI,
8989
raw_ostream &O);
90-
void printImmediate64(uint64_t Imm, const MCSubtargetInfo &STI,
91-
raw_ostream &O, bool IsFP);
92-
void printLiteral64(uint64_t Imm, const MCSubtargetInfo &STI, raw_ostream &O,
93-
bool IsFP);
90+
void printImmediate64(const MCInstrDesc &Desc, uint64_t Imm,
91+
const MCSubtargetInfo &STI, raw_ostream &O, bool IsFP);
92+
void printLiteral64(const MCInstrDesc &Desc, uint64_t Imm,
93+
const MCSubtargetInfo &STI, raw_ostream &O, bool IsFP);
9494
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
9595
raw_ostream &O);
9696
void printRegularOperand(const MCInst *MI, unsigned OpNo,

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class AMDGPUMCCodeEmitter : public MCCodeEmitter {
8888

8989
/// Encode an fp or int literal.
9090
std::optional<uint64_t>
91-
getLitEncoding(const MCOperand &MO, const MCOperandInfo &OpInfo,
91+
getLitEncoding(const MCInstrDesc &Desc, const MCOperand &MO, unsigned OpNo,
9292
const MCSubtargetInfo &STI,
9393
bool HasMandatoryLiteral = false) const;
9494

@@ -219,8 +219,8 @@ static uint32_t getLit16IntEncoding(uint32_t Val, const MCSubtargetInfo &STI) {
219219
return getLit32Encoding(Val, STI);
220220
}
221221

222-
static uint32_t getLit64Encoding(uint64_t Val, const MCSubtargetInfo &STI,
223-
bool IsFP) {
222+
static uint32_t getLit64Encoding(const MCInstrDesc &Desc, uint64_t Val,
223+
const MCSubtargetInfo &STI, bool IsFP) {
224224
uint32_t IntImm = getIntInlineImmEncoding(static_cast<int64_t>(Val));
225225
if (IntImm != 0)
226226
return IntImm;
@@ -255,20 +255,21 @@ static uint32_t getLit64Encoding(uint64_t Val, const MCSubtargetInfo &STI,
255255

256256
// The rest part needs to align with AMDGPUInstPrinter::printLiteral64.
257257

258+
bool CanUse64BitLiterals =
259+
STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
260+
!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P));
258261
if (IsFP) {
259-
return STI.hasFeature(AMDGPU::Feature64BitLiterals) && Lo_32(Val) ? 254
260-
: 255;
262+
return CanUse64BitLiterals && Lo_32(Val) ? 254 : 255;
261263
}
262264

263-
return STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
264-
(!isInt<32>(Val) || !isUInt<32>(Val))
265-
? 254
266-
: 255;
265+
return CanUse64BitLiterals && (!isInt<32>(Val) || !isUInt<32>(Val)) ? 254
266+
: 255;
267267
}
268268

269269
std::optional<uint64_t> AMDGPUMCCodeEmitter::getLitEncoding(
270-
const MCOperand &MO, const MCOperandInfo &OpInfo,
270+
const MCInstrDesc &Desc, const MCOperand &MO, unsigned OpNo,
271271
const MCSubtargetInfo &STI, bool HasMandatoryLiteral) const {
272+
const MCOperandInfo &OpInfo = Desc.operands()[OpNo];
272273
int64_t Imm;
273274
if (MO.isExpr()) {
274275
if (!MO.getExpr()->evaluateAsAbsolute(Imm))
@@ -296,14 +297,14 @@ std::optional<uint64_t> AMDGPUMCCodeEmitter::getLitEncoding(
296297

297298
case AMDGPU::OPERAND_REG_IMM_INT64:
298299
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
299-
return getLit64Encoding(static_cast<uint64_t>(Imm), STI, false);
300+
return getLit64Encoding(Desc, static_cast<uint64_t>(Imm), STI, false);
300301

301302
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
302303
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
303-
return getLit64Encoding(static_cast<uint64_t>(Imm), STI, true);
304+
return getLit64Encoding(Desc, static_cast<uint64_t>(Imm), STI, true);
304305

305306
case AMDGPU::OPERAND_REG_IMM_FP64: {
306-
auto Enc = getLit64Encoding(static_cast<uint64_t>(Imm), STI, true);
307+
auto Enc = getLit64Encoding(Desc, static_cast<uint64_t>(Imm), STI, true);
307308
return (HasMandatoryLiteral && Enc == 255) ? 254 : Enc;
308309
}
309310

@@ -444,7 +445,7 @@ void AMDGPUMCCodeEmitter::encodeInstruction(const MCInst &MI,
444445

445446
// Is this operand a literal immediate?
446447
const MCOperand &Op = MI.getOperand(i);
447-
auto Enc = getLitEncoding(Op, Desc.operands()[i], STI);
448+
auto Enc = getLitEncoding(Desc, Op, i, STI);
448449
if (!Enc || (*Enc != 255 && *Enc != 254))
449450
continue;
450451

@@ -518,7 +519,7 @@ void AMDGPUMCCodeEmitter::getSDWASrcEncoding(const MCInst &MI, unsigned OpNo,
518519
return;
519520
} else {
520521
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
521-
auto Enc = getLitEncoding(MO, Desc.operands()[OpNo], STI);
522+
auto Enc = getLitEncoding(Desc, MO, OpNo, STI);
522523
if (Enc && *Enc != 255) {
523524
Op = *Enc | SDWA9EncValues::SRC_SGPR_MASK;
524525
return;
@@ -701,8 +702,7 @@ void AMDGPUMCCodeEmitter::getMachineOpValueCommon(
701702
if (AMDGPU::isSISrcOperand(Desc, OpNo)) {
702703
bool HasMandatoryLiteral =
703704
AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::imm);
704-
if (auto Enc = getLitEncoding(MO, Desc.operands()[OpNo], STI,
705-
HasMandatoryLiteral)) {
705+
if (auto Enc = getLitEncoding(Desc, MO, OpNo, STI, HasMandatoryLiteral)) {
706706
Op = *Enc;
707707
return;
708708
}

0 commit comments

Comments
 (0)