Skip to content

Commit

Permalink
AMDGPU: Consolidate inline immediate predicate functions
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288718 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
arsenm committed Dec 5, 2016
1 parent 75dfa0e commit 792cdf8
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 76 deletions.
23 changes: 16 additions & 7 deletions lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,10 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
return AMDGPU::isVI(getSTI());
}

bool hasInv2PiInlineImm() const {
return getSTI().getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
}

bool hasSGPR102_SGPR103() const {
return !isVI();
}
Expand Down Expand Up @@ -855,7 +859,8 @@ bool AMDGPUOperand::isInlinableImm(MVT type) const {

if (Imm.IsFPImm) { // We got fp literal token
if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
return AMDGPU::isInlinableLiteral64(Imm.Val,
AsmParser->hasInv2PiInlineImm());
}

APFloat FPLiteral(APFloat::IEEEdouble, APInt(64, Imm.Val));
Expand All @@ -865,18 +870,19 @@ bool AMDGPUOperand::isInlinableImm(MVT type) const {
// Check if single precision literal is inlinable
return AMDGPU::isInlinableLiteral32(
static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
AsmParser->isVI());
AsmParser->hasInv2PiInlineImm());
}


// We got int literal token.
if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
return AMDGPU::isInlinableLiteral64(Imm.Val,
AsmParser->hasInv2PiInlineImm());
}

return AMDGPU::isInlinableLiteral32(
static_cast<int32_t>(Literal.getLoBits(32).getZExtValue()),
AsmParser->isVI());
AsmParser->hasInv2PiInlineImm());
}

bool AMDGPUOperand::isLiteralImm(MVT type) const {
Expand Down Expand Up @@ -945,7 +951,8 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val) const {
if (Imm.IsFPImm) { // We got fp literal token
if (OpSize == 8) { // Expected 64-bit operand
// Check if literal is inlinable
if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(), AsmParser->isVI())) {
if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(),
AsmParser->hasInv2PiInlineImm())) {
Inst.addOperand(MCOperand::createImm(Literal.getZExtValue()));
} else if (AMDGPU::isSISrcFPOperand(InstDesc, OpNum)) { // Expected 64-bit fp operand
// For fp operands we check if low 32 bits are zeros
Expand Down Expand Up @@ -974,13 +981,15 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val) const {
} else { // We got int literal token
if (OpSize == 8) { // Expected 64-bit operand
auto LiteralVal = Literal.getZExtValue();
if (AMDGPU::isInlinableLiteral64(LiteralVal, AsmParser->isVI())) {
if (AMDGPU::isInlinableLiteral64(LiteralVal,
AsmParser->hasInv2PiInlineImm())) {
Inst.addOperand(MCOperand::createImm(LiteralVal));
return;
}
} else { // Expected 32-bit operand
auto LiteralVal = static_cast<int32_t>(Literal.getLoBits(32).getZExtValue());
if (AMDGPU::isInlinableLiteral32(LiteralVal, AsmParser->isVI())) {
if (AMDGPU::isInlinableLiteral32(LiteralVal,
AsmParser->hasInv2PiInlineImm())) {
Inst.addOperand(MCOperand::createImm(LiteralVal));
return;
}
Expand Down
61 changes: 20 additions & 41 deletions lib/Target/AMDGPU/SIInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1673,44 +1673,16 @@ bool SIInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
}

bool SIInstrInfo::isInlineConstant(const APInt &Imm) const {
int64_t SVal = Imm.getSExtValue();
if (SVal >= -16 && SVal <= 64)
return true;

if (Imm.getBitWidth() == 64) {
uint64_t Val = Imm.getZExtValue();
return (DoubleToBits(0.0) == Val) ||
(DoubleToBits(1.0) == Val) ||
(DoubleToBits(-1.0) == Val) ||
(DoubleToBits(0.5) == Val) ||
(DoubleToBits(-0.5) == Val) ||
(DoubleToBits(2.0) == Val) ||
(DoubleToBits(-2.0) == Val) ||
(DoubleToBits(4.0) == Val) ||
(DoubleToBits(-4.0) == Val) ||
(ST.hasInv2PiInlineImm() && Val == 0x3fc45f306dc9c882);
}

// The actual type of the operand does not seem to matter as long
// as the bits match one of the inline immediate values. For example:
//
// -nan has the hexadecimal encoding of 0xfffffffe which is -2 in decimal,
// so it is a legal inline immediate.
//
// 1065353216 has the hexadecimal encoding 0x3f800000 which is 1.0f in
// floating-point, so it is a legal inline immediate.
uint32_t Val = Imm.getZExtValue();

return (FloatToBits(0.0f) == Val) ||
(FloatToBits(1.0f) == Val) ||
(FloatToBits(-1.0f) == Val) ||
(FloatToBits(0.5f) == Val) ||
(FloatToBits(-0.5f) == Val) ||
(FloatToBits(2.0f) == Val) ||
(FloatToBits(-2.0f) == Val) ||
(FloatToBits(4.0f) == Val) ||
(FloatToBits(-4.0f) == Val) ||
(ST.hasInv2PiInlineImm() && Val == 0x3e22f983);
switch (Imm.getBitWidth()) {
case 32:
return AMDGPU::isInlinableLiteral32(Imm.getSExtValue(),
ST.hasInv2PiInlineImm());
case 64:
return AMDGPU::isInlinableLiteral64(Imm.getSExtValue(),
ST.hasInv2PiInlineImm());
default:
llvm_unreachable("invalid bitwidth");
}
}

bool SIInstrInfo::isInlineConstant(const MachineOperand &MO,
Expand All @@ -1721,9 +1693,16 @@ bool SIInstrInfo::isInlineConstant(const MachineOperand &MO,
// 32-bit floating point immediate bit pattern is legal for an integer
// immediate. It would be for any 32-bit integer operand, but would not be
// for a 64-bit one.

unsigned BitSize = 8 * OpSize;
return isInlineConstant(APInt(BitSize, MO.getImm(), true));
switch (OpSize) {
case 4:
return AMDGPU::isInlinableLiteral32(static_cast<int32_t>(MO.getImm()),
ST.hasInv2PiInlineImm());
case 8:
return AMDGPU::isInlinableLiteral64(MO.getImm(),
ST.hasInv2PiInlineImm());
default:
llvm_unreachable("invalid bitwidth");
}
}

return false;
Expand Down
50 changes: 24 additions & 26 deletions lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,40 +392,38 @@ unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc,
return getRegBitWidth(MRI->getRegClass(RCID)) / 8;
}

bool isInlinableLiteral64(int64_t Literal, bool IsVI) {
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi) {
if (Literal >= -16 && Literal <= 64)
return true;

double D = BitsToDouble(Literal);

if (D == 0.5 || D == -0.5 ||
D == 1.0 || D == -1.0 ||
D == 2.0 || D == -2.0 ||
D == 4.0 || D == -4.0)
return true;

if (IsVI && Literal == 0x3fc45f306dc9c882)
return true;

return false;
uint64_t Val = static_cast<uint64_t>(Literal);
return (Val == DoubleToBits(0.0)) ||
(Val == DoubleToBits(1.0)) ||
(Val == DoubleToBits(-1.0)) ||
(Val == DoubleToBits(0.5)) ||
(Val == DoubleToBits(-0.5)) ||
(Val == DoubleToBits(2.0)) ||
(Val == DoubleToBits(-2.0)) ||
(Val == DoubleToBits(4.0)) ||
(Val == DoubleToBits(-4.0)) ||
(Val == 0x3fc45f306dc9c882 && HasInv2Pi);
}

bool isInlinableLiteral32(int32_t Literal, bool IsVI) {
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi) {
if (Literal >= -16 && Literal <= 64)
return true;

float F = BitsToFloat(Literal);

if (F == 0.5 || F == -0.5 ||
F == 1.0 || F == -1.0 ||
F == 2.0 || F == -2.0 ||
F == 4.0 || F == -4.0)
return true;

if (IsVI && Literal == 0x3e22f983)
return true;

return false;
uint32_t Val = static_cast<uint32_t>(Literal);
return (Val == FloatToBits(0.0f)) ||
(Val == FloatToBits(1.0f)) ||
(Val == FloatToBits(-1.0f)) ||
(Val == FloatToBits(0.5f)) ||
(Val == FloatToBits(-0.5f)) ||
(Val == FloatToBits(2.0f)) ||
(Val == FloatToBits(-2.0f)) ||
(Val == FloatToBits(4.0f)) ||
(Val == FloatToBits(-4.0f)) ||
(Val == 0x3e22f983 && HasInv2Pi);
}


Expand Down
8 changes: 6 additions & 2 deletions lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,12 @@ unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc,
unsigned OpNo);

/// \brief Is this literal inlinable
bool isInlinableLiteral64(int64_t Literal, bool IsVI);
bool isInlinableLiteral32(int32_t Literal, bool IsVI);
LLVM_READNONE
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi);

LLVM_READNONE
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi);


} // end namespace AMDGPU
} // end namespace llvm
Expand Down

0 comments on commit 792cdf8

Please sign in to comment.