summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp37
1 files changed, 28 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index a9f2be572664..5c6a2454d664 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9924,15 +9924,8 @@ SDValue SelectionDAG::simplifySelect(SDValue Cond, SDValue T, SDValue F) {
// select true, T, F --> T
// select false, T, F --> F
- if (auto *CondC = dyn_cast<ConstantSDNode>(Cond))
- return CondC->isZero() ? F : T;
-
- // TODO: This should simplify VSELECT with non-zero constant condition using
- // something like this (but check boolean contents to be complete?):
- if (ConstantSDNode *CondC = isConstOrConstSplat(Cond, /*AllowUndefs*/ false,
- /*AllowTruncation*/ true))
- if (CondC->isZero())
- return F;
+ if (auto C = isBoolConstant(Cond, /*AllowTruncation=*/true))
+ return *C ? T : F;
// select ?, T, T --> T
if (T == F)
@@ -13141,6 +13134,32 @@ SDNode *SelectionDAG::isConstantFPBuildVectorOrConstantFP(SDValue N) const {
return nullptr;
}
+std::optional<bool> SelectionDAG::isBoolConstant(SDValue N,
+ bool AllowTruncation) const {
+ ConstantSDNode *Const = isConstOrConstSplat(N, false, AllowTruncation);
+ if (!Const)
+ return std::nullopt;
+
+ const APInt &CVal = Const->getAPIntValue();
+ switch (TLI->getBooleanContents(N.getValueType())) {
+ case TargetLowering::ZeroOrOneBooleanContent:
+ if (CVal.isOne())
+ return true;
+ if (CVal.isZero())
+ return false;
+ return std::nullopt;
+ case TargetLowering::ZeroOrNegativeOneBooleanContent:
+ if (CVal.isAllOnes())
+ return true;
+ if (CVal.isZero())
+ return false;
+ return std::nullopt;
+ case TargetLowering::UndefinedBooleanContent:
+ return CVal[0];
+ }
+ llvm_unreachable("Unknown BooleanContent enum");
+}
+
void SelectionDAG::createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
assert(!Node->OperandList && "Node already has operands");
assert(SDNode::getMaxNumOperands() >= Vals.size() &&