aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/SelectionDAG/TargetLowering.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-01-29 01:59:02 +0000
committerDan Gohman <gohman@apple.com>2009-01-29 01:59:02 +0000
commit22cefb0de0d6b2dff668fd276a4650a6ce01c797 (patch)
tree8ef65dfe14fd2541c8d0785d1ce6855abfd876b4 /lib/CodeGen/SelectionDAG/TargetLowering.cpp
parent4b975a9e15698251ba5421f6aa00a0322d10ae92 (diff)
downloadexternal_llvm-22cefb0de0d6b2dff668fd276a4650a6ce01c797.zip
external_llvm-22cefb0de0d6b2dff668fd276a4650a6ce01c797.tar.gz
external_llvm-22cefb0de0d6b2dff668fd276a4650a6ce01c797.tar.bz2
Make x86's BT instruction matching more thorough, and add some
dagcombines that help it match in several more cases. Add several more cases to test/CodeGen/X86/bt.ll. This doesn't yet include matching for BT with an immediate operand, it just covers more register+register cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63266 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/TargetLowering.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 7245244..e479e05 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -724,7 +724,7 @@ TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op,
const APInt &Demanded) {
// FIXME: ISD::SELECT, ISD::SELECT_CC
- switch(Op.getOpcode()) {
+ switch (Op.getOpcode()) {
default: break;
case ISD::AND:
case ISD::OR:
@@ -1054,6 +1054,14 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
break;
case ISD::SRA:
+ // If this is an arithmetic shift right and only the low-bit is set, we can
+ // always convert this into a logical shr, even if the shift amount is
+ // variable. The low bit of the shift cannot be an input sign bit unless
+ // the shift amount is >= the size of the datatype, which is undefined.
+ if (DemandedMask == 1)
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, Op.getValueType(),
+ Op.getOperand(0), Op.getOperand(1)));
+
if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
MVT VT = Op.getValueType();
unsigned ShAmt = SA->getZExtValue();
@@ -1332,6 +1340,21 @@ unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
return 1;
}
+static bool ValueHasAtMostOneBitSet(SDValue Val, const SelectionDAG &DAG) {
+ // Logical shift right or left won't ever introduce new set bits.
+ // We check for this case because we don't care which bits are
+ // set, but ComputeMaskedBits won't know anything unless it can
+ // determine which specific bits may be set.
+ if (Val.getOpcode() == ISD::SHL || Val.getOpcode() == ISD::SRL)
+ return ValueHasAtMostOneBitSet(Val.getOperand(0), DAG);
+
+ MVT OpVT = Val.getValueType();
+ unsigned BitWidth = OpVT.getSizeInBits();
+ APInt Mask = APInt::getAllOnesValue(BitWidth);
+ APInt KnownZero, KnownOne;
+ DAG.ComputeMaskedBits(Val, Mask, KnownZero, KnownOne);
+ return KnownZero.countPopulation() == BitWidth - 1;
+}
/// SimplifySetCC - Try to simplify a setcc built with the specified operands
/// and cc. If it is unable to simplify it, return a null SDValue.
@@ -1791,6 +1814,24 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
}
}
}
+
+ // Simpify x&y == y to x&y == 0 if y has exactly one bit set.
+ if (N0.getOpcode() == ISD::AND)
+ if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
+ if (ValueHasAtMostOneBitSet(N1, DAG)) {
+ Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
+ SDValue Zero = DAG.getConstant(0, N1.getValueType());
+ return DAG.getSetCC(VT, N0, Zero, Cond);
+ }
+ }
+ if (N1.getOpcode() == ISD::AND)
+ if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
+ if (ValueHasAtMostOneBitSet(N0, DAG)) {
+ Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
+ SDValue Zero = DAG.getConstant(0, N0.getValueType());
+ return DAG.getSetCC(VT, N1, Zero, Cond);
+ }
+ }
}
// Fold away ALL boolean setcc's.