Skip to content

[AMDGPU] Change the representation of double literals in operands #68740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
cc9e065
[AMDGPU] Change the representation of double literals in operands
rampitec Oct 4, 2023
b74ad67
[AMDGPU] Change the representation of double literals in operands
rampitec Oct 4, 2023
c6cef06
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
5974041
Merge branch 'llvm:main' into lit64-mc-enc
rampitec Oct 12, 2023
6e7dffa
[AMDGPU] Make clang-format happy with disasm cganges
rampitec Oct 12, 2023
b430ae7
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
a84e1bc
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
cf4d55e
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
32ba230
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
f6bd002
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
4e64a2f
Merge branch 'llvm:main' into lit64-mc-enc
rampitec Oct 12, 2023
88e9ea9
[AMDGPU] Change the representation of double literals in operands
rampitec Oct 4, 2023
0bb5d06
[AMDGPU] Make clang-format happy with disasm cganges
rampitec Oct 12, 2023
e2e1efa
Change argument of AMDGPU::isValid32BitLiteral to IsFP64
rampitec Oct 12, 2023
95f2f2b
Merge branch 'lit64-mc-enc' of github.com:rampitec/llvm-project into …
rampitec Oct 12, 2023
68331b9
Merge branch 'llvm:main' into lit64-mc-enc
rampitec Oct 12, 2023
fca5229
Merge branch 'llvm:main' into lit64-mc-enc
rampitec Oct 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2141,9 +2141,10 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
const_cast<AMDGPUAsmParser *>(AsmParser)->Warning(Inst.getLoc(),
"Can't encode literal as exact 64-bit floating-point operand. "
"Low 32-bits will be set to zero");
Val &= 0xffffffff00000000u;
}

Inst.addOperand(MCOperand::createImm(Literal.lshr(32).getZExtValue()));
Inst.addOperand(MCOperand::createImm(Val));
setImmKindLiteral();
return;
}
Expand Down Expand Up @@ -2242,7 +2243,9 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
return;
}

Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? Val << 32 : Lo_32(Val);

Inst.addOperand(MCOperand::createImm(Val));
setImmKindLiteral();
return;

Expand Down Expand Up @@ -4309,7 +4312,19 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
continue;

if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
uint32_t Value = static_cast<uint32_t>(MO.getImm());
uint64_t Value = static_cast<uint64_t>(MO.getImm());
bool IsFP64 = AMDGPU::isSISrcFPOperand(Desc, OpIdx) &&
AMDGPU::getOperandSize(Desc.operands()[OpIdx]) == 8;
bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP64);

if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
Error(getLitLoc(Operands), "invalid operand for instruction");
return false;
}

if (IsFP64 && IsValid32Op)
Value = Hi_32(Value);

if (NumLiterals == 0 || LiteralValue != Value) {
LiteralValue = Value;
++NumLiterals;
Expand Down
27 changes: 20 additions & 7 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,15 @@ static DecodeStatus decodeOperand_AVLdSt_Any(MCInst &Inst, unsigned Imm,
return addOperand(Inst, DAsm->decodeSrcOp(Opw, Imm | 256));
}

static DecodeStatus decodeOperand_VSrc_f64(MCInst &Inst, unsigned Imm,
uint64_t Addr,
const MCDisassembler *Decoder) {
assert(Imm < (1 << 9) && "9-bit encoding");
auto DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
return addOperand(
Inst, DAsm->decodeSrcOp(AMDGPUDisassembler::OPW64, Imm, false, 64, true));
}

static DecodeStatus
DecodeAVLdSt_32RegisterClass(MCInst &Inst, unsigned Imm, uint64_t Addr,
const MCDisassembler *Decoder) {
Expand Down Expand Up @@ -1219,7 +1228,7 @@ AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const {
return MCOperand::createImm(Literal);
}

MCOperand AMDGPUDisassembler::decodeLiteralConstant() const {
MCOperand AMDGPUDisassembler::decodeLiteralConstant(bool ExtendFP64) const {
// For now all literal constants are supposed to be unsigned integer
// ToDo: deal with signed/unsigned 64-bit integer constants
// ToDo: deal with float/double constants
Expand All @@ -1229,9 +1238,11 @@ MCOperand AMDGPUDisassembler::decodeLiteralConstant() const {
Twine(Bytes.size()));
}
HasLiteral = true;
Literal = eatBytes<uint32_t>(Bytes);
Literal = Literal64 = eatBytes<uint32_t>(Bytes);
if (ExtendFP64)
Literal64 <<= 32;
}
return MCOperand::createImm(Literal);
return MCOperand::createImm(ExtendFP64 ? Literal64 : Literal);
}

MCOperand AMDGPUDisassembler::decodeIntImmed(unsigned Imm) {
Expand Down Expand Up @@ -1448,7 +1459,7 @@ int AMDGPUDisassembler::getTTmpIdx(unsigned Val) const {

MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val,
bool MandatoryLiteral,
unsigned ImmWidth) const {
unsigned ImmWidth, bool IsFP) const {
using namespace AMDGPU::EncValues;

assert(Val < 1024); // enum10
Expand All @@ -1460,13 +1471,15 @@ MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val,
return createRegOperand(IsAGPR ? getAgprClassId(Width)
: getVgprClassId(Width), Val - VGPR_MIN);
}
return decodeNonVGPRSrcOp(Width, Val & 0xFF, MandatoryLiteral, ImmWidth);
return decodeNonVGPRSrcOp(Width, Val & 0xFF, MandatoryLiteral, ImmWidth,
IsFP);
}

MCOperand AMDGPUDisassembler::decodeNonVGPRSrcOp(const OpWidthTy Width,
unsigned Val,
bool MandatoryLiteral,
unsigned ImmWidth) const {
unsigned ImmWidth,
bool IsFP) const {
// Cases when Val{8} is 1 (vgpr, agpr or true 16 vgpr) should have been
// decoded earlier.
assert(Val < (1 << 8) && "9-bit Src encoding when Val{8} is 0");
Expand Down Expand Up @@ -1494,7 +1507,7 @@ MCOperand AMDGPUDisassembler::decodeNonVGPRSrcOp(const OpWidthTy Width,
// Keep a sentinel value for deferred setting
return MCOperand::createImm(LITERAL_CONST);
else
return decodeLiteralConstant();
return decodeLiteralConstant(IsFP && ImmWidth == 64);
}

switch (Width) {
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class AMDGPUDisassembler : public MCDisassembler {
const unsigned TargetMaxInstBytes;
mutable ArrayRef<uint8_t> Bytes;
mutable uint32_t Literal;
mutable uint64_t Literal64;
mutable bool HasLiteral;
mutable std::optional<bool> EnableWavefrontSize32;

Expand Down Expand Up @@ -229,15 +230,15 @@ class AMDGPUDisassembler : public MCDisassembler {
static MCOperand decodeFPImmed(unsigned ImmWidth, unsigned Imm);

MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
MCOperand decodeLiteralConstant() const;
MCOperand decodeLiteralConstant(bool ExtendFP64) const;

MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val,
bool MandatoryLiteral = false,
unsigned ImmWidth = 0) const;
bool MandatoryLiteral = false, unsigned ImmWidth = 0,
bool IsFP = false) const;

MCOperand decodeNonVGPRSrcOp(const OpWidthTy Width, unsigned Val,
bool MandatoryLiteral = false,
unsigned ImmWidth = 0) const;
unsigned ImmWidth = 0, bool IsFP = false) const;

MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const;
MCOperand decodeSpecialReg32(unsigned Val) const;
Expand Down
15 changes: 10 additions & 5 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,

void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
const MCSubtargetInfo &STI,
raw_ostream &O) {
raw_ostream &O, bool IsFP) {
int64_t SImm = static_cast<int64_t>(Imm);
if (SImm >= -16 && SImm <= 64) {
O << SImm;
Expand Down Expand Up @@ -454,7 +454,10 @@ void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
else if (Imm == 0x3fc45f306dc9c882 &&
STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
O << "0.15915494309189532";
else {
else if (IsFP) {
assert(AMDGPU::isValid32BitLiteral(Imm, true));
O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
} else {
assert(isUInt<32>(Imm) || isInt<32>(Imm));

// In rare situations, we will have a 32-bit literal in a 64-bit
Expand Down Expand Up @@ -605,11 +608,13 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
printImmediate32(Op.getImm(), STI, O);
break;
case AMDGPU::OPERAND_REG_IMM_INT64:
case AMDGPU::OPERAND_REG_IMM_FP64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
printImmediate64(Op.getImm(), STI, O, false);
break;
case AMDGPU::OPERAND_REG_IMM_FP64:
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
printImmediate64(Op.getImm(), STI, O);
printImmediate64(Op.getImm(), STI, O, true);
break;
case AMDGPU::OPERAND_REG_INLINE_C_INT16:
case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
Expand Down Expand Up @@ -671,7 +676,7 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
if (RCBits == 32)
printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
else if (RCBits == 64)
printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O);
printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O, true);
else
llvm_unreachable("Invalid register class size");
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class AMDGPUInstPrinter : public MCInstPrinter {
void printImmediate32(uint32_t Imm, const MCSubtargetInfo &STI,
raw_ostream &O);
void printImmediate64(uint64_t Imm, const MCSubtargetInfo &STI,
raw_ostream &O);
raw_ostream &O, bool IsFP);
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
void printRegularOperand(const MCInst *MI, unsigned OpNo,
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,10 @@ void AMDGPUMCCodeEmitter::encodeInstruction(const MCInst &MI,
} else if (!Op.isExpr()) // Exprs will be replaced with a fixup value.
llvm_unreachable("Must be immediate or expr");

support::endian::write<uint32_t>(CB, Imm, llvm::endianness::little);
if (Desc.operands()[i].OperandType == AMDGPU::OPERAND_REG_IMM_FP64)
Imm = Hi_32(Imm);

support::endian::write<uint32_t>(CB, Imm, support::endianness::little);

// Only one literal value allowed
break;
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/AMDGPU/SIRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,9 @@ def VSrc_f32 : RegOrF32 <"VS_32", "OPERAND_REG_IMM">;
def VSrc_v2b16 : RegOrV2B16 <"VS_32", "OPERAND_REG_IMM">;
def VSrc_v2f16 : RegOrV2F16 <"VS_32", "OPERAND_REG_IMM">;
def VSrc_b64 : RegOrB64 <"VS_64", "OPERAND_REG_IMM">;
def VSrc_f64 : RegOrF64 <"VS_64", "OPERAND_REG_IMM">;
def VSrc_f64 : RegOrF64 <"VS_64", "OPERAND_REG_IMM"> {
let DecoderMethod = "decodeOperand_VSrc_f64";
}
def VSrc_v2b32 : RegOrV2B32 <"VS_64", "OPERAND_REG_IMM">;
def VSrc_v2f32 : RegOrV2F32 <"VS_64", "OPERAND_REG_IMM">;

Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,13 @@ bool isFoldableLiteralV216(int32_t Literal, bool HasInv2Pi) {
return Lo16 == Hi16;
}

bool isValid32BitLiteral(uint64_t Val, bool IsFP64) {
if (IsFP64)
return !(Val & 0xffffffffu);

return isUInt<32>(Val) || isInt<32>(Val);
}

bool isArgPassedInSGPR(const Argument *A) {
const Function *F = A->getParent();

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,9 @@ bool isInlinableIntLiteralV216(int32_t Literal);
LLVM_READNONE
bool isFoldableLiteralV216(int32_t Literal, bool HasInv2Pi);

LLVM_READNONE
bool isValid32BitLiteral(uint64_t Val, bool IsFP64);

bool isArgPassedInSGPR(const Argument *Arg);

bool isArgPassedInSGPR(const CallBase *CB, unsigned ArgNo);
Expand Down