llvm.org GIT mirror llvm / 9b187c9
[SDAG] Build up a more rich set of APIs for querying build-vector SDAG nodes about whether they are splats. This is factored out and improved from r212324 which got reverted as it was far too aggressive. The new API should help more conservatively handle buildvectors that are a mixture of splatted and undef values. No functionality change at this point. The hope is to slowly re-introduce the undef-tolerant optimization of splats, but each time being forced to make a concious decision about how to handle the undefs in a way that doesn't lead to contradicting assumptions about the collapsed value. Hal has pointed out in discussions that this may not end up being the desired API and instead it may be more convenient to get a mask of the undef elements or something similar. I'm starting simple and will expand the API as I adapt actual callers and see exactly what they need. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212514 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 5 years ago
4 changed file(s) with 59 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
15821582 unsigned MinSplatBits = 0,
15831583 bool isBigEndian = false) const;
15841584
1585 /// getConstantSplatValue - Check if this is a constant splat, and if so,
1586 /// return the splat value only if it is a ConstantSDNode. Otherwise
1587 /// return nullptr. This is a simpler form of isConstantSplat.
1588 /// Get the constant splat only if you care about the splat value.
1589 ConstantSDNode *getConstantSplatValue() const;
1585 /// \brief Returns the splatted value or a null value if this is not a splat.
1586 SDValue getSplatValue(bool &HasUndefElements) const;
1587
1588 /// \brief Returns the splatted constant or null if this is not a constant
1589 /// splat.
1590 ConstantSDNode *getConstantSplatNode(bool &HasUndefElements) const;
1591
1592 /// \brief Returns the splatted constant FP or null if this is not a constant
1593 /// FP splat.
1594 ConstantFPSDNode *getConstantFPSplatNode(bool &HasUndefElements) const;
15901595
15911596 bool isConstant() const;
15921597
654654 return CN;
655655
656656 if (BuildVectorSDNode *BV = dyn_cast(N)) {
657 ConstantSDNode *CN = BV->getConstantSplatValue();
657 bool HasUndefElements;
658 ConstantSDNode *CN = BV->getConstantSplatNode(HasUndefElements);
658659
659660 // BuildVectors can truncate their operands. Ignore that case here.
660 if (CN && CN->getValueType(0) == N.getValueType().getScalarType())
661 // FIXME: We blindly ignore splats which include undef which is overly
662 // pessimistic.
663 if (CN && !HasUndefElements &&
664 CN->getValueType(0) == N.getValueType().getScalarType())
661665 return CN;
662666 }
663667
15051505 return N1;
15061506
15071507 // Shuffling a constant splat doesn't change the result.
1508 bool SplatHasUndefs;
15081509 if (N2Undef && N1.getOpcode() == ISD::BUILD_VECTOR)
1509 if (cast(N1)->getConstantSplatValue())
1510 if (cast(N1)->getConstantSplatNode(SplatHasUndefs) &&
1511 !SplatHasUndefs)
15101512 return N1;
15111513
15121514 FoldingSetNodeID ID;
66026604 return true;
66036605 }
66046606
6605 ConstantSDNode *BuildVectorSDNode::getConstantSplatValue() const {
6606 SDValue Op0 = getOperand(0);
6607 if (Op0.getOpcode() != ISD::Constant)
6608 return nullptr;
6609
6610 for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
6611 if (getOperand(i) != Op0)
6612 return nullptr;
6613
6614 return cast(Op0);
6607 SDValue BuildVectorSDNode::getSplatValue(bool &HasUndefElements) const {
6608 HasUndefElements = false;
6609 SDValue Splatted;
6610 for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
6611 SDValue Op = getOperand(i);
6612 if (Op.getOpcode() == ISD::UNDEF)
6613 HasUndefElements = true;
6614 else if (!Splatted)
6615 Splatted = Op;
6616 else if (Splatted != Op)
6617 return SDValue();
6618 }
6619
6620 if (!Splatted) {
6621 assert(getOperand(0).getOpcode() == ISD::UNDEF &&
6622 "Can only have a splat without a constant for all undefs.");
6623 return getOperand(0);
6624 }
6625
6626 return Splatted;
6627 }
6628
6629 ConstantSDNode *
6630 BuildVectorSDNode::getConstantSplatNode(bool &HasUndefElements) const {
6631 return dyn_cast_or_null(
6632 getSplatValue(HasUndefElements).getNode());
6633 }
6634
6635 ConstantFPSDNode *
6636 BuildVectorSDNode::getConstantFPSplatNode(bool &HasUndefElements) const {
6637 return dyn_cast_or_null(
6638 getSplatValue(HasUndefElements).getNode());
66156639 }
66166640
66176641 bool BuildVectorSDNode::isConstant() const {
11571157 return false;
11581158
11591159 IsVec = true;
1160 CN = BV->getConstantSplatValue();
1160 bool HasUndefElements;
1161 CN = BV->getConstantSplatNode(HasUndefElements);
1162 if (HasUndefElements)
1163 return false; // Can't blindly collapse the undef values.
11611164 }
11621165
11631166 switch (getBooleanContents(IsVec)) {
11841187 return false;
11851188
11861189 IsVec = true;
1187 CN = BV->getConstantSplatValue();
1190 bool HasUndefElements;
1191 CN = BV->getConstantSplatNode(HasUndefElements);
1192 if (HasUndefElements)
1193 return false; // Can't blindly collapse the undef values.
11881194 }
11891195
11901196 if (getBooleanContents(IsVec) == UndefinedBooleanContent)