llvm.org GIT mirror llvm / 792cdf8
AMDGPU: Consolidate inline immediate predicate functions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288718 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 3 years ago
4 changed file(s) with 68 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
665665 return AMDGPU::isVI(getSTI());
666666 }
667667
668 bool hasInv2PiInlineImm() const {
669 return getSTI().getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
670 }
671
668672 bool hasSGPR102_SGPR103() const {
669673 return !isVI();
670674 }
854858
855859 if (Imm.IsFPImm) { // We got fp literal token
856860 if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
857 return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
861 return AMDGPU::isInlinableLiteral64(Imm.Val,
862 AsmParser->hasInv2PiInlineImm());
858863 }
859864
860865 APFloat FPLiteral(APFloat::IEEEdouble, APInt(64, Imm.Val));
864869 // Check if single precision literal is inlinable
865870 return AMDGPU::isInlinableLiteral32(
866871 static_cast(FPLiteral.bitcastToAPInt().getZExtValue()),
867 AsmParser->isVI());
872 AsmParser->hasInv2PiInlineImm());
868873 }
869874
870875
871876 // We got int literal token.
872877 if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
873 return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
878 return AMDGPU::isInlinableLiteral64(Imm.Val,
879 AsmParser->hasInv2PiInlineImm());
874880 }
875881
876882 return AMDGPU::isInlinableLiteral32(
877883 static_cast(Literal.getLoBits(32).getZExtValue()),
878 AsmParser->isVI());
884 AsmParser->hasInv2PiInlineImm());
879885 }
880886
881887 bool AMDGPUOperand::isLiteralImm(MVT type) const {
944950 if (Imm.IsFPImm) { // We got fp literal token
945951 if (OpSize == 8) { // Expected 64-bit operand
946952 // Check if literal is inlinable
947 if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(), AsmParser->isVI())) {
953 if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(),
954 AsmParser->hasInv2PiInlineImm())) {
948955 Inst.addOperand(MCOperand::createImm(Literal.getZExtValue()));
949956 } else if (AMDGPU::isSISrcFPOperand(InstDesc, OpNum)) { // Expected 64-bit fp operand
950957 // For fp operands we check if low 32 bits are zeros
973980 } else { // We got int literal token
974981 if (OpSize == 8) { // Expected 64-bit operand
975982 auto LiteralVal = Literal.getZExtValue();
976 if (AMDGPU::isInlinableLiteral64(LiteralVal, AsmParser->isVI())) {
983 if (AMDGPU::isInlinableLiteral64(LiteralVal,
984 AsmParser->hasInv2PiInlineImm())) {
977985 Inst.addOperand(MCOperand::createImm(LiteralVal));
978986 return;
979987 }
980988 } else { // Expected 32-bit operand
981989 auto LiteralVal = static_cast(Literal.getLoBits(32).getZExtValue());
982 if (AMDGPU::isInlinableLiteral32(LiteralVal, AsmParser->isVI())) {
990 if (AMDGPU::isInlinableLiteral32(LiteralVal,
991 AsmParser->hasInv2PiInlineImm())) {
983992 Inst.addOperand(MCOperand::createImm(LiteralVal));
984993 return;
985994 }
16721672 }
16731673
16741674 bool SIInstrInfo::isInlineConstant(const APInt &Imm) const {
1675 int64_t SVal = Imm.getSExtValue();
1676 if (SVal >= -16 && SVal <= 64)
1677 return true;
1678
1679 if (Imm.getBitWidth() == 64) {
1680 uint64_t Val = Imm.getZExtValue();
1681 return (DoubleToBits(0.0) == Val) ||
1682 (DoubleToBits(1.0) == Val) ||
1683 (DoubleToBits(-1.0) == Val) ||
1684 (DoubleToBits(0.5) == Val) ||
1685 (DoubleToBits(-0.5) == Val) ||
1686 (DoubleToBits(2.0) == Val) ||
1687 (DoubleToBits(-2.0) == Val) ||
1688 (DoubleToBits(4.0) == Val) ||
1689 (DoubleToBits(-4.0) == Val) ||
1690 (ST.hasInv2PiInlineImm() && Val == 0x3fc45f306dc9c882);
1691 }
1692
1693 // The actual type of the operand does not seem to matter as long
1694 // as the bits match one of the inline immediate values. For example:
1695 //
1696 // -nan has the hexadecimal encoding of 0xfffffffe which is -2 in decimal,
1697 // so it is a legal inline immediate.
1698 //
1699 // 1065353216 has the hexadecimal encoding 0x3f800000 which is 1.0f in
1700 // floating-point, so it is a legal inline immediate.
1701 uint32_t Val = Imm.getZExtValue();
1702
1703 return (FloatToBits(0.0f) == Val) ||
1704 (FloatToBits(1.0f) == Val) ||
1705 (FloatToBits(-1.0f) == Val) ||
1706 (FloatToBits(0.5f) == Val) ||
1707 (FloatToBits(-0.5f) == Val) ||
1708 (FloatToBits(2.0f) == Val) ||
1709 (FloatToBits(-2.0f) == Val) ||
1710 (FloatToBits(4.0f) == Val) ||
1711 (FloatToBits(-4.0f) == Val) ||
1712 (ST.hasInv2PiInlineImm() && Val == 0x3e22f983);
1675 switch (Imm.getBitWidth()) {
1676 case 32:
1677 return AMDGPU::isInlinableLiteral32(Imm.getSExtValue(),
1678 ST.hasInv2PiInlineImm());
1679 case 64:
1680 return AMDGPU::isInlinableLiteral64(Imm.getSExtValue(),
1681 ST.hasInv2PiInlineImm());
1682 default:
1683 llvm_unreachable("invalid bitwidth");
1684 }
17131685 }
17141686
17151687 bool SIInstrInfo::isInlineConstant(const MachineOperand &MO,
17201692 // 32-bit floating point immediate bit pattern is legal for an integer
17211693 // immediate. It would be for any 32-bit integer operand, but would not be
17221694 // for a 64-bit one.
1723
1724 unsigned BitSize = 8 * OpSize;
1725 return isInlineConstant(APInt(BitSize, MO.getImm(), true));
1695 switch (OpSize) {
1696 case 4:
1697 return AMDGPU::isInlinableLiteral32(static_cast(MO.getImm()),
1698 ST.hasInv2PiInlineImm());
1699 case 8:
1700 return AMDGPU::isInlinableLiteral64(MO.getImm(),
1701 ST.hasInv2PiInlineImm());
1702 default:
1703 llvm_unreachable("invalid bitwidth");
1704 }
17261705 }
17271706
17281707 return false;
391391 return getRegBitWidth(MRI->getRegClass(RCID)) / 8;
392392 }
393393
394 bool isInlinableLiteral64(int64_t Literal, bool IsVI) {
394 bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi) {
395395 if (Literal >= -16 && Literal <= 64)
396396 return true;
397397
398 double D = BitsToDouble(Literal);
399
400 if (D == 0.5 || D == -0.5 ||
401 D == 1.0 || D == -1.0 ||
402 D == 2.0 || D == -2.0 ||
403 D == 4.0 || D == -4.0)
404 return true;
405
406 if (IsVI && Literal == 0x3fc45f306dc9c882)
407 return true;
408
409 return false;
410 }
411
412 bool isInlinableLiteral32(int32_t Literal, bool IsVI) {
398 uint64_t Val = static_cast(Literal);
399 return (Val == DoubleToBits(0.0)) ||
400 (Val == DoubleToBits(1.0)) ||
401 (Val == DoubleToBits(-1.0)) ||
402 (Val == DoubleToBits(0.5)) ||
403 (Val == DoubleToBits(-0.5)) ||
404 (Val == DoubleToBits(2.0)) ||
405 (Val == DoubleToBits(-2.0)) ||
406 (Val == DoubleToBits(4.0)) ||
407 (Val == DoubleToBits(-4.0)) ||
408 (Val == 0x3fc45f306dc9c882 && HasInv2Pi);
409 }
410
411 bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi) {
413412 if (Literal >= -16 && Literal <= 64)
414413 return true;
415414
416 float F = BitsToFloat(Literal);
417
418 if (F == 0.5 || F == -0.5 ||
419 F == 1.0 || F == -1.0 ||
420 F == 2.0 || F == -2.0 ||
421 F == 4.0 || F == -4.0)
422 return true;
423
424 if (IsVI && Literal == 0x3e22f983)
425 return true;
426
427 return false;
415 uint32_t Val = static_cast(Literal);
416 return (Val == FloatToBits(0.0f)) ||
417 (Val == FloatToBits(1.0f)) ||
418 (Val == FloatToBits(-1.0f)) ||
419 (Val == FloatToBits(0.5f)) ||
420 (Val == FloatToBits(-0.5f)) ||
421 (Val == FloatToBits(2.0f)) ||
422 (Val == FloatToBits(-2.0f)) ||
423 (Val == FloatToBits(4.0f)) ||
424 (Val == FloatToBits(-4.0f)) ||
425 (Val == 0x3e22f983 && HasInv2Pi);
428426 }
429427
430428
167167 unsigned OpNo);
168168
169169 /// \brief Is this literal inlinable
170 bool isInlinableLiteral64(int64_t Literal, bool IsVI);
171 bool isInlinableLiteral32(int32_t Literal, bool IsVI);
170 LLVM_READNONE
171 bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi);
172
173 LLVM_READNONE
174 bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi);
175
172176
173177 } // end namespace AMDGPU
174178 } // end namespace llvm