@@ -1515,7 +1515,7 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
15151515// / The CCMP/CCMN/FCCMP/FCCMPE instructions allow the conditional execution of
15161516// / a comparison. They set the NZCV flags to a predefined value if their
15171517// / predicate is false. This allows to express arbitrary conjunctions, for
1518- // / example "cmp 0 (and (setCA (cmp A)) (setCB (cmp B)))) "
1518+ // / example "cmp 0 (and (setCA (cmp A)) (setCB (cmp B)))"
15191519// / expressed as:
15201520// / cmp A
15211521// / ccmp B, inv(CB), CA
@@ -1585,14 +1585,12 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
15851585 return DAG.getNode (Opcode, DL, MVT_CC, LHS, RHS, NZCVOp, Condition, CCOp);
15861586}
15871587
1588- // / Returns true if @p Val is a tree of AND/OR/SETCC operations.
1589- // / CanPushNegate is set to true if we can push a negate operation through
1590- // / the tree in a was that we are left with AND operations and negate operations
1591- // / at the leafs only. i.e. "not (or (or x y) z)" can be changed to
1592- // / "and (and (not x) (not y)) (not z)"; "not (or (and x y) z)" cannot be
1593- // / brought into such a form.
1594- static bool isConjunctionDisjunctionTree (const SDValue Val, bool &CanNegate,
1595- unsigned Depth = 0 ) {
1588+ // / Returns true if @p Val is a tree of AND/OR/SETCC operations that can be
1589+ // / expressed as a conjunction. See \ref AArch64CCMP.
1590+ // / \param CanNegate Set to true if we can also emit the negation of the
1591+ // / tree as a conjunction.
1592+ static bool canEmitConjunction (const SDValue Val, bool &CanNegate,
1593+ unsigned Depth = 0 ) {
15961594 if (!Val.hasOneUse ())
15971595 return false ;
15981596 unsigned Opcode = Val->getOpcode ();
@@ -1609,19 +1607,22 @@ static bool isConjunctionDisjunctionTree(const SDValue Val, bool &CanNegate,
16091607 SDValue O0 = Val->getOperand (0 );
16101608 SDValue O1 = Val->getOperand (1 );
16111609 bool CanNegateL;
1612- if (!isConjunctionDisjunctionTree (O0, CanNegateL, Depth+1 ))
1610+ if (!canEmitConjunction (O0, CanNegateL, Depth+1 ))
16131611 return false ;
16141612 bool CanNegateR;
1615- if (!isConjunctionDisjunctionTree (O1, CanNegateR, Depth+1 ))
1613+ if (!canEmitConjunction (O1, CanNegateR, Depth+1 ))
16161614 return false ;
16171615
16181616 if (Opcode == ISD::OR) {
16191617 // For an OR expression we need to be able to negate at least one side or
16201618 // we cannot do the transformation at all.
16211619 if (!CanNegateL && !CanNegateR)
16221620 return false ;
1623- // We can however change a (not (or x y)) to (and (not x) (not y)) if we
1624- // can negate the x and y subtrees.
1621+ // However if we can negate x and y, then we can change
1622+ // (not (or x y))
1623+ // into
1624+ // (and (not x) (not y))
1625+ // to eliminate the outer negation.
16251626 CanNegate = CanNegateL && CanNegateR;
16261627 } else {
16271628 // If the operands are OR expressions then we finally need to negate their
@@ -1631,7 +1632,7 @@ static bool isConjunctionDisjunctionTree(const SDValue Val, bool &CanNegate,
16311632 bool NeedsNegOutR = O1->getOpcode () == ISD::OR;
16321633 if (NeedsNegOutL && NeedsNegOutR)
16331634 return false ;
1634- // We cannot negate an AND operation (it would become an OR),
1635+ // We cannot negate an AND operation.
16351636 CanNegate = false ;
16361637 }
16371638 return true ;
@@ -1649,7 +1650,7 @@ static bool isConjunctionDisjunctionTree(const SDValue Val, bool &CanNegate,
16491650// / effects pushed to the tree leafs; @p Predicate is an NZCV flag predicate
16501651// / for the comparisons in the current subtree; @p Depth limits the search
16511652// / depth to avoid stack overflow.
1652- static SDValue emitConjunctionDisjunctionTreeRec (SelectionDAG &DAG, SDValue Val,
1653+ static SDValue emitConjunctionRec (SelectionDAG &DAG, SDValue Val,
16531654 AArch64CC::CondCode &OutCC, bool Negate, SDValue CCOp,
16541655 AArch64CC::CondCode Predicate) {
16551656 // We're at a tree leaf, produce a conditional comparison operation.
@@ -1706,13 +1707,13 @@ static SDValue emitConjunctionDisjunctionTreeRec(SelectionDAG &DAG, SDValue Val,
17061707 if (NegateOpsAndResult) {
17071708 // See which side we can negate.
17081709 bool CanNegateL;
1709- bool isValidL = isConjunctionDisjunctionTree (LHS, CanNegateL);
1710+ bool isValidL = canEmitConjunction (LHS, CanNegateL);
17101711 assert (isValidL && " Valid conjunction/disjunction tree" );
17111712 (void )isValidL;
17121713
17131714#ifndef NDEBUG
17141715 bool CanNegateR;
1715- bool isValidR = isConjunctionDisjunctionTree (RHS, CanNegateR);
1716+ bool isValidR = canEmitConjunction (RHS, CanNegateR);
17161717 assert (isValidR && " Valid conjunction/disjunction tree" );
17171718 assert ((CanNegateL || CanNegateR) && " Valid conjunction/disjunction tree" );
17181719#endif
@@ -1734,12 +1735,12 @@ static SDValue emitConjunctionDisjunctionTreeRec(SelectionDAG &DAG, SDValue Val,
17341735 // through if we are already in a PushNegate case, otherwise we can negate
17351736 // the "flags to test" afterwards.
17361737 AArch64CC::CondCode RHSCC;
1737- SDValue CmpR = emitConjunctionDisjunctionTreeRec (DAG, RHS, RHSCC, Negate,
1738+ SDValue CmpR = emitConjunctionRec (DAG, RHS, RHSCC, Negate,
17381739 CCOp, Predicate);
17391740 if (NegateOpsAndResult && !Negate)
17401741 RHSCC = AArch64CC::getInvertedCondCode (RHSCC);
17411742 // Emit LHS. We may need to negate it.
1742- SDValue CmpL = emitConjunctionDisjunctionTreeRec (DAG, LHS, OutCC,
1743+ SDValue CmpL = emitConjunctionRec (DAG, LHS, OutCC,
17431744 NegateOpsAndResult, CmpR,
17441745 RHSCC);
17451746 // If we transformed an OR to and AND then we have to negate the result
@@ -1749,17 +1750,17 @@ static SDValue emitConjunctionDisjunctionTreeRec(SelectionDAG &DAG, SDValue Val,
17491750 return CmpL;
17501751}
17511752
1752- // / Emit conjunction or disjunction tree with the CMP/FCMP followed by a chain
1753- // / of CCMP/CFCMP ops. See @ref AArch64CCMP.
1754- // / \see emitConjunctionDisjunctionTreeRec().
1755- static SDValue emitConjunctionDisjunctionTree (SelectionDAG &DAG, SDValue Val,
1756- AArch64CC::CondCode &OutCC) {
1757- bool CanNegate;
1758- if (!isConjunctionDisjunctionTree (Val, CanNegate))
1753+ // / Emit expression as a conjunction (a series of CCMP/CFCMP ops).
1754+ // / In some cases this is even possible with OR operations in the expression.
1755+ // / See \ref AArch64CCMP.
1756+ // / \see emitConjunctionRec().
1757+ static SDValue emitConjunction (SelectionDAG &DAG, SDValue Val,
1758+ AArch64CC::CondCode &OutCC) {
1759+ bool DummyCanNegate;
1760+ if (!canEmitConjunction (Val, DummyCanNegate))
17591761 return SDValue ();
17601762
1761- return emitConjunctionDisjunctionTreeRec (DAG, Val, OutCC, false , SDValue (),
1762- AArch64CC::AL);
1763+ return emitConjunctionRec (DAG, Val, OutCC, false , SDValue (), AArch64CC::AL);
17631764}
17641765
17651766// / @}
@@ -1859,7 +1860,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
18591860 }
18601861
18611862 if (!Cmp && (RHSC->isNullValue () || RHSC->isOne ())) {
1862- if ((Cmp = emitConjunctionDisjunctionTree (DAG, LHS, AArch64CC))) {
1863+ if ((Cmp = emitConjunction (DAG, LHS, AArch64CC))) {
18631864 if ((CC == ISD::SETNE) ^ RHSC->isNullValue ())
18641865 AArch64CC = AArch64CC::getInvertedCondCode (AArch64CC);
18651866 }
0 commit comments