diff options
| author | Dan Gohman <gohman@apple.com> | 2009-02-15 23:59:32 +0000 |
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2009-02-15 23:59:32 +0000 |
| commit | aaee6c9523ad727c83a211805eb1fee9932bbcd7 (patch) | |
| tree | b625300b8590d7d09d41c5717b8508257ae4566b | |
| parent | f6ccacba3659c99b52676d2e74022ced00ea5e80 (diff) | |
| download | bcm5719-llvm-aaee6c9523ad727c83a211805eb1fee9932bbcd7.tar.gz bcm5719-llvm-aaee6c9523ad727c83a211805eb1fee9932bbcd7.zip | |
Don't assume that a left-shift of a value with one bit set will have
one bit set, because the bit may be shifted off the end. Instead,
just check for a constant 1 being shifted. This is still sufficient
to handle all the cases in test/CodeGen/X86/bt.ll. This fixes PR3583.
llvm-svn: 64622
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 909789b970b..3f56febafa3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1346,14 +1346,31 @@ unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op, return 1; } +/// ValueHasExactlyOneBitSet - Test if the given value is known to have exactly +/// one bit set. This differs from ComputeMaskedBits in that it doesn't need to +/// determine which bit is set. +/// static bool ValueHasExactlyOneBitSet(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 ValueHasExactlyOneBitSet(Val.getOperand(0), DAG); + // A left-shift of a constant one will have exactly one bit set, because + // shifting the bit off the end is undefined. + if (Val.getOpcode() == ISD::SHL) + if (ConstantSDNode *C = + dyn_cast<ConstantSDNode>(Val.getNode()->getOperand(0))) + if (C->getAPIntValue() == 1) + return true; + + // Similarly, a right-shift of a constant sign-bit will have exactly + // one bit set. + if (Val.getOpcode() == ISD::SRL) + if (ConstantSDNode *C = + dyn_cast<ConstantSDNode>(Val.getNode()->getOperand(0))) + if (C->getAPIntValue().isSignBit()) + return true; + + // More could be done here, though the above checks are enough + // to handle some common cases. + // Fall back to ComputeMaskedBits to catch other known cases. MVT OpVT = Val.getValueType(); unsigned BitWidth = OpVT.getSizeInBits(); APInt Mask = APInt::getAllOnesValue(BitWidth); |

