summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2016-09-08 12:57:51 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2016-09-08 12:57:51 +0000
commitcc7b4b511bb366dd2b404b4ec176638954e90a3d (patch)
tree6bbef84ac0daf57526054ec90a203e14f2b98b5c /llvm/lib/CodeGen/SelectionDAG
parenta01ee07a19fd92c33ae8af36c24938c3aedc20eb (diff)
downloadbcm5719-llvm-cc7b4b511bb366dd2b404b4ec176638954e90a3d.tar.gz
bcm5719-llvm-cc7b4b511bb366dd2b404b4ec176638954e90a3d.zip
[SelectionDAG] Add BUILD_VECTOR support to computeKnownBits and SimplifyDemandedBits
Add the ability to computeKnownBits and SimplifyDemandedBits to extract the known zero/one bits from BUILD_VECTOR, returning the known bits that are shared by every vector element. This is an initial step towards determining the sign bits of a vector (PR29079). Differential Revision: https://reviews.llvm.org/D24253 llvm-svn: 280927
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp20
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp27
2 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9ac600bad72..991b19bf731 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2016,6 +2016,26 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue();
KnownZero = ~KnownOne;
break;
+ case ISD::BUILD_VECTOR:
+ // Collect the known bits that are shared by every vector element.
+ KnownZero = KnownOne = APInt::getAllOnesValue(BitWidth);
+ for (SDValue SrcOp : Op->ops()) {
+ computeKnownBits(SrcOp, KnownZero2, KnownOne2, Depth + 1);
+
+ // BUILD_VECTOR can implicitly truncate sources, we must handle this.
+ if (SrcOp.getValueSizeInBits() != BitWidth) {
+ assert(SrcOp.getValueSizeInBits() > BitWidth &&
+ "Expected BUILD_VECTOR implicit truncation");
+ KnownOne2 = KnownOne2.trunc(BitWidth);
+ KnownZero2 = KnownZero2.trunc(BitWidth);
+ }
+
+ // Known bits are the values that are shared by every element.
+ // TODO: support per-element known bits.
+ KnownOne &= KnownOne2;
+ KnownZero &= KnownZero2;
+ }
+ break;
case ISD::AND:
// If either the LHS or the RHS are Zero, the result is zero.
computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 3102a9a7084..d582a4b5b8a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -468,6 +468,33 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue();
KnownZero = ~KnownOne;
return false; // Don't fall through, will infinitely loop.
+ case ISD::BUILD_VECTOR:
+ // Collect the known bits that are shared by every constant vector element.
+ KnownZero = KnownOne = APInt::getAllOnesValue(BitWidth);
+ for (SDValue SrcOp : Op->ops()) {
+ if (!isa<ConstantSDNode>(SrcOp)) {
+ // We can only handle all constant values - bail out with no known bits.
+ KnownZero = KnownOne = APInt(BitWidth, 0);
+ return false;
+ }
+ KnownOne2 = cast<ConstantSDNode>(SrcOp)->getAPIntValue();
+ KnownZero2 = ~KnownOne2;
+
+ // BUILD_VECTOR can implicitly truncate sources, we must handle this.
+ if (KnownOne2.getBitWidth() != BitWidth) {
+ assert(KnownOne2.getBitWidth() > BitWidth &&
+ KnownZero2.getBitWidth() > BitWidth &&
+ "Expected BUILD_VECTOR implicit truncation");
+ KnownOne2 = KnownOne2.trunc(BitWidth);
+ KnownZero2 = KnownZero2.trunc(BitWidth);
+ }
+
+ // Known bits are the values that are shared by every element.
+ // TODO: support per-element known bits.
+ KnownOne &= KnownOne2;
+ KnownZero &= KnownZero2;
+ }
+ return false; // Don't fall through, will infinitely loop.
case ISD::AND:
// If the RHS is a constant, check to see if the LHS would be zero without
// using the bits from the RHS. Below, we use knowledge about the RHS to
OpenPOWER on IntegriCloud