summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2017-04-21 18:53:12 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2017-04-21 18:53:12 +0000
commit22e839f4b2d2406c81bf31a343ee0afa73e53bcb (patch)
tree2dd53c8c29bc4c1e9076e29f1971534b0d7cb2e8 /llvm/lib/CodeGen/SelectionDAG
parent134d94f9a339be22c22af1014f00eeca03884675 (diff)
downloadbcm5719-llvm-22e839f4b2d2406c81bf31a343ee0afa73e53bcb.tar.gz
bcm5719-llvm-22e839f4b2d2406c81bf31a343ee0afa73e53bcb.zip
[AArch64] Improve code generation for logical instructions taking
immediate operands. This commit adds an AArch64 dag-combine that optimizes code generation for logical instructions taking immediate operands. The optimization uses demanded bits to change a logical instruction's immediate operand so that the immediate can be folded into the immediate field of the instruction. This recommits r300932 and r300930, which was causing dag-combine to loop forever. The problem was that optimizeLogicalImm was returning true even when there was no change to the immediate node (which happened when the immediate was all zeros or ones), which caused dag-combine to push and pop the same node to the work list over and over again without making any progress. This commit fixes the bug by returning false early in optimizeLogicalImm if the immediate is all zeros or ones. Also, it changes the code to compare the immediate with 0 or Mask rather than calling countPopulation. rdar://problem/18231627 Differential Revision: https://reviews.llvm.org/D5591 llvm-svn: 301019
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp66
1 files changed, 36 insertions, 30 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 93c6738f650..069fb5b9c09 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -342,11 +342,16 @@ TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
/// If the specified instruction has a constant integer operand and there are
/// bits set in that constant that are not demanded, then clear those bits and
/// return true.
-bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
- SDValue Op, const APInt &Demanded) {
+bool TargetLowering::ShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
+ TargetLoweringOpt &TLO) const {
+ SelectionDAG &DAG = TLO.DAG;
SDLoc DL(Op);
unsigned Opcode = Op.getOpcode();
+ // Do target-specific constant optimization.
+ if (targetShrinkDemandedConstant(Op, Demanded, TLO))
+ return TLO.New.getNode();
+
// FIXME: ISD::SELECT, ISD::SELECT_CC
switch (Opcode) {
default:
@@ -367,7 +372,7 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
EVT VT = Op.getValueType();
SDValue NewC = DAG.getConstant(Demanded & C, DL, VT);
SDValue NewOp = DAG.getNode(Opcode, DL, VT, Op.getOperand(0), NewC);
- return CombineTo(Op, NewOp);
+ return TLO.CombineTo(Op, NewOp);
}
break;
@@ -380,15 +385,17 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
/// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
/// This uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
/// generalized for targets with other types of implicit widening casts.
-bool TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
- unsigned BitWidth,
- const APInt &Demanded,
- const SDLoc &dl) {
+bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth,
+ const APInt &Demanded,
+ TargetLoweringOpt &TLO) const {
assert(Op.getNumOperands() == 2 &&
"ShrinkDemandedOp only supports binary operators!");
assert(Op.getNode()->getNumValues() == 1 &&
"ShrinkDemandedOp only supports nodes with one result!");
+ SelectionDAG &DAG = TLO.DAG;
+ SDLoc dl(Op);
+
// Early return, as this function cannot handle vector types.
if (Op.getValueType().isVector())
return false;
@@ -418,23 +425,22 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
bool NeedZext = DemandedSize > SmallVTBits;
SDValue Z = DAG.getNode(NeedZext ? ISD::ZERO_EXTEND : ISD::ANY_EXTEND,
dl, Op.getValueType(), X);
- return CombineTo(Op, Z);
+ return TLO.CombineTo(Op, Z);
}
}
return false;
}
bool
-TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
- unsigned OpIdx,
- const APInt &Demanded,
- DAGCombinerInfo &DCI) {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+TargetLowering::SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
+ const APInt &Demanded,
+ DAGCombinerInfo &DCI,
+ TargetLoweringOpt &TLO) const {
SDValue Op = User->getOperand(OpIdx);
APInt KnownZero, KnownOne;
- if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
- *this, 0, true))
+ if (!SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
+ TLO, 0, true))
return false;
@@ -446,9 +452,9 @@ TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
// with the value 'x', which will give us:
// Old = i32 and x, 0xffffff
// New = x
- if (Old.hasOneUse()) {
+ if (TLO.Old.hasOneUse()) {
// For the one use case, we just commit the change.
- DCI.CommitTargetLoweringOpt(*this);
+ DCI.CommitTargetLoweringOpt(TLO);
return true;
}
@@ -456,17 +462,17 @@ TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
// AssumeSingleUse flag is not propogated to recursive calls of
// SimplifyDemanded bits, so the only node with multiple use that
// it will attempt to combine will be opt.
- assert(Old == Op);
+ assert(TLO.Old == Op);
SmallVector <SDValue, 4> NewOps;
for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
if (i == OpIdx) {
- NewOps.push_back(New);
+ NewOps.push_back(TLO.New);
continue;
}
NewOps.push_back(User->getOperand(i));
}
- DAG.UpdateNodeOperands(User, NewOps);
+ TLO.DAG.UpdateNodeOperands(User, NewOps);
// Op has less users now, so we may be able to perform additional combines
// with it.
DCI.AddToWorklist(Op.getNode());
@@ -585,7 +591,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If any of the set bits in the RHS are known zero on the LHS, shrink
// the constant.
- if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & NewMask))
+ if (ShrinkDemandedConstant(Op, ~LHSZero & NewMask, TLO))
return true;
// Bitwise-not (xor X, -1) is a special case: we don't usually shrink its
@@ -620,10 +626,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((NewMask & (KnownZero|KnownZero2)) == NewMask)
return TLO.CombineTo(Op, TLO.DAG.getConstant(0, dl, Op.getValueType()));
// If the RHS is a constant, see if we can simplify it.
- if (TLO.ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask))
+ if (ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask, TLO))
return true;
// If the operation can be done in a smaller type, do so.
- if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
+ if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// Output known-1 bits are only known if set in both the LHS & RHS.
@@ -654,10 +660,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask))
return TLO.CombineTo(Op, Op.getOperand(1));
// If the RHS is a constant, see if we can simplify it.
- if (TLO.ShrinkDemandedConstant(Op, NewMask))
+ if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// If the operation can be done in a smaller type, do so.
- if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
+ if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// Output known-0 bits are only known if clear in both the LHS & RHS.
@@ -682,7 +688,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((KnownZero2 & NewMask) == NewMask)
return TLO.CombineTo(Op, Op.getOperand(1));
// If the operation can be done in a smaller type, do so.
- if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
+ if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// If all of the unknown bits are known to be zero on one side or the other
@@ -727,7 +733,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
// If it already has all the bits set, nothing to change
// but don't shrink either!
- } else if (TLO.ShrinkDemandedConstant(Op, NewMask)) {
+ } else if (ShrinkDemandedConstant(Op, NewMask, TLO)) {
return true;
}
}
@@ -746,7 +752,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
- if (TLO.ShrinkDemandedConstant(Op, NewMask))
+ if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// Only known if known in both the LHS and RHS.
@@ -764,7 +770,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
- if (TLO.ShrinkDemandedConstant(Op, NewMask))
+ if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// Only known if known in both the LHS and RHS.
@@ -1284,7 +1290,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2,
KnownOne2, TLO, Depth+1) ||
// See if the operation should be performed at a smaller bit width.
- TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) {
+ ShrinkDemandedOp(Op, BitWidth, NewMask, TLO)) {
const SDNodeFlags *Flags = Op.getNode()->getFlags();
if (Flags->hasNoSignedWrap() || Flags->hasNoUnsignedWrap()) {
// Disable the nsw and nuw flags. We can no longer guarantee that we
OpenPOWER on IntegriCloud