diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp | 105 |
1 files changed, 92 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp index 2de20489e1d1..8146a67d4dfb 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -17,6 +17,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/IR/Module.h" #define DEBUG_TYPE "gisel-known-bits" @@ -87,10 +88,10 @@ LLVM_ATTRIBUTE_UNUSED static void dumpResult(const MachineInstr &MI, const KnownBits &Known, unsigned Depth) { dbgs() << "[" << Depth << "] Compute known bits: " << MI << "[" << Depth << "] Computed for: " << MI << "[" << Depth << "] Known: 0x" - << (Known.Zero | Known.One).toString(16, false) << "\n" - << "[" << Depth << "] Zero: 0x" << Known.Zero.toString(16, false) + << toString(Known.Zero | Known.One, 16, false) << "\n" + << "[" << Depth << "] Zero: 0x" << toString(Known.Zero, 16, false) << "\n" - << "[" << Depth << "] One: 0x" << Known.One.toString(16, false) + << "[" << Depth << "] One: 0x" << toString(Known.One, 16, false) << "\n"; } @@ -113,6 +114,20 @@ void GISelKnownBits::computeKnownBitsMin(Register Src0, Register Src1, Known = KnownBits::commonBits(Known, Known2); } +// Bitfield extract is computed as (Src >> Offset) & Mask, where Mask is +// created using Width. Use this function when the inputs are KnownBits +// objects. TODO: Move this KnownBits.h if this is usable in more cases. +static KnownBits extractBits(unsigned BitWidth, const KnownBits &SrcOpKnown, + const KnownBits &OffsetKnown, + const KnownBits &WidthKnown) { + KnownBits Mask(BitWidth); + Mask.Zero = APInt::getBitsSetFrom( + BitWidth, WidthKnown.getMaxValue().getLimitedValue(BitWidth)); + Mask.One = APInt::getLowBitsSet( + BitWidth, WidthKnown.getMinValue().getLimitedValue(BitWidth)); + return KnownBits::lshr(SrcOpKnown, OffsetKnown) & Mask; +} + void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, const APInt &DemandedElts, unsigned Depth) { @@ -129,7 +144,7 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, return; } - unsigned BitWidth = DstTy.getSizeInBits(); + unsigned BitWidth = DstTy.getScalarSizeInBits(); auto CacheEntry = ComputeKnownBitsCache.find(R); if (CacheEntry != ComputeKnownBitsCache.end()) { Known = CacheEntry->second; @@ -140,9 +155,6 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, } Known = KnownBits(BitWidth); // Don't know anything - if (DstTy.isVector()) - return; // TODO: Handle vectors. - // Depth may get bigger than max depth if it gets passed to a different // GISelKnownBits object. // This may happen when say a generic part uses a GISelKnownBits object @@ -164,6 +176,25 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, TL.computeKnownBitsForTargetInstr(*this, R, Known, DemandedElts, MRI, Depth); break; + case TargetOpcode::G_BUILD_VECTOR: { + // Collect the known bits that are shared by every demanded vector element. + Known.Zero.setAllBits(); Known.One.setAllBits(); + for (unsigned i = 0, e = MI.getNumOperands() - 1; i < e; ++i) { + if (!DemandedElts[i]) + continue; + + computeKnownBitsImpl(MI.getOperand(i + 1).getReg(), Known2, DemandedElts, + Depth + 1); + + // Known bits are the values that are shared by every demanded element. + Known = KnownBits::commonBits(Known, Known2); + + // If we don't know any bits, early out. + if (Known.isUnknown()) + break; + } + break; + } case TargetOpcode::COPY: case TargetOpcode::G_PHI: case TargetOpcode::PHI: { @@ -244,6 +275,8 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, break; } case TargetOpcode::G_PTR_ADD: { + if (DstTy.isVector()) + break; // G_PTR_ADD is like G_ADD. FIXME: Is this true for all targets? LLT Ty = MRI.getType(MI.getOperand(1).getReg()); if (DL.isNonIntegralAddressSpace(Ty.getAddressSpace())) @@ -284,7 +317,7 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, Depth + 1); computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts, Depth + 1); - Known = KnownBits::computeForMul(Known, Known2); + Known = KnownBits::mul(Known, Known2); break; } case TargetOpcode::G_SELECT: { @@ -332,6 +365,8 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, } case TargetOpcode::G_FCMP: case TargetOpcode::G_ICMP: { + if (DstTy.isVector()) + break; if (TL.getBooleanContents(DstTy.isVector(), Opcode == TargetOpcode::G_FCMP) == TargetLowering::ZeroOrOneBooleanContent && @@ -347,6 +382,7 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, Known = Known.sext(BitWidth); break; } + case TargetOpcode::G_ASSERT_SEXT: case TargetOpcode::G_SEXT_INREG: { computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts, Depth + 1); @@ -368,6 +404,8 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, break; } case TargetOpcode::G_ZEXTLOAD: { + if (DstTy.isVector()) + break; // Everything above the retrieved bits is zero Known.Zero.setBitsFrom((*MI.memoperands_begin())->getSizeInBits()); break; @@ -401,15 +439,25 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, } case TargetOpcode::G_INTTOPTR: case TargetOpcode::G_PTRTOINT: + if (DstTy.isVector()) + break; // Fall through and handle them the same as zext/trunc. LLVM_FALLTHROUGH; + case TargetOpcode::G_ASSERT_ZEXT: case TargetOpcode::G_ZEXT: case TargetOpcode::G_TRUNC: { Register SrcReg = MI.getOperand(1).getReg(); LLT SrcTy = MRI.getType(SrcReg); - unsigned SrcBitWidth = SrcTy.isPointer() - ? DL.getIndexSizeInBits(SrcTy.getAddressSpace()) - : SrcTy.getSizeInBits(); + unsigned SrcBitWidth; + + // G_ASSERT_ZEXT stores the original bitwidth in the immediate operand. + if (Opcode == TargetOpcode::G_ASSERT_ZEXT) + SrcBitWidth = MI.getOperand(2).getImm(); + else { + SrcBitWidth = SrcTy.isPointer() + ? DL.getIndexSizeInBits(SrcTy.getAddressSpace()) + : SrcTy.getSizeInBits(); + } assert(SrcBitWidth && "SrcBitWidth can't be zero"); Known = Known.zextOrTrunc(SrcBitWidth); computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1); @@ -431,6 +479,8 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, break; } case TargetOpcode::G_UNMERGE_VALUES: { + if (DstTy.isVector()) + break; unsigned NumOps = MI.getNumOperands(); Register SrcReg = MI.getOperand(NumOps - 1).getReg(); if (MRI.getType(SrcReg).isVector()) @@ -451,13 +501,41 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known, case TargetOpcode::G_BSWAP: { Register SrcReg = MI.getOperand(1).getReg(); computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1); - Known.byteSwap(); + Known = Known.byteSwap(); break; } case TargetOpcode::G_BITREVERSE: { Register SrcReg = MI.getOperand(1).getReg(); computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1); - Known.reverseBits(); + Known = Known.reverseBits(); + break; + } + case TargetOpcode::G_UBFX: { + KnownBits SrcOpKnown, OffsetKnown, WidthKnown; + computeKnownBitsImpl(MI.getOperand(1).getReg(), SrcOpKnown, DemandedElts, + Depth + 1); + computeKnownBitsImpl(MI.getOperand(2).getReg(), OffsetKnown, DemandedElts, + Depth + 1); + computeKnownBitsImpl(MI.getOperand(3).getReg(), WidthKnown, DemandedElts, + Depth + 1); + Known = extractBits(BitWidth, SrcOpKnown, OffsetKnown, WidthKnown); + break; + } + case TargetOpcode::G_SBFX: { + KnownBits SrcOpKnown, OffsetKnown, WidthKnown; + computeKnownBitsImpl(MI.getOperand(1).getReg(), SrcOpKnown, DemandedElts, + Depth + 1); + computeKnownBitsImpl(MI.getOperand(2).getReg(), OffsetKnown, DemandedElts, + Depth + 1); + computeKnownBitsImpl(MI.getOperand(3).getReg(), WidthKnown, DemandedElts, + Depth + 1); + Known = extractBits(BitWidth, SrcOpKnown, OffsetKnown, WidthKnown); + // Sign extend the extracted value using shift left and arithmetic shift + // right. + KnownBits ExtKnown = KnownBits::makeConstant(APInt(BitWidth, BitWidth)); + KnownBits ShiftKnown = KnownBits::computeForAddSub( + /*Add*/ false, /*NSW*/ false, ExtKnown, WidthKnown); + Known = KnownBits::ashr(KnownBits::shl(Known, ShiftKnown), ShiftKnown); break; } } @@ -523,6 +601,7 @@ unsigned GISelKnownBits::computeNumSignBits(Register R, unsigned Tmp = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits(); return computeNumSignBits(Src, DemandedElts, Depth + 1) + Tmp; } + case TargetOpcode::G_ASSERT_SEXT: case TargetOpcode::G_SEXT_INREG: { // Max of the input and what this extends. Register Src = MI.getOperand(1).getReg(); |