[llvm] 7c05f09 - [NFC] Refactor DAGCombiner::foldSelectOfConstants to reduce nesting
Amaury Séchet via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 5 09:40:59 PDT 2022
Author: Amaury Séchet
Date: 2022-11-05T16:17:58Z
New Revision: 7c05f092c96f0db0956a59b2beac482f9bf03ec6
URL: https://github.com/llvm/llvm-project/commit/7c05f092c96f0db0956a59b2beac482f9bf03ec6
DIFF: https://github.com/llvm/llvm-project/commit/7c05f092c96f0db0956a59b2beac482f9bf03ec6.diff
LOG: [NFC] Refactor DAGCombiner::foldSelectOfConstants to reduce nesting
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 7d139fce7f758..ef32cfae26eae 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10380,101 +10380,103 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) {
if (!C1 || !C2)
return SDValue();
+ if (CondVT != MVT::i1 || LegalOperations) {
+ // fold (select Cond, 0, 1) -> (xor Cond, 1)
+ // We can't do this reliably if integer based booleans have
diff erent contents
+ // to floating point based booleans. This is because we can't tell whether we
+ // have an integer-based boolean or a floating-point-based boolean unless we
+ // can find the SETCC that produced it and inspect its operands. This is
+ // fairly easy if C is the SETCC node, but it can potentially be
+ // undiscoverable (or not reasonably discoverable). For example, it could be
+ // in another basic block or it could require searching a complicated
+ // expression.
+ if (CondVT.isInteger() &&
+ TLI.getBooleanContents(/*isVec*/false, /*isFloat*/true) ==
+ TargetLowering::ZeroOrOneBooleanContent &&
+ TLI.getBooleanContents(/*isVec*/false, /*isFloat*/false) ==
+ TargetLowering::ZeroOrOneBooleanContent &&
+ C1->isZero() && C2->isOne()) {
+ SDValue NotCond =
+ DAG.getNode(ISD::XOR, DL, CondVT, Cond, DAG.getConstant(1, DL, CondVT));
+ if (VT.bitsEq(CondVT))
+ return NotCond;
+ return DAG.getZExtOrTrunc(NotCond, DL, VT);
+ }
+
+ return SDValue();
+ }
+
// Only do this before legalization to avoid conflicting with target-specific
// transforms in the other direction (create a select from a zext/sext). There
// is also a target-independent combine here in DAGCombiner in the other
// direction for (select Cond, -1, 0) when the condition is not i1.
- if (CondVT == MVT::i1 && !LegalOperations) {
- // select Cond, 1, 0 --> zext (Cond)
- if (C1->isOne() && C2->isZero())
- return DAG.getZExtOrTrunc(Cond, DL, VT);
+ assert(CondVT == MVT::i1 && !LegalOperations);
- // select Cond, -1, 0 --> sext (Cond)
- if (C1->isAllOnes() && C2->isZero())
- return DAG.getSExtOrTrunc(Cond, DL, VT);
+ // select Cond, 1, 0 --> zext (Cond)
+ if (C1->isOne() && C2->isZero())
+ return DAG.getZExtOrTrunc(Cond, DL, VT);
- // select Cond, 0, 1 --> zext (!Cond)
- if (C1->isZero() && C2->isOne()) {
- SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
- NotCond = DAG.getZExtOrTrunc(NotCond, DL, VT);
- return NotCond;
- }
+ // select Cond, -1, 0 --> sext (Cond)
+ if (C1->isAllOnes() && C2->isZero())
+ return DAG.getSExtOrTrunc(Cond, DL, VT);
- // select Cond, 0, -1 --> sext (!Cond)
- if (C1->isZero() && C2->isAllOnes()) {
- SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
- NotCond = DAG.getSExtOrTrunc(NotCond, DL, VT);
- return NotCond;
- }
-
- // Use a target hook because some targets may prefer to transform in the
- // other direction.
- if (shouldConvertSelectOfConstantsToMath(Cond, VT, TLI)) {
- // For any constants that
diff er by 1, we can transform the select into
- // an extend and add.
- const APInt &C1Val = C1->getAPIntValue();
- const APInt &C2Val = C2->getAPIntValue();
+ // select Cond, 0, 1 --> zext (!Cond)
+ if (C1->isZero() && C2->isOne()) {
+ SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
+ NotCond = DAG.getZExtOrTrunc(NotCond, DL, VT);
+ return NotCond;
+ }
- // select Cond, C1, C1-1 --> add (zext Cond), C1-1
- if (C1Val - 1 == C2Val) {
- Cond = DAG.getZExtOrTrunc(Cond, DL, VT);
- return DAG.getNode(ISD::ADD, DL, VT, Cond, N2);
- }
+ // select Cond, 0, -1 --> sext (!Cond)
+ if (C1->isZero() && C2->isAllOnes()) {
+ SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
+ NotCond = DAG.getSExtOrTrunc(NotCond, DL, VT);
+ return NotCond;
+ }
- // select Cond, C1, C1+1 --> add (sext Cond), C1+1
- if (C1Val + 1 == C2Val) {
- Cond = DAG.getSExtOrTrunc(Cond, DL, VT);
- return DAG.getNode(ISD::ADD, DL, VT, Cond, N2);
- }
+ // Use a target hook because some targets may prefer to transform in the
+ // other direction.
+ if (shouldConvertSelectOfConstantsToMath(Cond, VT, TLI)) {
+ // For any constants that
diff er by 1, we can transform the select into
+ // an extend and add.
+ const APInt &C1Val = C1->getAPIntValue();
+ const APInt &C2Val = C2->getAPIntValue();
- // select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2)
- if (C1Val.isPowerOf2() && C2Val.isZero()) {
- Cond = DAG.getZExtOrTrunc(Cond, DL, VT);
- SDValue ShAmtC =
- DAG.getShiftAmountConstant(C1Val.exactLogBase2(), VT, DL);
- return DAG.getNode(ISD::SHL, DL, VT, Cond, ShAmtC);
- }
+ // select Cond, C1, C1-1 --> add (zext Cond), C1-1
+ if (C1Val - 1 == C2Val) {
+ Cond = DAG.getZExtOrTrunc(Cond, DL, VT);
+ return DAG.getNode(ISD::ADD, DL, VT, Cond, N2);
+ }
- // select Cond, -1, C --> or (sext Cond), C
- if (C1->isAllOnes()) {
- Cond = DAG.getSExtOrTrunc(Cond, DL, VT);
- return DAG.getNode(ISD::OR, DL, VT, Cond, N2);
- }
+ // select Cond, C1, C1+1 --> add (sext Cond), C1+1
+ if (C1Val + 1 == C2Val) {
+ Cond = DAG.getSExtOrTrunc(Cond, DL, VT);
+ return DAG.getNode(ISD::ADD, DL, VT, Cond, N2);
+ }
- // select Cond, C, -1 --> or (sext (not Cond)), C
- if (C2->isAllOnes()) {
- SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
- NotCond = DAG.getSExtOrTrunc(NotCond, DL, VT);
- return DAG.getNode(ISD::OR, DL, VT, NotCond, N1);
- }
+ // select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2)
+ if (C1Val.isPowerOf2() && C2Val.isZero()) {
+ Cond = DAG.getZExtOrTrunc(Cond, DL, VT);
+ SDValue ShAmtC =
+ DAG.getShiftAmountConstant(C1Val.exactLogBase2(), VT, DL);
+ return DAG.getNode(ISD::SHL, DL, VT, Cond, ShAmtC);
+ }
- if (SDValue V = foldSelectOfConstantsUsingSra(N, DAG))
- return V;
+ // select Cond, -1, C --> or (sext Cond), C
+ if (C1->isAllOnes()) {
+ Cond = DAG.getSExtOrTrunc(Cond, DL, VT);
+ return DAG.getNode(ISD::OR, DL, VT, Cond, N2);
}
- return SDValue();
- }
+ // select Cond, C, -1 --> or (sext (not Cond)), C
+ if (C2->isAllOnes()) {
+ SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
+ NotCond = DAG.getSExtOrTrunc(NotCond, DL, VT);
+ return DAG.getNode(ISD::OR, DL, VT, NotCond, N1);
+ }
- // fold (select Cond, 0, 1) -> (xor Cond, 1)
- // We can't do this reliably if integer based booleans have
diff erent contents
- // to floating point based booleans. This is because we can't tell whether we
- // have an integer-based boolean or a floating-point-based boolean unless we
- // can find the SETCC that produced it and inspect its operands. This is
- // fairly easy if C is the SETCC node, but it can potentially be
- // undiscoverable (or not reasonably discoverable). For example, it could be
- // in another basic block or it could require searching a complicated
- // expression.
- if (CondVT.isInteger() &&
- TLI.getBooleanContents(/*isVec*/false, /*isFloat*/true) ==
- TargetLowering::ZeroOrOneBooleanContent &&
- TLI.getBooleanContents(/*isVec*/false, /*isFloat*/false) ==
- TargetLowering::ZeroOrOneBooleanContent &&
- C1->isZero() && C2->isOne()) {
- SDValue NotCond =
- DAG.getNode(ISD::XOR, DL, CondVT, Cond, DAG.getConstant(1, DL, CondVT));
- if (VT.bitsEq(CondVT))
- return NotCond;
- return DAG.getZExtOrTrunc(NotCond, DL, VT);
+ if (SDValue V = foldSelectOfConstantsUsingSra(N, DAG))
+ return V;
}
return SDValue();
More information about the llvm-commits
mailing list