AMDGPU: Consolidate inline immediate predicate functions

llvm-svn: 288718
This commit is contained in:
Matt Arsenault 2016-12-05 22:26:17 +00:00
parent c0bd197c6b
commit 26faed3960
4 changed files with 65 additions and 75 deletions

View File

@ -666,6 +666,10 @@ public:
return AMDGPU::isVI(getSTI());
}
bool hasInv2PiInlineImm() const {
return getSTI().getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
}
bool hasSGPR102_SGPR103() const {
return !isVI();
}
@ -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));
@ -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 {
@ -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
@ -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;
}

View File

@ -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);
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");
}
// 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);
}
bool SIInstrInfo::isInlineConstant(const MachineOperand &MO,
@ -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;

View File

@ -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);
}

View File

@ -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