aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-02-15 23:59:32 +0000
committerDan Gohman <gohman@apple.com>2009-02-15 23:59:32 +0000
commit97d116346cdf47ce0c8536a69ff6c606309cb4c0 (patch)
tree4c66333d17b3415da1f8ef940e2bf00aa32807ce
parent35188eb54db0df31a11bc2227292170d987efe1a (diff)
downloadexternal_llvm-97d116346cdf47ce0c8536a69ff6c606309cb4c0.zip
external_llvm-97d116346cdf47ce0c8536a69ff6c606309cb4c0.tar.gz
external_llvm-97d116346cdf47ce0c8536a69ff6c606309cb4c0.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64622 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp29
1 files changed, 23 insertions, 6 deletions
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 909789b..3f56feb 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/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);