mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01: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:
parent
946fd240da
commit
af680f3cea
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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()))
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}]>;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user