@@ -1515,7 +1515,7 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
1515
1515
// / The CCMP/CCMN/FCCMP/FCCMPE instructions allow the conditional execution of
1516
1516
// / a comparison. They set the NZCV flags to a predefined value if their
1517
1517
// / 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)))"
1519
1519
// / expressed as:
1520
1520
// / cmp A
1521
1521
// / ccmp B, inv(CB), CA
@@ -1585,14 +1585,12 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
1585
1585
return DAG.getNode (Opcode, DL, MVT_CC, LHS, RHS, NZCVOp, Condition, CCOp);
1586
1586
}
1587
1587
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 ) {
1596
1594
if (!Val.hasOneUse ())
1597
1595
return false ;
1598
1596
unsigned Opcode = Val->getOpcode ();
@@ -1609,19 +1607,22 @@ static bool isConjunctionDisjunctionTree(const SDValue Val, bool &CanNegate,
1609
1607
SDValue O0 = Val->getOperand (0 );
1610
1608
SDValue O1 = Val->getOperand (1 );
1611
1609
bool CanNegateL;
1612
- if (!isConjunctionDisjunctionTree (O0, CanNegateL, Depth+1 ))
1610
+ if (!canEmitConjunction (O0, CanNegateL, Depth+1 ))
1613
1611
return false ;
1614
1612
bool CanNegateR;
1615
- if (!isConjunctionDisjunctionTree (O1, CanNegateR, Depth+1 ))
1613
+ if (!canEmitConjunction (O1, CanNegateR, Depth+1 ))
1616
1614
return false ;
1617
1615
1618
1616
if (Opcode == ISD::OR) {
1619
1617
// For an OR expression we need to be able to negate at least one side or
1620
1618
// we cannot do the transformation at all.
1621
1619
if (!CanNegateL && !CanNegateR)
1622
1620
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.
1625
1626
CanNegate = CanNegateL && CanNegateR;
1626
1627
} else {
1627
1628
// 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,
1631
1632
bool NeedsNegOutR = O1->getOpcode () == ISD::OR;
1632
1633
if (NeedsNegOutL && NeedsNegOutR)
1633
1634
return false ;
1634
- // We cannot negate an AND operation (it would become an OR),
1635
+ // We cannot negate an AND operation.
1635
1636
CanNegate = false ;
1636
1637
}
1637
1638
return true ;
@@ -1649,7 +1650,7 @@ static bool isConjunctionDisjunctionTree(const SDValue Val, bool &CanNegate,
1649
1650
// / effects pushed to the tree leafs; @p Predicate is an NZCV flag predicate
1650
1651
// / for the comparisons in the current subtree; @p Depth limits the search
1651
1652
// / depth to avoid stack overflow.
1652
- static SDValue emitConjunctionDisjunctionTreeRec (SelectionDAG &DAG, SDValue Val,
1653
+ static SDValue emitConjunctionRec (SelectionDAG &DAG, SDValue Val,
1653
1654
AArch64CC::CondCode &OutCC, bool Negate, SDValue CCOp,
1654
1655
AArch64CC::CondCode Predicate) {
1655
1656
// We're at a tree leaf, produce a conditional comparison operation.
@@ -1706,13 +1707,13 @@ static SDValue emitConjunctionDisjunctionTreeRec(SelectionDAG &DAG, SDValue Val,
1706
1707
if (NegateOpsAndResult) {
1707
1708
// See which side we can negate.
1708
1709
bool CanNegateL;
1709
- bool isValidL = isConjunctionDisjunctionTree (LHS, CanNegateL);
1710
+ bool isValidL = canEmitConjunction (LHS, CanNegateL);
1710
1711
assert (isValidL && " Valid conjunction/disjunction tree" );
1711
1712
(void )isValidL;
1712
1713
1713
1714
#ifndef NDEBUG
1714
1715
bool CanNegateR;
1715
- bool isValidR = isConjunctionDisjunctionTree (RHS, CanNegateR);
1716
+ bool isValidR = canEmitConjunction (RHS, CanNegateR);
1716
1717
assert (isValidR && " Valid conjunction/disjunction tree" );
1717
1718
assert ((CanNegateL || CanNegateR) && " Valid conjunction/disjunction tree" );
1718
1719
#endif
@@ -1734,12 +1735,12 @@ static SDValue emitConjunctionDisjunctionTreeRec(SelectionDAG &DAG, SDValue Val,
1734
1735
// through if we are already in a PushNegate case, otherwise we can negate
1735
1736
// the "flags to test" afterwards.
1736
1737
AArch64CC::CondCode RHSCC;
1737
- SDValue CmpR = emitConjunctionDisjunctionTreeRec (DAG, RHS, RHSCC, Negate,
1738
+ SDValue CmpR = emitConjunctionRec (DAG, RHS, RHSCC, Negate,
1738
1739
CCOp, Predicate);
1739
1740
if (NegateOpsAndResult && !Negate)
1740
1741
RHSCC = AArch64CC::getInvertedCondCode (RHSCC);
1741
1742
// Emit LHS. We may need to negate it.
1742
- SDValue CmpL = emitConjunctionDisjunctionTreeRec (DAG, LHS, OutCC,
1743
+ SDValue CmpL = emitConjunctionRec (DAG, LHS, OutCC,
1743
1744
NegateOpsAndResult, CmpR,
1744
1745
RHSCC);
1745
1746
// 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,
1749
1750
return CmpL;
1750
1751
}
1751
1752
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))
1759
1761
return SDValue ();
1760
1762
1761
- return emitConjunctionDisjunctionTreeRec (DAG, Val, OutCC, false , SDValue (),
1762
- AArch64CC::AL);
1763
+ return emitConjunctionRec (DAG, Val, OutCC, false , SDValue (), AArch64CC::AL);
1763
1764
}
1764
1765
1765
1766
// / @}
@@ -1859,7 +1860,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
1859
1860
}
1860
1861
1861
1862
if (!Cmp && (RHSC->isNullValue () || RHSC->isOne ())) {
1862
- if ((Cmp = emitConjunctionDisjunctionTree (DAG, LHS, AArch64CC))) {
1863
+ if ((Cmp = emitConjunction (DAG, LHS, AArch64CC))) {
1863
1864
if ((CC == ISD::SETNE) ^ RHSC->isNullValue ())
1864
1865
AArch64CC = AArch64CC::getInvertedCondCode (AArch64CC);
1865
1866
}
0 commit comments