Index: lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -650,6 +650,10 @@ return AMDGPU::isVI(getSTI()); } + bool hasInv2PiInlineImm() const { + return getSTI().getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]; + } + bool hasSGPR102_SGPR103() const { return !isVI(); } @@ -829,7 +833,8 @@ 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)); @@ -839,18 +844,19 @@ // Check if single precision literal is inlinable return AMDGPU::isInlinableLiteral32( static_cast(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(Literal.getLoBits(32).getZExtValue()), - AsmParser->isVI()); + AsmParser->hasInv2PiInlineImm()); } bool AMDGPUOperand::isLiteralImm(MVT type) const { @@ -919,7 +925,8 @@ 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 @@ -948,13 +955,15 @@ } 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(Literal.getLoBits(32).getZExtValue()); - if (AMDGPU::isInlinableLiteral32(LiteralVal, AsmParser->isVI())) { + if (AMDGPU::isInlinableLiteral32(LiteralVal, + AsmParser->hasInv2PiInlineImm())) { Inst.addOperand(MCOperand::createImm(LiteralVal)); return; } Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1673,44 +1673,16 @@ } 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, @@ -1721,9 +1693,16 @@ // 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(MO.getImm()), + ST.hasInv2PiInlineImm()); + case 8: + return AMDGPU::isInlinableLiteral64(MO.getImm(), + ST.hasInv2PiInlineImm()); + default: + llvm_unreachable("invalid bitwidth"); + } } return false; Index: lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h =================================================================== --- lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -168,8 +168,9 @@ unsigned OpNo); /// \brief Is this literal inlinable -bool isInlinableLiteral64(int64_t Literal, bool IsVI); -bool isInlinableLiteral32(int32_t Literal, bool IsVI); +bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi); +bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi); + } // end namespace AMDGPU } // end namespace llvm Index: lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp =================================================================== --- lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -392,40 +392,38 @@ 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(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(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); }