diff options
author | Dan Gohman <gohman@apple.com> | 2009-01-29 01:59:02 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-01-29 01:59:02 +0000 |
commit | 22cefb0de0d6b2dff668fd276a4650a6ce01c797 (patch) | |
tree | 8ef65dfe14fd2541c8d0785d1ce6855abfd876b4 /lib/CodeGen/SelectionDAG/TargetLowering.cpp | |
parent | 4b975a9e15698251ba5421f6aa00a0322d10ae92 (diff) | |
download | external_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.cpp | 43 |
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. |