aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp105
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();