1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[SelectionDAG] Use KnownBits struct in DAG's computeKnownBits and simplifyDemandedBits

This patch replaces the separate APInts for KnownZero/KnownOne with a single KnownBits struct. This is similar to what was done to ValueTracking's version recently.

This is largely a mechanical transformation from KnownZero to Known.Zero.

Differential Revision: https://reviews.llvm.org/D32569

llvm-svn: 301620
This commit is contained in:
Craig Topper 2017-04-28 05:31:46 +00:00
parent 946fd240da
commit af680f3cea
31 changed files with 676 additions and 746 deletions

View File

@ -25,6 +25,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <vector>
@ -171,9 +172,8 @@ public:
struct LiveOutInfo {
unsigned NumSignBits : 31;
unsigned IsValid : 1;
APInt KnownOne, KnownZero;
LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
KnownZero(1, 0) {}
KnownBits Known;
LiveOutInfo() : NumSignBits(0), IsValid(true), Known(1) {}
};
/// Record the preferred extend type (ISD::SIGN_EXTEND or ISD::ZERO_EXTEND)
@ -247,16 +247,16 @@ public:
/// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
const APInt &KnownZero, const APInt &KnownOne) {
const KnownBits &Known) {
// Only install this information if it tells us something.
if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0)
if (NumSignBits == 1 && Known.Zero == 0 && Known.One == 0)
return;
LiveOutRegInfo.grow(Reg);
LiveOutInfo &LOI = LiveOutRegInfo[Reg];
LOI.NumSignBits = NumSignBits;
LOI.KnownOne = KnownOne;
LOI.KnownZero = KnownZero;
LOI.Known.One = Known.One;
LOI.Known.Zero = Known.Zero;
}
/// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination

View File

@ -33,6 +33,7 @@
namespace llvm {
struct KnownBits;
class MachineConstantPoolValue;
class MachineFunction;
class MDNode;
@ -1283,21 +1284,19 @@ public:
const;
/// Determine which bits of Op are known to be either zero or one and return
/// them in the KnownZero/KnownOne bitsets. For vectors, the known bits are
/// those that are shared by every vector element.
/// them in Known. For vectors, the known bits are those that are shared by
/// every vector element.
/// Targets can implement the computeKnownBitsForTargetNode method in the
/// TargetLowering class to allow target nodes to be understood.
void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
unsigned Depth = 0) const;
void computeKnownBits(SDValue Op, KnownBits &Known, unsigned Depth = 0) const;
/// Determine which bits of Op are known to be either zero or one and return
/// them in the KnownZero/KnownOne bitsets. The DemandedElts argument allows
/// us to only collect the known bits that are shared by the requested vector
/// elements.
/// them in Known. The DemandedElts argument allows us to only collect the
/// known bits that are shared by the requested vector elements.
/// Targets can implement the computeKnownBitsForTargetNode method in the
/// TargetLowering class to allow target nodes to be understood.
void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
const APInt &DemandedElts, unsigned Depth = 0) const;
void computeKnownBits(SDValue Op, KnownBits &Known, const APInt &DemandedElts,
unsigned Depth = 0) const;
/// Used to represent the possible overflow behavior of an operation.
/// Never: the operation cannot overflow.

View File

@ -69,6 +69,7 @@ class CCValAssign;
class FastISel;
class FunctionLoweringInfo;
class IntrinsicInst;
struct KnownBits;
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
@ -2442,7 +2443,7 @@ public:
/// with TLO.New will be incorrect when this parameter is true and TLO.Old
/// has multiple uses.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
APInt &KnownZero, APInt &KnownOne,
KnownBits &Known,
TargetLoweringOpt &TLO,
unsigned Depth = 0,
bool AssumeSingleUse = false) const;
@ -2456,8 +2457,7 @@ public:
/// argument allows us to only collect the known bits that are shared by the
/// requested vector elements.
virtual void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const;

View File

@ -33,6 +33,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
@ -965,8 +966,8 @@ CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) {
/// things it uses can be simplified by bit propagation. If so, return true.
bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
APInt KnownZero, KnownOne;
if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
KnownBits Known;
if (!TLI.SimplifyDemandedBits(Op, Demanded, Known, TLO))
return false;
// Revisit the node.
@ -5697,16 +5698,16 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
// fold (srl (ctlz x), "5") -> x iff x has one bit set (the low bit).
if (N1C && N0.getOpcode() == ISD::CTLZ &&
N1C->getAPIntValue() == Log2_32(OpSizeInBits)) {
APInt KnownZero, KnownOne;
DAG.computeKnownBits(N0.getOperand(0), KnownZero, KnownOne);
KnownBits Known;
DAG.computeKnownBits(N0.getOperand(0), Known);
// If any of the input bits are KnownOne, then the input couldn't be all
// zeros, thus the result of the srl will always be zero.
if (KnownOne.getBoolValue()) return DAG.getConstant(0, SDLoc(N0), VT);
if (Known.One.getBoolValue()) return DAG.getConstant(0, SDLoc(N0), VT);
// If all of the bits input the to ctlz node are known to be zero, then
// the result of the ctlz is "32" and the result of the shift is one.
APInt UnknownBits = ~KnownZero;
APInt UnknownBits = ~Known.Zero;
if (UnknownBits == 0) return DAG.getConstant(1, SDLoc(N0), VT);
// Otherwise, check to see if there is exactly one bit input to the ctlz.
@ -7133,15 +7134,14 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
}
// isTruncateOf - If N is a truncate of some other value, return true, record
// the value being truncated in Op and which of Op's bits are zero in KnownZero.
// This function computes KnownZero to avoid a duplicated call to
// the value being truncated in Op and which of Op's bits are zero/one in Known.
// This function computes KnownBits to avoid a duplicated call to
// computeKnownBits in the caller.
static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op,
APInt &KnownZero) {
APInt KnownOne;
KnownBits &Known) {
if (N->getOpcode() == ISD::TRUNCATE) {
Op = N->getOperand(0);
DAG.computeKnownBits(Op, KnownZero, KnownOne);
DAG.computeKnownBits(Op, Known);
return true;
}
@ -7160,9 +7160,9 @@ static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op,
else
return false;
DAG.computeKnownBits(Op, KnownZero, KnownOne);
DAG.computeKnownBits(Op, Known);
if (!(KnownZero | 1).isAllOnesValue())
if (!(Known.Zero | 1).isAllOnesValue())
return false;
return true;
@ -7187,8 +7187,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
// This is valid when the truncated bits of x are already zero.
// FIXME: We should extend this to work for vectors too.
SDValue Op;
APInt KnownZero;
if (!VT.isVector() && isTruncateOf(DAG, N0, Op, KnownZero)) {
KnownBits Known;
if (!VT.isVector() && isTruncateOf(DAG, N0, Op, Known)) {
APInt TruncatedBits =
(Op.getValueSizeInBits() == N0.getValueSizeInBits()) ?
APInt(Op.getValueSizeInBits(), 0) :
@ -7196,7 +7196,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
N0.getValueSizeInBits(),
std::min(Op.getValueSizeInBits(),
VT.getSizeInBits()));
if (TruncatedBits.isSubsetOf(KnownZero)) {
if (TruncatedBits.isSubsetOf(Known.Zero)) {
if (VT.bitsGT(Op.getValueType()))
return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), VT, Op);
if (VT.bitsLT(Op.getValueType()))

View File

@ -400,10 +400,10 @@ FunctionLoweringInfo::GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth) {
if (!LOI->IsValid)
return nullptr;
if (BitWidth > LOI->KnownZero.getBitWidth()) {
if (BitWidth > LOI->Known.getBitWidth()) {
LOI->NumSignBits = 1;
LOI->KnownZero = LOI->KnownZero.zextOrTrunc(BitWidth);
LOI->KnownOne = LOI->KnownOne.zextOrTrunc(BitWidth);
LOI->Known.Zero = LOI->Known.Zero.zextOrTrunc(BitWidth);
LOI->Known.One = LOI->Known.One.zextOrTrunc(BitWidth);
}
return LOI;
@ -436,17 +436,15 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
Value *V = PN->getIncomingValue(0);
if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) {
DestLOI.NumSignBits = 1;
APInt Zero(BitWidth, 0);
DestLOI.KnownZero = Zero;
DestLOI.KnownOne = Zero;
DestLOI.Known = KnownBits(BitWidth);
return;
}
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
DestLOI.NumSignBits = Val.getNumSignBits();
DestLOI.KnownZero = ~Val;
DestLOI.KnownOne = Val;
DestLOI.Known.Zero = ~Val;
DestLOI.Known.One = Val;
} else {
assert(ValueMap.count(V) && "V should have been placed in ValueMap when its"
"CopyToReg node was created.");
@ -463,25 +461,23 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
DestLOI = *SrcLOI;
}
assert(DestLOI.KnownZero.getBitWidth() == BitWidth &&
DestLOI.KnownOne.getBitWidth() == BitWidth &&
assert(DestLOI.Known.Zero.getBitWidth() == BitWidth &&
DestLOI.Known.One.getBitWidth() == BitWidth &&
"Masks should have the same bit width as the type.");
for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *V = PN->getIncomingValue(i);
if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) {
DestLOI.NumSignBits = 1;
APInt Zero(BitWidth, 0);
DestLOI.KnownZero = Zero;
DestLOI.KnownOne = Zero;
DestLOI.Known = KnownBits(BitWidth);
return;
}
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits());
DestLOI.KnownZero &= ~Val;
DestLOI.KnownOne &= Val;
DestLOI.Known.Zero &= ~Val;
DestLOI.Known.One &= Val;
continue;
}
@ -498,8 +494,8 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
return;
}
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits);
DestLOI.KnownZero &= SrcLOI->KnownZero;
DestLOI.KnownOne &= SrcLOI->KnownOne;
DestLOI.Known.Zero &= SrcLOI->Known.Zero;
DestLOI.Known.One &= SrcLOI->Known.One;
}
}

View File

@ -21,6 +21,7 @@
#include "LegalizeTypes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@ -1525,11 +1526,11 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
SDLoc dl(N);
APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
APInt KnownZero, KnownOne;
DAG.computeKnownBits(N->getOperand(1), KnownZero, KnownOne);
KnownBits Known;
DAG.computeKnownBits(N->getOperand(1), Known);
// If we don't know anything about the high bits, exit.
if (((KnownZero|KnownOne) & HighBitMask) == 0)
if (((Known.Zero|Known.One) & HighBitMask) == 0)
return false;
// Get the incoming operand to be shifted.
@ -1538,7 +1539,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
// If we know that any of the high bits of the shift amount are one, then we
// can do this as a couple of simple shifts.
if (KnownOne.intersects(HighBitMask)) {
if (Known.One.intersects(HighBitMask)) {
// Mask out the high bit, which we know is set.
Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
DAG.getConstant(~HighBitMask, dl, ShTy));
@ -1563,7 +1564,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
// If we know that all of the high bits of the shift amount are zero, then we
// can do this as a couple of simple shifts.
if (HighBitMask.isSubsetOf(KnownZero)) {
if (HighBitMask.isSubsetOf(Known.Zero)) {
// Calculate 31-x. 31 is used instead of 32 to avoid creating an undefined
// shift if x is zero. We can use XOR here because x is known to be smaller
// than 32.

File diff suppressed because it is too large Load Diff

View File

@ -675,7 +675,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
unsigned RegSize = RegisterVT.getSizeInBits();
unsigned NumSignBits = LOI->NumSignBits;
unsigned NumZeroBits = LOI->KnownZero.countLeadingOnes();
unsigned NumZeroBits = LOI->Known.Zero.countLeadingOnes();
if (NumZeroBits == RegSize) {
// The current value is a zero.

View File

@ -73,6 +73,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
@ -650,8 +651,7 @@ void SelectionDAGISel::ComputeLiveOutVRegInfo() {
Worklist.push_back(CurDAG->getRoot().getNode());
APInt KnownZero;
APInt KnownOne;
KnownBits Known;
do {
SDNode *N = Worklist.pop_back_val();
@ -680,8 +680,8 @@ void SelectionDAGISel::ComputeLiveOutVRegInfo() {
continue;
unsigned NumSignBits = CurDAG->ComputeNumSignBits(Src);
CurDAG->computeKnownBits(Src, KnownZero, KnownOne);
FuncInfo->AddLiveOutRegInfo(DestReg, NumSignBits, KnownZero, KnownOne);
CurDAG->computeKnownBits(Src, Known);
FuncInfo->AddLiveOutRegInfo(DestReg, NumSignBits, Known);
} while (!Worklist.empty());
}
@ -1930,11 +1930,11 @@ bool SelectionDAGISel::CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
// either already zero or is not demanded. Check for known zero input bits.
APInt NeededMask = DesiredMask & ~ActualMask;
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(LHS, KnownZero, KnownOne);
KnownBits Known;
CurDAG->computeKnownBits(LHS, Known);
// If all the missing bits in the or are already known to be set, match!
if (NeededMask.isSubsetOf(KnownOne))
if (NeededMask.isSubsetOf(Known.One))
return true;
// TODO: check to see if missing bits are just not demanded.

View File

@ -27,6 +27,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@ -437,10 +438,9 @@ TargetLowering::SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
DAGCombinerInfo &DCI,
TargetLoweringOpt &TLO) const {
SDValue Op = User->getOperand(OpIdx);
APInt KnownZero, KnownOne;
KnownBits Known;
if (!SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
TLO, 0, true))
if (!SimplifyDemandedBits(Op, Demanded, Known, TLO, 0, true))
return false;
@ -488,10 +488,9 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, APInt &DemandedMask,
SelectionDAG &DAG = DCI.DAG;
TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
!DCI.isBeforeLegalizeOps());
APInt KnownZero, KnownOne;
KnownBits Known;
bool Simplified = SimplifyDemandedBits(Op, DemandedMask, KnownZero, KnownOne,
TLO);
bool Simplified = SimplifyDemandedBits(Op, DemandedMask, Known, TLO);
if (Simplified)
DCI.CommitTargetLoweringOpt(TLO);
return Simplified;
@ -501,13 +500,12 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, APInt &DemandedMask,
/// result of Op are ever used downstream. If we can use this information to
/// simplify Op, create a new simplified DAG node and return true, returning the
/// original and new nodes in Old and New. Otherwise, analyze the expression and
/// return a mask of KnownOne and KnownZero bits for the expression (used to
/// simplify the caller). The KnownZero/One bits may only be accurate for those
/// bits in the DemandedMask.
/// return a mask of Known bits for the expression (used to simplify the
/// caller). The Known bits may only be accurate for those bits in the
/// DemandedMask.
bool TargetLowering::SimplifyDemandedBits(SDValue Op,
const APInt &DemandedMask,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
TargetLoweringOpt &TLO,
unsigned Depth,
bool AssumeSingleUse) const {
@ -519,14 +517,14 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
auto &DL = TLO.DAG.getDataLayout();
// Don't know anything.
KnownZero = KnownOne = APInt(BitWidth, 0);
Known = KnownBits(BitWidth);
// Other users may use these bits.
if (!Op.getNode()->hasOneUse() && !AssumeSingleUse) {
if (Depth != 0) {
// If not at the root, Just compute the KnownZero/KnownOne bits to
// If not at the root, Just compute the Known bits to
// simplify things downstream.
TLO.DAG.computeKnownBits(Op, KnownZero, KnownOne, Depth);
TLO.DAG.computeKnownBits(Op, Known, Depth);
return false;
}
// If this is the root being simplified, allow it to have multiple uses,
@ -541,38 +539,37 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
return false;
}
APInt KnownZero2, KnownOne2, KnownZeroOut, KnownOneOut;
KnownBits Known2, KnownOut;
switch (Op.getOpcode()) {
case ISD::Constant:
// We know all of the bits for a constant!
KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue();
KnownZero = ~KnownOne;
Known.One = cast<ConstantSDNode>(Op)->getAPIntValue();
Known.Zero = ~Known.One;
return false; // Don't fall through, will infinitely loop.
case ISD::BUILD_VECTOR:
// Collect the known bits that are shared by every constant vector element.
KnownZero.setAllBits(); KnownOne.setAllBits();
Known.Zero.setAllBits(); Known.One.setAllBits();
for (SDValue SrcOp : Op->ops()) {
if (!isa<ConstantSDNode>(SrcOp)) {
// We can only handle all constant values - bail out with no known bits.
KnownZero = KnownOne = APInt(BitWidth, 0);
Known = KnownBits(BitWidth);
return false;
}
KnownOne2 = cast<ConstantSDNode>(SrcOp)->getAPIntValue();
KnownZero2 = ~KnownOne2;
Known2.One = cast<ConstantSDNode>(SrcOp)->getAPIntValue();
Known2.Zero = ~Known2.One;
// BUILD_VECTOR can implicitly truncate sources, we must handle this.
if (KnownOne2.getBitWidth() != BitWidth) {
assert(KnownOne2.getBitWidth() > BitWidth &&
KnownZero2.getBitWidth() > BitWidth &&
if (Known2.One.getBitWidth() != BitWidth) {
assert(Known2.getBitWidth() > BitWidth &&
"Expected BUILD_VECTOR implicit truncation");
KnownOne2 = KnownOne2.trunc(BitWidth);
KnownZero2 = KnownZero2.trunc(BitWidth);
Known2.One = Known2.One.trunc(BitWidth);
Known2.Zero = Known2.Zero.trunc(BitWidth);
}
// Known bits are the values that are shared by every element.
// TODO: support per-element known bits.
KnownOne &= KnownOne2;
KnownZero &= KnownZero2;
Known.One &= Known2.One;
Known.Zero &= Known2.Zero;
}
return false; // Don't fall through, will infinitely loop.
case ISD::AND:
@ -582,16 +579,16 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// the RHS.
if (ConstantSDNode *RHSC = isConstOrConstSplat(Op.getOperand(1))) {
SDValue Op0 = Op.getOperand(0);
APInt LHSZero, LHSOne;
KnownBits LHSKnown;
// Do not increment Depth here; that can cause an infinite loop.
TLO.DAG.computeKnownBits(Op0, LHSZero, LHSOne, Depth);
TLO.DAG.computeKnownBits(Op0, LHSKnown, Depth);
// If the LHS already has zeros where RHSC does, this and is dead.
if ((LHSZero & NewMask) == (~RHSC->getAPIntValue() & NewMask))
if ((LHSKnown.Zero & NewMask) == (~RHSC->getAPIntValue() & NewMask))
return TLO.CombineTo(Op, Op0);
// If any of the set bits in the RHS are known zero on the LHS, shrink
// the constant.
if (ShrinkDemandedConstant(Op, ~LHSZero & NewMask, TLO))
if (ShrinkDemandedConstant(Op, ~LHSKnown.Zero & NewMask, TLO))
return true;
// Bitwise-not (xor X, -1) is a special case: we don't usually shrink its
@ -600,58 +597,56 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// the xor. For example, for a 32-bit X:
// and (xor (srl X, 31), -1), 1 --> xor (srl X, 31), 1
if (isBitwiseNot(Op0) && Op0.hasOneUse() &&
LHSOne == ~RHSC->getAPIntValue()) {
LHSKnown.One == ~RHSC->getAPIntValue()) {
SDValue Xor = TLO.DAG.getNode(ISD::XOR, dl, Op.getValueType(),
Op0.getOperand(0), Op.getOperand(1));
return TLO.CombineTo(Op, Xor);
}
}
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,
KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op.getOperand(0), ~KnownZero & NewMask,
KnownZero2, KnownOne2, TLO, Depth+1))
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op.getOperand(0), ~Known.Zero & NewMask,
Known2, TLO, Depth+1))
return true;
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
assert((Known2.Zero & Known2.One) == 0 && "Bits known to be one AND zero?");
// If all of the demanded bits are known one on one side, return the other.
// These bits cannot contribute to the result of the 'and'.
if (NewMask.isSubsetOf(KnownZero2 | KnownOne))
if (NewMask.isSubsetOf(Known2.Zero | Known.One))
return TLO.CombineTo(Op, Op.getOperand(0));
if (NewMask.isSubsetOf(KnownZero | KnownOne2))
if (NewMask.isSubsetOf(Known.Zero | Known2.One))
return TLO.CombineTo(Op, Op.getOperand(1));
// If all of the demanded bits in the inputs are known zeros, return zero.
if (NewMask.isSubsetOf(KnownZero | KnownZero2))
if (NewMask.isSubsetOf(Known.Zero | Known2.Zero))
return TLO.CombineTo(Op, TLO.DAG.getConstant(0, dl, Op.getValueType()));
// If the RHS is a constant, see if we can simplify it.
if (ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask, TLO))
if (ShrinkDemandedConstant(Op, ~Known2.Zero & NewMask, TLO))
return true;
// If the operation can be done in a smaller type, do so.
if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// Output known-1 bits are only known if set in both the LHS & RHS.
KnownOne &= KnownOne2;
Known.One &= Known2.One;
// Output known-0 are known to be clear if zero in either the LHS | RHS.
KnownZero |= KnownZero2;
Known.Zero |= Known2.Zero;
break;
case ISD::OR:
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,
KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op.getOperand(0), ~KnownOne & NewMask,
KnownZero2, KnownOne2, TLO, Depth+1))
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op.getOperand(0), ~Known.One & NewMask,
Known2, TLO, Depth+1))
return true;
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
assert((Known2.Zero & Known2.One) == 0 && "Bits known to be one AND zero?");
// If all of the demanded bits are known zero on one side, return the other.
// These bits cannot contribute to the result of the 'or'.
if (NewMask.isSubsetOf(KnownOne2 | KnownZero))
if (NewMask.isSubsetOf(Known2.One | Known.Zero))
return TLO.CombineTo(Op, Op.getOperand(0));
if (NewMask.isSubsetOf(KnownOne | KnownZero2))
if (NewMask.isSubsetOf(Known.One | Known2.Zero))
return TLO.CombineTo(Op, Op.getOperand(1));
// If the RHS is a constant, see if we can simplify it.
if (ShrinkDemandedConstant(Op, NewMask, TLO))
@ -661,25 +656,23 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
return true;
// Output known-0 bits are only known if clear in both the LHS & RHS.
KnownZero &= KnownZero2;
Known.Zero &= Known2.Zero;
// Output known-1 are known to be set if set in either the LHS | RHS.
KnownOne |= KnownOne2;
Known.One |= Known2.One;
break;
case ISD::XOR:
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,
KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op.getOperand(0), NewMask, KnownZero2,
KnownOne2, TLO, Depth+1))
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op.getOperand(0), NewMask, Known2, TLO, Depth+1))
return true;
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
assert((Known2.Zero & Known2.One) == 0 && "Bits known to be one AND zero?");
// If all of the demanded bits are known zero on one side, return the other.
// These bits cannot contribute to the result of the 'xor'.
if (NewMask.isSubsetOf(KnownZero))
if (NewMask.isSubsetOf(Known.Zero))
return TLO.CombineTo(Op, Op.getOperand(0));
if (NewMask.isSubsetOf(KnownZero2))
if (NewMask.isSubsetOf(Known2.Zero))
return TLO.CombineTo(Op, Op.getOperand(1));
// If the operation can be done in a smaller type, do so.
if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
@ -688,25 +681,25 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If all of the unknown bits are known to be zero on one side or the other
// (but not both) turn this into an *inclusive* or.
// e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
if ((NewMask & ~KnownZero & ~KnownZero2) == 0)
if ((NewMask & ~Known.Zero & ~Known2.Zero) == 0)
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, dl, Op.getValueType(),
Op.getOperand(0),
Op.getOperand(1)));
// Output known-0 bits are known if clear or set in both the LHS & RHS.
KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
KnownOut.Zero = (Known.Zero & Known2.Zero) | (Known.One & Known2.One);
// Output known-1 are known to be set if set in only one of the LHS, RHS.
KnownOneOut = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
KnownOut.One = (Known.Zero & Known2.One) | (Known.One & Known2.Zero);
// If all of the demanded bits on one side are known, and all of the set
// bits on that side are also known to be set on the other side, turn this
// into an AND, as we know the bits will be cleared.
// e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
// NB: it is okay if more bits are known than are requested
if (NewMask.isSubsetOf(KnownZero|KnownOne)) { // all known on one side
if (KnownOne == KnownOne2) { // set bits are the same on both sides
if (NewMask.isSubsetOf(Known.Zero|Known.One)) { // all known on one side
if (Known.One == Known2.One) { // set bits are the same on both sides
EVT VT = Op.getValueType();
SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, dl, VT);
SDValue ANDC = TLO.DAG.getConstant(~Known.One & NewMask, dl, VT);
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT,
Op.getOperand(0), ANDC));
}
@ -732,44 +725,39 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
}
KnownZero = std::move(KnownZeroOut);
KnownOne = std::move(KnownOneOut);
Known = std::move(KnownOut);
break;
case ISD::SELECT:
if (SimplifyDemandedBits(Op.getOperand(2), NewMask, KnownZero,
KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(2), NewMask, Known, TLO, Depth+1))
return true;
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero2,
KnownOne2, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(1), NewMask, Known2, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
assert((Known2.Zero & Known2.One) == 0 && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// Only known if known in both the LHS and RHS.
KnownOne &= KnownOne2;
KnownZero &= KnownZero2;
Known.One &= Known2.One;
Known.Zero &= Known2.Zero;
break;
case ISD::SELECT_CC:
if (SimplifyDemandedBits(Op.getOperand(3), NewMask, KnownZero,
KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(3), NewMask, Known, TLO, Depth+1))
return true;
if (SimplifyDemandedBits(Op.getOperand(2), NewMask, KnownZero2,
KnownOne2, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(2), NewMask, Known2, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
assert((Known2.Zero & Known2.One) == 0 && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// Only known if known in both the LHS and RHS.
KnownOne &= KnownOne2;
KnownZero &= KnownZero2;
Known.One &= Known2.One;
Known.Zero &= Known2.Zero;
break;
case ISD::SETCC: {
SDValue Op0 = Op.getOperand(0);
@ -795,7 +783,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if (getBooleanContents(Op0.getValueType()) ==
TargetLowering::ZeroOrOneBooleanContent &&
BitWidth > 1)
KnownZero.setBitsFrom(1);
Known.Zero.setBitsFrom(1);
break;
}
case ISD::SHL:
@ -829,8 +817,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
}
if (SimplifyDemandedBits(InOp, NewMask.lshr(ShAmt),
KnownZero, KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(InOp, NewMask.lshr(ShAmt), Known, TLO, Depth+1))
return true;
// Convert (shl (anyext x, c)) to (anyext (shl x, c)) if the high bits
@ -879,10 +866,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
}
KnownZero <<= SA->getZExtValue();
KnownOne <<= SA->getZExtValue();
Known.Zero <<= SA->getZExtValue();
Known.One <<= SA->getZExtValue();
// low bits known zero.
KnownZero.setLowBits(SA->getZExtValue());
Known.Zero.setLowBits(SA->getZExtValue());
}
break;
case ISD::SRL:
@ -925,14 +912,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
// Compute the new bits that are at the top now.
if (SimplifyDemandedBits(InOp, InDemandedMask,
KnownZero, KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(InOp, InDemandedMask, Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero.lshrInPlace(ShAmt);
KnownOne.lshrInPlace(ShAmt);
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
Known.Zero.lshrInPlace(ShAmt);
Known.One.lshrInPlace(ShAmt);
KnownZero.setHighBits(ShAmt); // High bits known zero.
Known.Zero.setHighBits(ShAmt); // High bits known zero.
}
break;
case ISD::SRA:
@ -965,16 +951,16 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if (NewMask.countLeadingZeros() < ShAmt)
InDemandedMask.setSignBit();
if (SimplifyDemandedBits(Op.getOperand(0), InDemandedMask,
KnownZero, KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(0), InDemandedMask, Known, TLO,
Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero.lshrInPlace(ShAmt);
KnownOne.lshrInPlace(ShAmt);
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
Known.Zero.lshrInPlace(ShAmt);
Known.One.lshrInPlace(ShAmt);
// If the input sign bit is known to be zero, or if none of the top bits
// are demanded, turn this into an unsigned shift right.
if (KnownZero[BitWidth - ShAmt - 1] ||
if (Known.Zero[BitWidth - ShAmt - 1] ||
NewMask.countLeadingZeros() >= ShAmt) {
SDNodeFlags Flags;
Flags.setExact(cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact());
@ -993,9 +979,9 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
Op.getOperand(0), NewSA));
}
if (KnownOne[BitWidth - ShAmt - 1])
if (Known.One[BitWidth - ShAmt - 1])
// New bits are known one.
KnownOne.setHighBits(ShAmt);
Known.One.setHighBits(ShAmt);
}
break;
case ISD::SIGN_EXTEND_INREG: {
@ -1048,24 +1034,24 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
InputDemandedBits |= InSignBit;
if (SimplifyDemandedBits(Op.getOperand(0), InputDemandedBits,
KnownZero, KnownOne, TLO, Depth+1))
Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
// If the sign bit of the input is known set or clear, then we know the
// top bits of the result.
// If the input sign bit is known zero, convert this into a zero extension.
if (KnownZero.intersects(InSignBit))
if (Known.Zero.intersects(InSignBit))
return TLO.CombineTo(Op, TLO.DAG.getZeroExtendInReg(
Op.getOperand(0), dl, ExVT.getScalarType()));
if (KnownOne.intersects(InSignBit)) { // Input sign bit known set
KnownOne |= NewBits;
KnownZero &= ~NewBits;
if (Known.One.intersects(InSignBit)) { // Input sign bit known set
Known.One |= NewBits;
Known.Zero &= ~NewBits;
} else { // Input sign bit unknown
KnownZero &= ~NewBits;
KnownOne &= ~NewBits;
Known.Zero &= ~NewBits;
Known.One &= ~NewBits;
}
break;
}
@ -1076,22 +1062,19 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
APInt MaskLo = NewMask.getLoBits(HalfBitWidth).trunc(HalfBitWidth);
APInt MaskHi = NewMask.getHiBits(HalfBitWidth).trunc(HalfBitWidth);
APInt KnownZeroLo, KnownOneLo;
APInt KnownZeroHi, KnownOneHi;
KnownBits KnownLo, KnownHi;
if (SimplifyDemandedBits(Op.getOperand(0), MaskLo, KnownZeroLo,
KnownOneLo, TLO, Depth + 1))
if (SimplifyDemandedBits(Op.getOperand(0), MaskLo, KnownLo, TLO, Depth + 1))
return true;
if (SimplifyDemandedBits(Op.getOperand(1), MaskHi, KnownZeroHi,
KnownOneHi, TLO, Depth + 1))
if (SimplifyDemandedBits(Op.getOperand(1), MaskHi, KnownHi, TLO, Depth + 1))
return true;
KnownZero = KnownZeroLo.zext(BitWidth) |
KnownZeroHi.zext(BitWidth).shl(HalfBitWidth);
Known.Zero = KnownLo.Zero.zext(BitWidth) |
KnownHi.Zero.zext(BitWidth).shl(HalfBitWidth);
KnownOne = KnownOneLo.zext(BitWidth) |
KnownOneHi.zext(BitWidth).shl(HalfBitWidth);
Known.One = KnownLo.One.zext(BitWidth) |
KnownHi.One.zext(BitWidth).shl(HalfBitWidth);
break;
}
case ISD::ZERO_EXTEND: {
@ -1106,13 +1089,12 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
Op.getValueType(),
Op.getOperand(0)));
if (SimplifyDemandedBits(Op.getOperand(0), InMask,
KnownZero, KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(0), InMask, Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero = KnownZero.zext(BitWidth);
KnownOne = KnownOne.zext(BitWidth);
KnownZero |= NewBits;
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
Known.Zero = Known.Zero.zext(BitWidth);
Known.One = Known.One.zext(BitWidth);
Known.Zero |= NewBits;
break;
}
case ISD::SIGN_EXTEND: {
@ -1134,37 +1116,36 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
InDemandedBits |= InSignBit;
InDemandedBits = InDemandedBits.trunc(InBits);
if (SimplifyDemandedBits(Op.getOperand(0), InDemandedBits, KnownZero,
KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(0), InDemandedBits, Known, TLO,
Depth+1))
return true;
KnownZero = KnownZero.zext(BitWidth);
KnownOne = KnownOne.zext(BitWidth);
Known.Zero = Known.Zero.zext(BitWidth);
Known.One = Known.One.zext(BitWidth);
// If the sign bit is known zero, convert this to a zero extend.
if (KnownZero.intersects(InSignBit))
if (Known.Zero.intersects(InSignBit))
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, dl,
Op.getValueType(),
Op.getOperand(0)));
// If the sign bit is known one, the top bits match.
if (KnownOne.intersects(InSignBit)) {
KnownOne |= NewBits;
assert((KnownZero & NewBits) == 0);
if (Known.One.intersects(InSignBit)) {
Known.One |= NewBits;
assert((Known.Zero & NewBits) == 0);
} else { // Otherwise, top bits aren't known.
assert((KnownOne & NewBits) == 0);
assert((KnownZero & NewBits) == 0);
assert((Known.One & NewBits) == 0);
assert((Known.Zero & NewBits) == 0);
}
break;
}
case ISD::ANY_EXTEND: {
unsigned OperandBitWidth = Op.getOperand(0).getScalarValueSizeInBits();
APInt InMask = NewMask.trunc(OperandBitWidth);
if (SimplifyDemandedBits(Op.getOperand(0), InMask,
KnownZero, KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(0), InMask, Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero = KnownZero.zext(BitWidth);
KnownOne = KnownOne.zext(BitWidth);
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
Known.Zero = Known.Zero.zext(BitWidth);
Known.One = Known.One.zext(BitWidth);
break;
}
case ISD::TRUNCATE: {
@ -1172,11 +1153,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// zero/one bits live out.
unsigned OperandBitWidth = Op.getOperand(0).getScalarValueSizeInBits();
APInt TruncMask = NewMask.zext(OperandBitWidth);
if (SimplifyDemandedBits(Op.getOperand(0), TruncMask,
KnownZero, KnownOne, TLO, Depth+1))
if (SimplifyDemandedBits(Op.getOperand(0), TruncMask, Known, TLO, Depth+1))
return true;
KnownZero = KnownZero.trunc(BitWidth);
KnownOne = KnownOne.trunc(BitWidth);
Known.Zero = Known.Zero.trunc(BitWidth);
Known.One = Known.One.trunc(BitWidth);
// If the input is only used by this truncate, see if we can shrink it based
// on the known demanded bits.
@ -1224,7 +1204,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
}
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
break;
}
case ISD::AssertZext: {
@ -1234,11 +1214,11 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
APInt InMask = APInt::getLowBitsSet(BitWidth,
VT.getSizeInBits());
if (SimplifyDemandedBits(Op.getOperand(0), ~InMask | NewMask,
KnownZero, KnownOne, TLO, Depth+1))
Known, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
KnownZero |= ~InMask;
Known.Zero |= ~InMask;
break;
}
case ISD::BITCAST:
@ -1276,10 +1256,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// of the highest bit demanded of them.
APInt LoMask = APInt::getLowBitsSet(BitWidth,
BitWidth - NewMask.countLeadingZeros());
if (SimplifyDemandedBits(Op.getOperand(0), LoMask, KnownZero2,
KnownOne2, TLO, Depth+1) ||
SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2,
KnownOne2, TLO, Depth+1) ||
if (SimplifyDemandedBits(Op.getOperand(0), LoMask, Known2, TLO, Depth+1) ||
SimplifyDemandedBits(Op.getOperand(1), LoMask, Known2, TLO, Depth+1) ||
// See if the operation should be performed at a smaller bit width.
ShrinkDemandedOp(Op, BitWidth, NewMask, TLO)) {
const SDNodeFlags *Flags = Op.getNode()->getFlags();
@ -1300,13 +1278,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
default:
// Just use computeKnownBits to compute output bits.
TLO.DAG.computeKnownBits(Op, KnownZero, KnownOne, Depth);
TLO.DAG.computeKnownBits(Op, Known, Depth);
break;
}
// If we know the value of all of the demanded bits, return this as a
// constant.
if (NewMask.isSubsetOf(KnownZero|KnownOne)) {
if (NewMask.isSubsetOf(Known.Zero|Known.One)) {
// Avoid folding to a constant if any OpaqueConstant is involved.
const SDNode *N = Op.getNode();
for (SDNodeIterator I = SDNodeIterator::begin(N),
@ -1317,17 +1295,16 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
return false;
}
return TLO.CombineTo(Op,
TLO.DAG.getConstant(KnownOne, dl, Op.getValueType()));
TLO.DAG.getConstant(Known.One, dl, Op.getValueType()));
}
return false;
}
/// Determine which of the bits specified in Mask are known to be either zero or
/// one and return them in the KnownZero/KnownOne bitsets.
/// one and return them in the Known.
void TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const {
@ -1337,7 +1314,7 @@ void TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
Op.getOpcode() == ISD::INTRINSIC_VOID) &&
"Should use MaskedValueIsZero if you don't know whether Op"
" is a target node!");
KnownZero.clearAllBits(); KnownOne.clearAllBits();
Known.Zero.clearAllBits(); Known.One.clearAllBits();
}
/// This method can be implemented by targets that want to expose additional

View File

@ -20,6 +20,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@ -2078,18 +2079,18 @@ static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op,
(void)BitWidth;
assert(BitWidth == 32 || BitWidth == 64);
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(Op, KnownZero, KnownOne);
KnownBits Known;
CurDAG->computeKnownBits(Op, Known);
// Non-zero in the sense that they're not provably zero, which is the key
// point if we want to use this value
uint64_t NonZeroBits = (~KnownZero).getZExtValue();
uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
// Discard a constant AND mask if present. It's safe because the node will
// already have been factored into the computeKnownBits calculation above.
uint64_t AndImm;
if (isOpcWithIntImmediate(Op.getNode(), ISD::AND, AndImm)) {
assert((~APInt(BitWidth, AndImm) & ~KnownZero) == 0);
assert((~APInt(BitWidth, AndImm) & ~Known.Zero) == 0);
Op = Op.getOperand(0);
}
@ -2158,15 +2159,15 @@ static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG) {
// Compute the Known Zero for the AND as this allows us to catch more general
// cases than just looking for AND with imm.
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(And, KnownZero, KnownOne);
KnownBits Known;
CurDAG->computeKnownBits(And, Known);
// Non-zero in the sense that they're not provably zero, which is the key
// point if we want to use this value.
uint64_t NotKnownZero = (~KnownZero).getZExtValue();
uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
// The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
if (!isShiftedMask(KnownZero.getZExtValue(), VT))
if (!isShiftedMask(Known.Zero.getZExtValue(), VT))
return false;
// The bits being inserted must only set those bits that are known to be zero.
@ -2300,15 +2301,15 @@ static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits,
// This allows to catch more general case than just looking for
// AND with imm. Indeed, simplify-demanded-bits may have removed
// the AND instruction because it proves it was useless.
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(OrOpd1Val, KnownZero, KnownOne);
KnownBits Known;
CurDAG->computeKnownBits(OrOpd1Val, Known);
// Check if there is enough room for the second operand to appear
// in the first one
APInt BitsToBeInserted =
APInt::getBitsSet(KnownZero.getBitWidth(), DstLSB, DstLSB + Width);
APInt::getBitsSet(Known.getBitWidth(), DstLSB, DstLSB + Width);
if ((BitsToBeInserted & ~KnownZero) != 0)
if ((BitsToBeInserted & ~Known.Zero) != 0)
continue;
// Set the first operand

View File

@ -67,6 +67,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetCallingConv.h"
@ -929,20 +930,19 @@ bool AArch64TargetLowering::targetShrinkDemandedConstant(
}
/// computeKnownBitsForTargetNode - Determine which of the bits specified in
/// Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
/// Mask are known to be either zero or one and return them Known.
void AArch64TargetLowering::computeKnownBitsForTargetNode(
const SDValue Op, APInt &KnownZero, APInt &KnownOne,
const SDValue Op, KnownBits &Known,
const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const {
switch (Op.getOpcode()) {
default:
break;
case AArch64ISD::CSEL: {
APInt KnownZero2, KnownOne2;
DAG.computeKnownBits(Op->getOperand(0), KnownZero, KnownOne, Depth + 1);
DAG.computeKnownBits(Op->getOperand(1), KnownZero2, KnownOne2, Depth + 1);
KnownZero &= KnownZero2;
KnownOne &= KnownOne2;
KnownBits Known2;
DAG.computeKnownBits(Op->getOperand(0), Known, Depth + 1);
DAG.computeKnownBits(Op->getOperand(1), Known2, Depth + 1);
Known.Zero &= Known2.Zero;
Known.One &= Known2.One;
break;
}
case ISD::INTRINSIC_W_CHAIN: {
@ -952,10 +952,10 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
default: return;
case Intrinsic::aarch64_ldaxr:
case Intrinsic::aarch64_ldxr: {
unsigned BitWidth = KnownOne.getBitWidth();
unsigned BitWidth = Known.getBitWidth();
EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
unsigned MemBits = VT.getScalarSizeInBits();
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
return;
}
}
@ -974,15 +974,15 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
// bits larger than the element datatype. 32-bit or larget doesn't need
// this as those are legal types and will be handled by isel directly.
MVT VT = Op.getOperand(1).getValueType().getSimpleVT();
unsigned BitWidth = KnownZero.getBitWidth();
unsigned BitWidth = Known.getBitWidth();
if (VT == MVT::v8i8 || VT == MVT::v16i8) {
assert(BitWidth >= 8 && "Unexpected width!");
APInt Mask = APInt::getHighBitsSet(BitWidth, BitWidth - 8);
KnownZero |= Mask;
Known.Zero |= Mask;
} else if (VT == MVT::v4i16 || VT == MVT::v8i16) {
assert(BitWidth >= 16 && "Unexpected width!");
APInt Mask = APInt::getHighBitsSet(BitWidth, BitWidth - 16);
KnownZero |= Mask;
Known.Zero |= Mask;
}
break;
} break;
@ -9461,11 +9461,11 @@ static bool performTBISimplification(SDValue Addr,
TargetLowering::DAGCombinerInfo &DCI,
SelectionDAG &DAG) {
APInt DemandedMask = APInt::getLowBitsSet(64, 56);
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, DCI.isBeforeLegalize(),
DCI.isBeforeLegalizeOps());
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.SimplifyDemandedBits(Addr, DemandedMask, KnownZero, KnownOne, TLO)) {
if (TLI.SimplifyDemandedBits(Addr, DemandedMask, Known, TLO)) {
DCI.CommitTargetLoweringOpt(TLO);
return true;
}

View File

@ -250,8 +250,8 @@ public:
/// Determine which of the bits specified in Mask are known to be either zero
/// or one and return them in the KnownZero/KnownOne bitsets.
void computeKnownBitsForTargetNode(const SDValue Op, APInt &KnownZero,
APInt &KnownOne, const APInt &DemandedElts,
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const override;

View File

@ -29,6 +29,7 @@
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/Support/KnownBits.h"
#include "SIInstrInfo.h"
using namespace llvm;
@ -2293,11 +2294,11 @@ SDValue AMDGPUTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
//===----------------------------------------------------------------------===//
static bool isU24(SDValue Op, SelectionDAG &DAG) {
APInt KnownZero, KnownOne;
KnownBits Known;
EVT VT = Op.getValueType();
DAG.computeKnownBits(Op, KnownZero, KnownOne);
DAG.computeKnownBits(Op, Known);
return (VT.getSizeInBits() - KnownZero.countLeadingOnes()) <= 24;
return (VT.getSizeInBits() - Known.Zero.countLeadingOnes()) <= 24;
}
static bool isI24(SDValue Op, SelectionDAG &DAG) {
@ -3358,13 +3359,12 @@ SDValue AMDGPUTargetLowering::PerformDAGCombine(SDNode *N,
OffsetVal,
OffsetVal + WidthVal);
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
!DCI.isBeforeLegalizeOps());
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.ShrinkDemandedConstant(BitsFrom, Demanded, TLO) ||
TLI.SimplifyDemandedBits(BitsFrom, Demanded,
KnownZero, KnownOne, TLO)) {
TLI.SimplifyDemandedBits(BitsFrom, Demanded, Known, TLO)) {
DCI.CommitTargetLoweringOpt(TLO);
}
}
@ -3574,14 +3574,12 @@ SDValue AMDGPUTargetLowering::getRecipEstimate(SDValue Operand,
}
void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
const SDValue Op, APInt &KnownZero, APInt &KnownOne,
const SDValue Op, KnownBits &Known,
const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const {
unsigned BitWidth = KnownZero.getBitWidth();
KnownZero = KnownOne = APInt(BitWidth, 0); // Don't know anything.
Known.Zero.clearAllBits(); Known.One.clearAllBits(); // Don't know anything.
APInt KnownZero2;
APInt KnownOne2;
KnownBits Known2;
unsigned Opc = Op.getOpcode();
switch (Opc) {
@ -3589,7 +3587,7 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
break;
case AMDGPUISD::CARRY:
case AMDGPUISD::BORROW: {
KnownZero = APInt::getHighBitsSet(32, 31);
Known.Zero = APInt::getHighBitsSet(32, 31);
break;
}
@ -3602,16 +3600,16 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
uint32_t Width = CWidth->getZExtValue() & 0x1f;
if (Opc == AMDGPUISD::BFE_U32)
KnownZero = APInt::getHighBitsSet(32, 32 - Width);
Known.Zero = APInt::getHighBitsSet(32, 32 - Width);
break;
}
case AMDGPUISD::FP_TO_FP16:
case AMDGPUISD::FP16_ZEXT: {
unsigned BitWidth = KnownZero.getBitWidth();
unsigned BitWidth = Known.getBitWidth();
// High bits are zero.
KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - 16);
Known.Zero = APInt::getHighBitsSet(BitWidth, BitWidth - 16);
break;
}
}

View File

@ -199,8 +199,7 @@ public:
/// either zero or one and return them in the \p KnownZero and \p KnownOne
/// bitsets.
void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const override;

View File

@ -68,6 +68,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetOptions.h"
@ -4706,12 +4707,12 @@ SDValue SITargetLowering::performCvtF32UByteNCombine(SDNode *N,
APInt Demanded = APInt::getBitsSet(32, 8 * Offset, 8 * Offset + 8);
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
!DCI.isBeforeLegalizeOps());
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.ShrinkDemandedConstant(Src, Demanded, TLO) ||
TLI.SimplifyDemandedBits(Src, Demanded, KnownZero, KnownOne, TLO)) {
TLI.SimplifyDemandedBits(Src, Demanded, Known, TLO)) {
DCI.CommitTargetLoweringOpt(TLO);
}

View File

@ -91,6 +91,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
@ -11758,9 +11759,9 @@ SDValue ARMTargetLowering::PerformCMOVToBFICombine(SDNode *CMOV, SelectionDAG &D
// Lastly, can we determine that the bits defined by OrCI
// are zero in Y?
APInt KnownZero, KnownOne;
DAG.computeKnownBits(Y, KnownZero, KnownOne);
if ((OrCI & KnownZero) != OrCI)
KnownBits Known;
DAG.computeKnownBits(Y, Known);
if ((OrCI & Known.Zero) != OrCI)
return SDValue();
// OK, we can do the combine.
@ -11898,16 +11899,16 @@ ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const {
}
if (Res.getNode()) {
APInt KnownZero, KnownOne;
DAG.computeKnownBits(SDValue(N,0), KnownZero, KnownOne);
KnownBits Known;
DAG.computeKnownBits(SDValue(N,0), Known);
// Capture demanded bits information that would be otherwise lost.
if (KnownZero == 0xfffffffe)
if (Known.Zero == 0xfffffffe)
Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
DAG.getValueType(MVT::i1));
else if (KnownZero == 0xffffff00)
else if (Known.Zero == 0xffffff00)
Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
DAG.getValueType(MVT::i8));
else if (KnownZero == 0xffff0000)
else if (Known.Zero == 0xffff0000)
Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
DAG.getValueType(MVT::i16));
}
@ -12596,13 +12597,12 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
}
void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const {
unsigned BitWidth = KnownOne.getBitWidth();
KnownZero = KnownOne = APInt(BitWidth, 0);
unsigned BitWidth = Known.getBitWidth();
Known.Zero.clearAllBits(); Known.One.clearAllBits();
switch (Op.getOpcode()) {
default: break;
case ARMISD::ADDC:
@ -12612,17 +12612,17 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
// These nodes' second result is a boolean
if (Op.getResNo() == 0)
break;
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
break;
case ARMISD::CMOV: {
// Bits are known zero/one if known on the LHS and RHS.
DAG.computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
if (KnownZero == 0 && KnownOne == 0) return;
DAG.computeKnownBits(Op.getOperand(0), Known, Depth+1);
if (Known.Zero == 0 && Known.One == 0) return;
APInt KnownZeroRHS, KnownOneRHS;
DAG.computeKnownBits(Op.getOperand(1), KnownZeroRHS, KnownOneRHS, Depth+1);
KnownZero &= KnownZeroRHS;
KnownOne &= KnownOneRHS;
KnownBits KnownRHS;
DAG.computeKnownBits(Op.getOperand(1), KnownRHS, Depth+1);
Known.Zero &= KnownRHS.Zero;
Known.One &= KnownRHS.One;
return;
}
case ISD::INTRINSIC_W_CHAIN: {
@ -12634,7 +12634,7 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
case Intrinsic::arm_ldrex: {
EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
unsigned MemBits = VT.getScalarSizeInBits();
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
return;
}
}
@ -12642,14 +12642,14 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
case ARMISD::BFI: {
// Conservatively, we can recurse down the first operand
// and just mask out all affected bits.
DAG.computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth + 1);
DAG.computeKnownBits(Op.getOperand(0), Known, Depth + 1);
// The operand to BFI is already a mask suitable for removing the bits it
// sets.
ConstantSDNode *CI = cast<ConstantSDNode>(Op.getOperand(2));
const APInt &Mask = CI->getAPIntValue();
KnownZero &= Mask;
KnownOne &= Mask;
Known.Zero &= Mask;
Known.One &= Mask;
return;
}
}

View File

@ -350,8 +350,7 @@ class InstrItineraryData;
SDValue &Offset, ISD::MemIndexedMode &AM,
SelectionDAG &DAG) const override;
void computeKnownBitsForTargetNode(const SDValue Op, APInt &KnownZero,
APInt &KnownOne,
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const override;

View File

@ -49,6 +49,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
@ -542,12 +543,12 @@ bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *N) {
SDValue Op1 = N->getOperand(1);
SDLoc dl(N);
APInt LKZ, LKO, RKZ, RKO;
CurDAG->computeKnownBits(Op0, LKZ, LKO);
CurDAG->computeKnownBits(Op1, RKZ, RKO);
KnownBits LKnown, RKnown;
CurDAG->computeKnownBits(Op0, LKnown);
CurDAG->computeKnownBits(Op1, RKnown);
unsigned TargetMask = LKZ.getZExtValue();
unsigned InsertMask = RKZ.getZExtValue();
unsigned TargetMask = LKnown.Zero.getZExtValue();
unsigned InsertMask = RKnown.Zero.getZExtValue();
if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
unsigned Op0Opc = Op0.getOpcode();
@ -590,9 +591,9 @@ bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *N) {
// The AND mask might not be a constant, and we need to make sure that
// if we're going to fold the masking with the insert, all bits not
// know to be zero in the mask are known to be one.
APInt MKZ, MKO;
CurDAG->computeKnownBits(Op1.getOperand(1), MKZ, MKO);
bool CanFoldMask = InsertMask == MKO.getZExtValue();
KnownBits MKnown;
CurDAG->computeKnownBits(Op1.getOperand(1), MKnown);
bool CanFoldMask = InsertMask == MKnown.One.getZExtValue();
unsigned SHOpc = Op1.getOperand(0).getOpcode();
if ((SHOpc == ISD::SHL || SHOpc == ISD::SRL) && CanFoldMask &&
@ -2772,12 +2773,12 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
short Imm;
if (N->getOperand(0)->getOpcode() == ISD::FrameIndex &&
isIntS16Immediate(N->getOperand(1), Imm)) {
APInt LHSKnownZero, LHSKnownOne;
CurDAG->computeKnownBits(N->getOperand(0), LHSKnownZero, LHSKnownOne);
KnownBits LHSKnown;
CurDAG->computeKnownBits(N->getOperand(0), LHSKnown);
// If this is equivalent to an add, then we can fold it with the
// FrameIndex calculation.
if ((LHSKnownZero.getZExtValue()|~(uint64_t)Imm) == ~0ULL) {
if ((LHSKnown.Zero.getZExtValue()|~(uint64_t)Imm) == ~0ULL) {
selectFrameIndex(N, N->getOperand(0).getNode(), (int)Imm);
return;
}

View File

@ -79,6 +79,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
@ -1847,17 +1848,14 @@ bool PPCTargetLowering::SelectAddressRegReg(SDValue N, SDValue &Base,
// If this is an or of disjoint bitfields, we can codegen this as an add
// (for better address arithmetic) if the LHS and RHS of the OR are provably
// disjoint.
APInt LHSKnownZero, LHSKnownOne;
APInt RHSKnownZero, RHSKnownOne;
DAG.computeKnownBits(N.getOperand(0),
LHSKnownZero, LHSKnownOne);
KnownBits LHSKnown, RHSKnown;
DAG.computeKnownBits(N.getOperand(0), LHSKnown);
if (LHSKnownZero.getBoolValue()) {
DAG.computeKnownBits(N.getOperand(1),
RHSKnownZero, RHSKnownOne);
if (LHSKnown.Zero.getBoolValue()) {
DAG.computeKnownBits(N.getOperand(1), RHSKnown);
// If all of the bits are known zero on the LHS or RHS, the add won't
// carry.
if (~(LHSKnownZero | RHSKnownZero) == 0) {
if (~(LHSKnown.Zero | RHSKnown.Zero) == 0) {
Base = N.getOperand(0);
Index = N.getOperand(1);
return true;
@ -1953,10 +1951,10 @@ bool PPCTargetLowering::SelectAddressRegImm(SDValue N, SDValue &Disp,
// If this is an or of disjoint bitfields, we can codegen this as an add
// (for better address arithmetic) if the LHS and RHS of the OR are
// provably disjoint.
APInt LHSKnownZero, LHSKnownOne;
DAG.computeKnownBits(N.getOperand(0), LHSKnownZero, LHSKnownOne);
KnownBits LHSKnown;
DAG.computeKnownBits(N.getOperand(0), LHSKnown);
if ((LHSKnownZero.getZExtValue()|~(uint64_t)imm) == ~0ULL) {
if ((LHSKnown.Zero.getZExtValue()|~(uint64_t)imm) == ~0ULL) {
// If all of the bits are known zero on the LHS or RHS, the add won't
// carry.
if (FrameIndexSDNode *FI =
@ -10318,17 +10316,16 @@ SDValue PPCTargetLowering::DAGCombineTruncBoolExt(SDNode *N,
} else {
// This is neither a signed nor an unsigned comparison, just make sure
// that the high bits are equal.
APInt Op1Zero, Op1One;
APInt Op2Zero, Op2One;
DAG.computeKnownBits(N->getOperand(0), Op1Zero, Op1One);
DAG.computeKnownBits(N->getOperand(1), Op2Zero, Op2One);
KnownBits Op1Known, Op2Known;
DAG.computeKnownBits(N->getOperand(0), Op1Known);
DAG.computeKnownBits(N->getOperand(1), Op2Known);
// We don't really care about what is known about the first bit (if
// anything), so clear it in all masks prior to comparing them.
Op1Zero.clearBit(0); Op1One.clearBit(0);
Op2Zero.clearBit(0); Op2One.clearBit(0);
Op1Known.Zero.clearBit(0); Op1Known.One.clearBit(0);
Op2Known.Zero.clearBit(0); Op2Known.One.clearBit(0);
if (Op1Zero != Op2Zero || Op1One != Op2One)
if (Op1Known.Zero != Op2Known.Zero || Op1Known.One != Op2Known.One)
return SDValue();
}
}
@ -12015,18 +12012,17 @@ PPCTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
//===----------------------------------------------------------------------===//
void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const {
KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0);
Known.Zero.clearAllBits(); Known.One.clearAllBits();
switch (Op.getOpcode()) {
default: break;
case PPCISD::LBRX: {
// lhbrx is known to have the top bits cleared out.
if (cast<VTSDNode>(Op.getOperand(2))->getVT() == MVT::i16)
KnownZero = 0xFFFF0000;
Known.Zero = 0xFFFF0000;
break;
}
case ISD::INTRINSIC_WO_CHAIN: {
@ -12048,7 +12044,7 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
case Intrinsic::ppc_altivec_vcmpgtuh_p:
case Intrinsic::ppc_altivec_vcmpgtuw_p:
case Intrinsic::ppc_altivec_vcmpgtud_p:
KnownZero = ~1U; // All bits but the low one are known to be zero.
Known.Zero = ~1U; // All bits but the low one are known to be zero.
break;
}
}

View File

@ -606,8 +606,7 @@ namespace llvm {
SelectionDAG &DAG) const override;
void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const override;

View File

@ -30,6 +30,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
using namespace llvm;
@ -1875,25 +1876,24 @@ EVT SparcTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
/// combiner.
void SparcTargetLowering::computeKnownBitsForTargetNode
(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const {
APInt KnownZero2, KnownOne2;
KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0);
KnownBits Known2;
Known.Zero.clearAllBits(); Known.One.clearAllBits();
switch (Op.getOpcode()) {
default: break;
case SPISD::SELECT_ICC:
case SPISD::SELECT_XCC:
case SPISD::SELECT_FCC:
DAG.computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
DAG.computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
DAG.computeKnownBits(Op.getOperand(1), Known, Depth+1);
DAG.computeKnownBits(Op.getOperand(0), Known2, Depth+1);
// Only known if known in both the LHS and RHS.
KnownOne &= KnownOne2;
KnownZero &= KnownZero2;
Known.One &= Known2.One;
Known.Zero &= Known2.Zero;
break;
}
}

View File

@ -66,8 +66,7 @@ namespace llvm {
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const override;

View File

@ -15,6 +15,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@ -711,9 +712,9 @@ bool SystemZDAGToDAGISel::detectOrAndInsertion(SDValue &Op,
// The inner check covers all cases but is more expensive.
uint64_t Used = allOnes(Op.getValueSizeInBits());
if (Used != (AndMask | InsertMask)) {
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(Op.getOperand(0), KnownZero, KnownOne);
if (Used != (AndMask | InsertMask | KnownZero.getZExtValue()))
KnownBits Known;
CurDAG->computeKnownBits(Op.getOperand(0), Known);
if (Used != (AndMask | InsertMask | Known.Zero.getZExtValue()))
return false;
}
@ -770,9 +771,9 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
// If some bits of Input are already known zeros, those bits will have
// been removed from the mask. See if adding them back in makes the
// mask suitable.
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(Input, KnownZero, KnownOne);
Mask |= KnownZero.getZExtValue();
KnownBits Known;
CurDAG->computeKnownBits(Input, Known);
Mask |= Known.Zero.getZExtValue();
if (!refineRxSBGMask(RxSBG, Mask))
return false;
}
@ -794,9 +795,9 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
// If some bits of Input are already known ones, those bits will have
// been removed from the mask. See if adding them back in makes the
// mask suitable.
APInt KnownZero, KnownOne;
CurDAG->computeKnownBits(Input, KnownZero, KnownOne);
Mask &= ~KnownOne.getZExtValue();
KnownBits Known;
CurDAG->computeKnownBits(Input, Known);
Mask &= ~Known.One.getZExtValue();
if (!refineRxSBGMask(RxSBG, Mask))
return false;
}

View File

@ -20,8 +20,9 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/KnownBits.h"
#include <cctype>
using namespace llvm;
@ -3066,14 +3067,14 @@ SDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const {
// Get the known-zero masks for each operand.
SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1) };
APInt KnownZero[2], KnownOne[2];
DAG.computeKnownBits(Ops[0], KnownZero[0], KnownOne[0]);
DAG.computeKnownBits(Ops[1], KnownZero[1], KnownOne[1]);
KnownBits Known[2];
DAG.computeKnownBits(Ops[0], Known[0]);
DAG.computeKnownBits(Ops[1], Known[1]);
// See if the upper 32 bits of one operand and the lower 32 bits of the
// other are known zero. They are the low and high operands respectively.
uint64_t Masks[] = { KnownZero[0].getZExtValue(),
KnownZero[1].getZExtValue() };
uint64_t Masks[] = { Known[0].Zero.getZExtValue(),
Known[1].Zero.getZExtValue() };
unsigned High, Low;
if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
High = 1, Low = 0;
@ -3158,9 +3159,9 @@ SDValue SystemZTargetLowering::lowerCTPOP(SDValue Op,
}
// Get the known-zero mask for the operand.
APInt KnownZero, KnownOne;
DAG.computeKnownBits(Op, KnownZero, KnownOne);
unsigned NumSignificantBits = (~KnownZero).getActiveBits();
KnownBits Known;
DAG.computeKnownBits(Op, Known);
unsigned NumSignificantBits = (~Known.Zero).getActiveBits();
if (NumSignificantBits == 0)
return DAG.getConstant(0, DL, VT);

View File

@ -31,6 +31,7 @@
#include "llvm/IR/Type.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
@ -1070,9 +1071,9 @@ static bool foldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N,
}
APInt MaskedHighBits =
APInt::getHighBitsSet(X.getSimpleValueType().getSizeInBits(), MaskLZ);
APInt KnownZero, KnownOne;
DAG.computeKnownBits(X, KnownZero, KnownOne);
if (MaskedHighBits != KnownZero) return true;
KnownBits Known;
DAG.computeKnownBits(X, Known);
if (MaskedHighBits != Known.Zero) return true;
// We've identified a pattern that can be transformed into a single shift
// and an addressing mode. Make it so.

View File

@ -52,6 +52,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
@ -16799,9 +16800,9 @@ static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC,
unsigned BitWidth = Op0.getValueSizeInBits();
unsigned AndBitWidth = And.getValueSizeInBits();
if (BitWidth > AndBitWidth) {
APInt Zeros, Ones;
DAG.computeKnownBits(Op0, Zeros, Ones);
if (Zeros.countLeadingOnes() < BitWidth - AndBitWidth)
KnownBits Known;
DAG.computeKnownBits(Op0, Known);
if (Known.Zero.countLeadingOnes() < BitWidth - AndBitWidth)
return SDValue();
}
LHS = Op1;
@ -26667,12 +26668,11 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
//===----------------------------------------------------------------------===//
void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const {
unsigned BitWidth = KnownZero.getBitWidth();
unsigned BitWidth = Known.getBitWidth();
unsigned Opc = Op.getOpcode();
EVT VT = Op.getValueType();
assert((Opc >= ISD::BUILTIN_OP_END ||
@ -26682,7 +26682,7 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
"Should use MaskedValueIsZero if you don't know whether Op"
" is a target node!");
KnownZero = KnownOne = APInt(BitWidth, 0); // Don't know anything.
Known = KnownBits(BitWidth); // Don't know anything.
switch (Opc) {
default: break;
case X86ISD::ADD:
@ -26701,33 +26701,33 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
break;
LLVM_FALLTHROUGH;
case X86ISD::SETCC:
KnownZero.setBits(1, BitWidth);
Known.Zero.setBits(1, BitWidth);
break;
case X86ISD::MOVMSK: {
unsigned NumLoBits = Op.getOperand(0).getValueType().getVectorNumElements();
KnownZero.setBits(NumLoBits, BitWidth);
Known.Zero.setBits(NumLoBits, BitWidth);
break;
}
case X86ISD::VSHLI:
case X86ISD::VSRLI: {
if (auto *ShiftImm = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
if (ShiftImm->getAPIntValue().uge(VT.getScalarSizeInBits())) {
KnownZero.setAllBits();
Known.Zero.setAllBits();
break;
}
DAG.computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth + 1);
DAG.computeKnownBits(Op.getOperand(0), Known, Depth + 1);
unsigned ShAmt = ShiftImm->getZExtValue();
if (Opc == X86ISD::VSHLI) {
KnownZero <<= ShAmt;
KnownOne <<= ShAmt;
Known.Zero <<= ShAmt;
Known.One <<= ShAmt;
// Low bits are known zero.
KnownZero.setLowBits(ShAmt);
Known.Zero.setLowBits(ShAmt);
} else {
KnownZero.lshrInPlace(ShAmt);
KnownOne.lshrInPlace(ShAmt);
Known.Zero.lshrInPlace(ShAmt);
Known.One.lshrInPlace(ShAmt);
// High bits are known zero.
KnownZero.setHighBits(ShAmt);
Known.Zero.setHighBits(ShAmt);
}
}
break;
@ -26741,12 +26741,12 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
unsigned InBitWidth = SrcVT.getScalarSizeInBits();
assert(InNumElts >= NumElts && "Illegal VZEXT input");
KnownZero = KnownOne = APInt(InBitWidth, 0);
Known = KnownBits(InBitWidth);
APInt DemandedSrcElts = APInt::getLowBitsSet(InNumElts, NumElts);
DAG.computeKnownBits(N0, KnownZero, KnownOne, DemandedSrcElts, Depth + 1);
KnownOne = KnownOne.zext(BitWidth);
KnownZero = KnownZero.zext(BitWidth);
KnownZero.setBits(InBitWidth, BitWidth);
DAG.computeKnownBits(N0, Known, DemandedSrcElts, Depth + 1);
Known.One = Known.One.zext(BitWidth);
Known.Zero = Known.Zero.zext(BitWidth);
Known.Zero.setBits(InBitWidth, BitWidth);
break;
}
}
@ -30206,12 +30206,11 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
assert(BitWidth >= 8 && BitWidth <= 64 && "Invalid mask size");
APInt DemandedMask(APInt::getSignMask(BitWidth));
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, DCI.isBeforeLegalize(),
DCI.isBeforeLegalizeOps());
if (TLI.ShrinkDemandedConstant(Cond, DemandedMask, TLO) ||
TLI.SimplifyDemandedBits(Cond, DemandedMask, KnownZero, KnownOne,
TLO)) {
TLI.SimplifyDemandedBits(Cond, DemandedMask, Known, TLO)) {
// If we changed the computation somewhere in the DAG, this change will
// affect all users of Cond. Make sure it is fine and update all the nodes
// so that we do not use the generic VSELECT anymore. Otherwise, we may
@ -33774,12 +33773,12 @@ static SDValue combineBT(SDNode *N, SelectionDAG &DAG,
if (Op1.hasOneUse()) {
unsigned BitWidth = Op1.getValueSizeInBits();
APInt DemandedMask = APInt::getLowBitsSet(BitWidth, Log2_32(BitWidth));
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
!DCI.isBeforeLegalizeOps());
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.ShrinkDemandedConstant(Op1, DemandedMask, TLO) ||
TLI.SimplifyDemandedBits(Op1, DemandedMask, KnownZero, KnownOne, TLO))
TLI.SimplifyDemandedBits(Op1, DemandedMask, Known, TLO))
DCI.CommitTargetLoweringOpt(TLO);
}
return SDValue();

View File

@ -828,8 +828,7 @@ namespace llvm {
/// Determine which of the bits specified in Mask are known to be either
/// zero or one and return them in the KnownZero/KnownOne bitsets.
void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const override;

View File

@ -1271,11 +1271,11 @@ def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue());
APInt KnownZero0, KnownOne0;
CurDAG->computeKnownBits(N->getOperand(0), KnownZero0, KnownOne0, 0);
APInt KnownZero1, KnownOne1;
CurDAG->computeKnownBits(N->getOperand(1), KnownZero1, KnownOne1, 0);
return (~KnownZero0 & ~KnownZero1) == 0;
KnownBits Known0;
CurDAG->computeKnownBits(N->getOperand(0), Known0, 0);
KnownBits Known1;
CurDAG->computeKnownBits(N->getOperand(1), Known1, 0);
return (~Known0.Zero & ~Known1.Zero) == 0;
}]>;

View File

@ -34,6 +34,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@ -406,9 +407,9 @@ SDValue XCoreTargetLowering::lowerLoadWordFromAlignedBasePlusOffset(
static bool isWordAligned(SDValue Value, SelectionDAG &DAG)
{
APInt KnownZero, KnownOne;
DAG.computeKnownBits(Value, KnownZero, KnownOne);
return KnownZero.countTrailingOnes() >= 2;
KnownBits Known;
DAG.computeKnownBits(Value, Known);
return Known.Zero.countTrailingOnes() >= 2;
}
SDValue XCoreTargetLowering::
@ -1601,13 +1602,12 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
if (OutVal.hasOneUse()) {
unsigned BitWidth = OutVal.getValueSizeInBits();
APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
!DCI.isBeforeLegalizeOps());
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.ShrinkDemandedConstant(OutVal, DemandedMask, TLO) ||
TLI.SimplifyDemandedBits(OutVal, DemandedMask, KnownZero, KnownOne,
TLO))
TLI.SimplifyDemandedBits(OutVal, DemandedMask, Known, TLO))
DCI.CommitTargetLoweringOpt(TLO);
}
break;
@ -1618,13 +1618,12 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
if (Time.hasOneUse()) {
unsigned BitWidth = Time.getValueSizeInBits();
APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
APInt KnownZero, KnownOne;
KnownBits Known;
TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
!DCI.isBeforeLegalizeOps());
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.ShrinkDemandedConstant(Time, DemandedMask, TLO) ||
TLI.SimplifyDemandedBits(Time, DemandedMask, KnownZero, KnownOne,
TLO))
TLI.SimplifyDemandedBits(Time, DemandedMask, Known, TLO))
DCI.CommitTargetLoweringOpt(TLO);
}
break;
@ -1655,11 +1654,11 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
// fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the
// low bit set
if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 1)) {
APInt KnownZero, KnownOne;
KnownBits Known;
APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
VT.getSizeInBits() - 1);
DAG.computeKnownBits(N2, KnownZero, KnownOne);
if ((KnownZero & Mask) == Mask) {
DAG.computeKnownBits(N2, Known);
if ((Known.Zero & Mask) == Mask) {
SDValue Carry = DAG.getConstant(0, dl, VT);
SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2);
SDValue Ops[] = { Result, Carry };
@ -1678,11 +1677,11 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
// fold (lsub 0, 0, x) -> x, -x iff x has only the low bit set
if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) {
APInt KnownZero, KnownOne;
KnownBits Known;
APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
VT.getSizeInBits() - 1);
DAG.computeKnownBits(N2, KnownZero, KnownOne);
if ((KnownZero & Mask) == Mask) {
DAG.computeKnownBits(N2, Known);
if ((Known.Zero & Mask) == Mask) {
SDValue Borrow = N2;
SDValue Result = DAG.getNode(ISD::SUB, dl, VT,
DAG.getConstant(0, dl, VT), N2);
@ -1694,11 +1693,11 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
// fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the
// low bit set
if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 1)) {
APInt KnownZero, KnownOne;
KnownBits Known;
APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
VT.getSizeInBits() - 1);
DAG.computeKnownBits(N2, KnownZero, KnownOne);
if ((KnownZero & Mask) == Mask) {
DAG.computeKnownBits(N2, Known);
if ((Known.Zero & Mask) == Mask) {
SDValue Borrow = DAG.getConstant(0, dl, VT);
SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2);
SDValue Ops[] = { Result, Borrow };
@ -1822,20 +1821,19 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
}
void XCoreTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth) const {
KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0);
Known.Zero.clearAllBits(); Known.One.clearAllBits();
switch (Op.getOpcode()) {
default: break;
case XCoreISD::LADD:
case XCoreISD::LSUB:
if (Op.getResNo() == 1) {
// Top bits of carry / borrow are clear.
KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(),
KnownZero.getBitWidth() - 1);
Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
Known.getBitWidth() - 1);
}
break;
case ISD::INTRINSIC_W_CHAIN:
@ -1844,24 +1842,24 @@ void XCoreTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
switch (IntNo) {
case Intrinsic::xcore_getts:
// High bits are known to be zero.
KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(),
KnownZero.getBitWidth() - 16);
Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
Known.getBitWidth() - 16);
break;
case Intrinsic::xcore_int:
case Intrinsic::xcore_inct:
// High bits are known to be zero.
KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(),
KnownZero.getBitWidth() - 8);
Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
Known.getBitWidth() - 8);
break;
case Intrinsic::xcore_testct:
// Result is either 0 or 1.
KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(),
KnownZero.getBitWidth() - 1);
Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
Known.getBitWidth() - 1);
break;
case Intrinsic::xcore_testwct:
// Result is in the range 0 - 4.
KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(),
KnownZero.getBitWidth() - 3);
Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
Known.getBitWidth() - 3);
break;
}
}

View File

@ -200,8 +200,7 @@ namespace llvm {
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
KnownBits &Known,
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const override;