@@ -1521,33 +1521,44 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
1521
1521
// / ccmp B, inv(CB), CA
1522
1522
// / check for CB flags
1523
1523
// /
1524
- // / In general we can create code for arbitrary "... (and (and A B) C)"
1525
- // / sequences. We can also implement some "or" expressions, because "(or A B)"
1526
- // / is equivalent to "not (and (not A) (not B))" and we can implement some
1527
- // / negation operations:
1528
- // / We can negate the results of a single comparison by inverting the flags
1529
- // / used when the predicate fails and inverting the flags tested in the next
1530
- // / instruction; We can also negate the results of the whole previous
1531
- // / conditional compare sequence by inverting the flags tested in the next
1532
- // / instruction. However there is no way to negate the result of a partial
1533
- // / sequence.
1524
+ // / This naturally lets us implement chains of AND operations with SETCC
1525
+ // / operands. And we can even implement some other situations by transforming
1526
+ // / them:
1527
+ // / - We can implement (NEG SETCC) i.e. negating a single comparison by
1528
+ // / negating the flags used in a CCMP/FCCMP operations.
1529
+ // / - We can negate the result of a whole chain of CMP/CCMP/FCCMP operations
1530
+ // / by negating the flags we test for afterwards. i.e.
1531
+ // / NEG (CMP CCMP CCCMP ...) can be implemented.
1532
+ // / - Note that we can only ever negate all previously processed results.
1533
+ // / What we can not implement by flipping the flags to test is a negation
1534
+ // / of two sub-trees (because the negation affects all sub-trees emitted so
1535
+ // / far, so the 2nd sub-tree we emit would also affect the first).
1536
+ // / With those tools we can implement some OR operations:
1537
+ // / - (OR (SETCC A) (SETCC B)) can be implemented via:
1538
+ // / NEG (AND (NEG (SETCC A)) (NEG (SETCC B)))
1539
+ // / - After transforming OR to NEG/AND combinations we may be able to use NEG
1540
+ // / elimination rules from earlier to implement the whole thing as a
1541
+ // / CCMP/FCCMP chain.
1534
1542
// /
1535
- // / Therefore on encountering an "or" expression we can negate the subtree on
1536
- // / one side and have to be able to push the negate to the leafs of the subtree
1537
- // / on the other side (see also the comments in code). As complete example:
1538
- // / "or (or (setCA (cmp A)) (setCB (cmp B)))
1539
- // / (and (setCC (cmp C)) (setCD (cmp D)))"
1540
- // / is transformed to
1541
- // / "not (and (not (and (setCC (cmp C)) (setCC (cmp D))))
1542
- // / (and (not (setCA (cmp A)) (not (setCB (cmp B))))))"
1543
- // / and implemented as:
1543
+ // / As complete example:
1544
+ // / or (or (setCA (cmp A)) (setCB (cmp B)))
1545
+ // / (and (setCC (cmp C)) (setCD (cmp D)))"
1546
+ // / can be reassociated to:
1547
+ // / or (and (setCC (cmp C)) setCD (cmp D))
1548
+ // (or (setCA (cmp A)) (setCB (cmp B)))
1549
+ // / can be transformed to:
1550
+ // / not (and (not (and (setCC (cmp C)) (setCD (cmp D))))
1551
+ // / (and (not (setCA (cmp A)) (not (setCB (cmp B))))))"
1552
+ // / which can be implemented as:
1544
1553
// / cmp C
1545
1554
// / ccmp D, inv(CD), CC
1546
1555
// / ccmp A, CA, inv(CD)
1547
1556
// / ccmp B, CB, inv(CA)
1548
1557
// / check for CB flags
1549
- // / A counterexample is "or (and A B) (and C D)" which cannot be implemented
1550
- // / by conditional compare sequences.
1558
+ // /
1559
+ // / A counterexample is "or (and A B) (and C D)" which translates to
1560
+ // / not (and (not (and (not A) (not B))) (not (and (not C) (not D)))), we
1561
+ // / can only implement 1 of the inner (not) operations, but not both!
1551
1562
// / @{
1552
1563
1553
1564
// / Create a conditional comparison; Use CCMP, CCMN or FCCMP as appropriate.
@@ -1587,9 +1598,20 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
1587
1598
1588
1599
// / Returns true if @p Val is a tree of AND/OR/SETCC operations that can be
1589
1600
// / 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.
1601
+ // / \param CanNegate Set to true if we can negate the whole sub-tree just by
1602
+ // / changing the conditions on the SETCC tests.
1603
+ // / (this means we can call emitConjunctionRec() with
1604
+ // / Negate==true on this sub-tree)
1605
+ // / \param MustBeFirst Set to true if this subtree needs to be negated and we
1606
+ // / cannot do the negation naturally. We are required to
1607
+ // / emit the subtree first in this case.
1608
+ // / \param WillNegate Is true if are called when the result of this
1609
+ // / subexpression must be negated. This happens when the
1610
+ // / outer expression is an OR. We can use this fact to know
1611
+ // / that we have a double negation (or (or ...) ...) that
1612
+ // / can be implemented for free.
1592
1613
static bool canEmitConjunction (const SDValue Val, bool &CanNegate,
1614
+ bool &MustBeFirst, bool WillNegate,
1593
1615
unsigned Depth = 0 ) {
1594
1616
if (!Val.hasOneUse ())
1595
1617
return false ;
@@ -1598,42 +1620,44 @@ static bool canEmitConjunction(const SDValue Val, bool &CanNegate,
1598
1620
if (Val->getOperand (0 ).getValueType () == MVT::f128)
1599
1621
return false ;
1600
1622
CanNegate = true ;
1623
+ MustBeFirst = false ;
1601
1624
return true ;
1602
1625
}
1603
1626
// Protect against exponential runtime and stack overflow.
1604
1627
if (Depth > 6 )
1605
1628
return false ;
1606
1629
if (Opcode == ISD::AND || Opcode == ISD::OR) {
1630
+ bool IsOR = Opcode == ISD::OR;
1607
1631
SDValue O0 = Val->getOperand (0 );
1608
1632
SDValue O1 = Val->getOperand (1 );
1609
1633
bool CanNegateL;
1610
- if (!canEmitConjunction (O0, CanNegateL, Depth+1 ))
1634
+ bool MustBeFirstL;
1635
+ if (!canEmitConjunction (O0, CanNegateL, MustBeFirstL, IsOR, Depth+1 ))
1611
1636
return false ;
1612
1637
bool CanNegateR;
1613
- if (!canEmitConjunction (O1, CanNegateR, Depth+1 ))
1638
+ bool MustBeFirstR;
1639
+ if (!canEmitConjunction (O1, CanNegateR, MustBeFirstR, IsOR, Depth+1 ))
1640
+ return false ;
1641
+
1642
+ if (MustBeFirstL && MustBeFirstR)
1614
1643
return false ;
1615
1644
1616
- if (Opcode == ISD::OR ) {
1617
- // For an OR expression we need to be able to negate at least one side or
1618
- // we cannot do the transformation at all.
1645
+ if (IsOR ) {
1646
+ // For an OR expression we need to be able to naturally negate at least
1647
+ // one side or we cannot do the transformation at all.
1619
1648
if (!CanNegateL && !CanNegateR)
1620
1649
return false ;
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 .
1626
- CanNegate = CanNegateL && CanNegateR ;
1650
+ // If we the result of the OR will be negated and we can naturally negate
1651
+ // the leafs, then this sub-tree as a whole negates naturally.
1652
+ CanNegate = WillNegate && CanNegateL && CanNegateR;
1653
+ // If we cannot naturally negate the whole sub-tree, then this must be
1654
+ // emitted first .
1655
+ MustBeFirst = !CanNegate ;
1627
1656
} else {
1628
- // If the operands are OR expressions then we finally need to negate their
1629
- // outputs, we can only do that for the operand with emitted last by
1630
- // negating OutCC, not for both operands.
1631
- bool NeedsNegOutL = O0->getOpcode () == ISD::OR;
1632
- bool NeedsNegOutR = O1->getOpcode () == ISD::OR;
1633
- if (NeedsNegOutL && NeedsNegOutR)
1634
- return false ;
1635
- // We cannot negate an AND operation.
1657
+ assert (Opcode == ISD::AND && " Must be OR or AND" );
1658
+ // We cannot naturally negate an AND operation.
1636
1659
CanNegate = false ;
1660
+ MustBeFirst = MustBeFirstL || MustBeFirstR;
1637
1661
}
1638
1662
return true ;
1639
1663
}
@@ -1646,10 +1670,8 @@ static bool canEmitConjunction(const SDValue Val, bool &CanNegate,
1646
1670
// / and conditional compare operations. @returns an NZCV flags producing node
1647
1671
// / and sets @p OutCC to the flags that should be tested or returns SDValue() if
1648
1672
// / transformation was not possible.
1649
- // / On recursive invocations @p PushNegate may be set to true to have negation
1650
- // / effects pushed to the tree leafs; @p Predicate is an NZCV flag predicate
1651
- // / for the comparisons in the current subtree; @p Depth limits the search
1652
- // / depth to avoid stack overflow.
1673
+ // / \p Negate is true if we want this sub-tree being negated just by changing
1674
+ // / SETCC conditions.
1653
1675
static SDValue emitConjunctionRec (SelectionDAG &DAG, SDValue Val,
1654
1676
AArch64CC::CondCode &OutCC, bool Negate, SDValue CCOp,
1655
1677
AArch64CC::CondCode Predicate) {
@@ -1691,61 +1713,69 @@ static SDValue emitConjunctionRec(SelectionDAG &DAG, SDValue Val,
1691
1713
return emitConditionalComparison (LHS, RHS, CC, CCOp, Predicate, OutCC, DL,
1692
1714
DAG);
1693
1715
}
1694
- assert ((Opcode == ISD::AND || (Opcode == ISD::OR && Val->hasOneUse ())) &&
1695
- " Valid conjunction/disjunction tree" );
1716
+ assert (Val->hasOneUse () && " Valid conjunction/disjunction tree" );
1696
1717
1697
- // Check if both sides can be transformed.
1698
- SDValue LHS = Val->getOperand (0 );
1699
- SDValue RHS = Val->getOperand (1 );
1700
-
1701
- // In case of an OR we need to negate our operands and the result.
1702
- // (A v B) <=> not(not(A) ^ not(B))
1703
- bool NegateOpsAndResult = Opcode == ISD::OR;
1704
- // We can negate the results of all previous operations by inverting the
1705
- // predicate flags giving us a free negation for one side. The other side
1706
- // must be negatable by itself.
1707
- if (NegateOpsAndResult) {
1708
- // See which side we can negate.
1709
- bool CanNegateL;
1710
- bool isValidL = canEmitConjunction (LHS, CanNegateL);
1711
- assert (isValidL && " Valid conjunction/disjunction tree" );
1712
- (void )isValidL;
1718
+ bool IsOR = Opcode == ISD::OR;
1713
1719
1714
- # ifndef NDEBUG
1715
- bool CanNegateR ;
1716
- bool isValidR = canEmitConjunction (RHS, CanNegateR) ;
1717
- assert (isValidR && " Valid conjunction/disjunction tree " );
1718
- assert ((CanNegateL || CanNegateR) && " Valid conjunction/disjunction tree" );
1719
- # endif
1720
+ SDValue LHS = Val-> getOperand ( 0 );
1721
+ bool CanNegateL ;
1722
+ bool MustBeFirstL ;
1723
+ bool ValidL = canEmitConjunction (LHS, CanNegateL, MustBeFirstL, IsOR );
1724
+ assert (ValidL && " Valid conjunction/disjunction tree" );
1725
+ ( void )ValidL;
1720
1726
1721
- // Order the side which we cannot negate to RHS so we can emit it first.
1722
- if (!CanNegateL)
1727
+ SDValue RHS = Val->getOperand (1 );
1728
+ bool CanNegateR;
1729
+ bool MustBeFirstR;
1730
+ bool ValidR = canEmitConjunction (RHS, CanNegateR, MustBeFirstR, IsOR);
1731
+ assert (ValidR && " Valid conjunction/disjunction tree" );
1732
+ (void )ValidR;
1733
+
1734
+ // Swap sub-tree that must come first to the right side.
1735
+ if (MustBeFirstL) {
1736
+ assert (!MustBeFirstR && " Valid conjunction/disjunction tree" );
1737
+ std::swap (LHS, RHS);
1738
+ std::swap (CanNegateL, CanNegateR);
1739
+ std::swap (MustBeFirstL, MustBeFirstR);
1740
+ }
1741
+
1742
+ bool NegateR;
1743
+ bool NegateAfterR;
1744
+ bool NegateL;
1745
+ bool NegateAfterAll;
1746
+ if (Opcode == ISD::OR) {
1747
+ // Swap the sub-tree that we can negate naturally to the left.
1748
+ if (!CanNegateL) {
1749
+ assert (CanNegateR && " at least one side must be negatable" );
1750
+ assert (!MustBeFirstR && " invalid conjunction/disjunction tree" );
1751
+ assert (!Negate);
1723
1752
std::swap (LHS, RHS);
1753
+ NegateR = false ;
1754
+ NegateAfterR = true ;
1755
+ } else {
1756
+ // Negate the left sub-tree if possible, otherwise negate the result.
1757
+ NegateR = CanNegateR;
1758
+ NegateAfterR = !CanNegateR;
1759
+ }
1760
+ NegateL = true ;
1761
+ NegateAfterAll = !Negate;
1724
1762
} else {
1725
- bool NeedsNegOutL = LHS-> getOpcode () == ISD::OR ;
1726
- assert ((!NeedsNegOutL || RHS-> getOpcode () != ISD::OR) &&
1727
- " Valid conjunction/disjunction tree " );
1728
- // Order the side where we need to negate the output flags to RHS so it
1729
- // gets emitted first.
1730
- if (NeedsNegOutL)
1731
- std::swap (LHS, RHS) ;
1763
+ assert (Opcode == ISD::AND && " Valid conjunction/disjunction tree " ) ;
1764
+ assert (!Negate && " Valid conjunction/disjunction tree " );
1765
+
1766
+ NegateL = false ;
1767
+ NegateR = false ;
1768
+ NegateAfterR = false ;
1769
+ NegateAfterAll = false ;
1732
1770
}
1733
1771
1734
- // Emit RHS. If we want to negate the tree we only need to push a negate
1735
- // through if we are already in a PushNegate case, otherwise we can negate
1736
- // the "flags to test" afterwards.
1772
+ // Emit sub-trees.
1737
1773
AArch64CC::CondCode RHSCC;
1738
- SDValue CmpR = emitConjunctionRec (DAG, RHS, RHSCC, Negate,
1739
- CCOp, Predicate);
1740
- if (NegateOpsAndResult && !Negate)
1774
+ SDValue CmpR = emitConjunctionRec (DAG, RHS, RHSCC, NegateR, CCOp, Predicate);
1775
+ if (NegateAfterR)
1741
1776
RHSCC = AArch64CC::getInvertedCondCode (RHSCC);
1742
- // Emit LHS. We may need to negate it.
1743
- SDValue CmpL = emitConjunctionRec (DAG, LHS, OutCC,
1744
- NegateOpsAndResult, CmpR,
1745
- RHSCC);
1746
- // If we transformed an OR to and AND then we have to negate the result
1747
- // (or absorb the Negate parameter).
1748
- if (NegateOpsAndResult && !Negate)
1777
+ SDValue CmpL = emitConjunctionRec (DAG, LHS, OutCC, NegateL, CmpR, RHSCC);
1778
+ if (NegateAfterAll)
1749
1779
OutCC = AArch64CC::getInvertedCondCode (OutCC);
1750
1780
return CmpL;
1751
1781
}
@@ -1757,7 +1787,8 @@ static SDValue emitConjunctionRec(SelectionDAG &DAG, SDValue Val,
1757
1787
static SDValue emitConjunction (SelectionDAG &DAG, SDValue Val,
1758
1788
AArch64CC::CondCode &OutCC) {
1759
1789
bool DummyCanNegate;
1760
- if (!canEmitConjunction (Val, DummyCanNegate))
1790
+ bool DummyMustBeFirst;
1791
+ if (!canEmitConjunction (Val, DummyCanNegate, DummyMustBeFirst, false ))
1761
1792
return SDValue ();
1762
1793
1763
1794
return emitConjunctionRec (DAG, Val, OutCC, false , SDValue (), AArch64CC::AL);
0 commit comments