@@ -1549,136 +1549,147 @@ void X86DAGToDAGISel::PostprocessISelDAG() {
1549
1549
continue ;
1550
1550
}
1551
1551
1552
- // Look for a TESTrr+ANDrr pattern where both operands of the test are
1553
- // the same. Rewrite to remove the AND.
1554
1552
unsigned Opc = N->getMachineOpcode ();
1555
- if ((Opc == X86::TEST8rr || Opc == X86::TEST16rr ||
1556
- Opc == X86::TEST32rr || Opc == X86::TEST64rr) &&
1557
- N->getOperand (0 ) == N->getOperand (1 ) &&
1558
- N->getOperand (0 )->hasNUsesOfValue (2 , N->getOperand (0 ).getResNo ()) &&
1559
- N->getOperand (0 ).isMachineOpcode ()) {
1560
- SDValue And = N->getOperand (0 );
1561
- unsigned N0Opc = And.getMachineOpcode ();
1562
- if ((N0Opc == X86::AND8rr || N0Opc == X86::AND16rr ||
1563
- N0Opc == X86::AND32rr || N0Opc == X86::AND64rr ||
1564
- N0Opc == X86::AND8rr_ND || N0Opc == X86::AND16rr_ND ||
1565
- N0Opc == X86::AND32rr_ND || N0Opc == X86::AND64rr_ND) &&
1566
- !And->hasAnyUseOfValue (1 )) {
1567
- MachineSDNode *Test = CurDAG->getMachineNode (Opc, SDLoc (N),
1568
- MVT::i32 ,
1569
- And.getOperand (0 ),
1570
- And.getOperand (1 ));
1571
- ReplaceUses (N, Test);
1572
- MadeChange = true ;
1553
+ switch (Opc) {
1554
+ default :
1555
+ continue ;
1556
+ // TESTrr+ANDrr/rm -> TESTrr/TESTmr
1557
+ case X86::TEST8rr:
1558
+ case X86::TEST16rr:
1559
+ case X86::TEST32rr:
1560
+ case X86::TEST64rr: {
1561
+ auto &Op0 = N->getOperand (0 );
1562
+ if (Op0 != N->getOperand (1 ) || !Op0->hasNUsesOfValue (2 , Op0.getResNo ()) ||
1563
+ !Op0.isMachineOpcode ())
1573
1564
continue ;
1574
- }
1575
- if ((N0Opc == X86::AND8rm || N0Opc == X86::AND16rm ||
1576
- N0Opc == X86::AND32rm || N0Opc == X86::AND64rm ||
1577
- N0Opc == X86::AND8rm_ND || N0Opc == X86::AND16rm_ND ||
1578
- N0Opc == X86::AND32rm_ND || N0Opc == X86::AND64rm_ND) &&
1579
- !And->hasAnyUseOfValue (1 )) {
1580
- unsigned NewOpc;
1565
+ SDValue And = N->getOperand (0 );
1581
1566
#define CASE_ND (OP ) \
1582
1567
case X86::OP: \
1583
1568
case X86::OP##_ND:
1569
+ switch (And.getMachineOpcode ()) {
1570
+ default :
1571
+ continue ;
1572
+ CASE_ND (AND8rr)
1573
+ CASE_ND (AND16rr)
1574
+ CASE_ND (AND32rr)
1575
+ CASE_ND (AND64rr) {
1576
+ if (And->hasAnyUseOfValue (1 ))
1577
+ continue ;
1578
+ MachineSDNode *Test = CurDAG->getMachineNode (
1579
+ Opc, SDLoc (N), MVT::i32 , And.getOperand (0 ), And.getOperand (1 ));
1580
+ ReplaceUses (N, Test);
1581
+ MadeChange = true ;
1582
+ continue ;
1583
+ }
1584
+ CASE_ND (AND8rm)
1585
+ CASE_ND (AND16rm)
1586
+ CASE_ND (AND32rm)
1587
+ CASE_ND (AND64rm) {
1588
+ if (And->hasAnyUseOfValue (1 ))
1589
+ continue ;
1590
+ unsigned NewOpc;
1584
1591
#define FROM_TO (A, B ) \
1585
1592
CASE_ND (A) NewOpc = X86::B; \
1586
1593
break ;
1587
- switch (N0Opc ) {
1588
- FROM_TO (AND8rm, TEST8mr);
1589
- FROM_TO (AND16rm, TEST16mr);
1590
- FROM_TO (AND32rm, TEST32mr);
1591
- FROM_TO (AND64rm, TEST64mr);
1592
- }
1594
+ switch (And. getMachineOpcode () ) {
1595
+ FROM_TO (AND8rm, TEST8mr);
1596
+ FROM_TO (AND16rm, TEST16mr);
1597
+ FROM_TO (AND32rm, TEST32mr);
1598
+ FROM_TO (AND64rm, TEST64mr);
1599
+ }
1593
1600
#undef FROM_TO
1594
1601
#undef CASE_ND
1595
-
1596
- // Need to swap the memory and register operand.
1597
- SDValue Ops[] = { And.getOperand (1 ),
1598
- And.getOperand (2 ),
1599
- And.getOperand (3 ),
1600
- And.getOperand (4 ),
1601
- And.getOperand (5 ),
1602
- And.getOperand (0 ),
1603
- And.getOperand (6 ) /* Chain */ };
1604
- MachineSDNode *Test = CurDAG->getMachineNode (NewOpc, SDLoc (N),
1605
- MVT::i32 , MVT::Other, Ops);
1606
- CurDAG->setNodeMemRefs (
1607
- Test, cast<MachineSDNode>(And.getNode ())->memoperands ());
1608
- ReplaceUses (And.getValue (2 ), SDValue (Test, 1 ));
1609
- ReplaceUses (SDValue (N, 0 ), SDValue (Test, 0 ));
1610
- MadeChange = true ;
1611
- continue ;
1602
+ // Need to swap the memory and register operand.
1603
+ SDValue Ops[] = {And.getOperand (1 ), And.getOperand (2 ),
1604
+ And.getOperand (3 ), And.getOperand (4 ),
1605
+ And.getOperand (5 ), And.getOperand (0 ),
1606
+ And.getOperand (6 ) /* Chain */ };
1607
+ MachineSDNode *Test = CurDAG->getMachineNode (
1608
+ NewOpc, SDLoc (N), MVT::i32 , MVT::Other, Ops);
1609
+ CurDAG->setNodeMemRefs (
1610
+ Test, cast<MachineSDNode>(And.getNode ())->memoperands ());
1611
+ ReplaceUses (And.getValue (2 ), SDValue (Test, 1 ));
1612
+ ReplaceUses (SDValue (N, 0 ), SDValue (Test, 0 ));
1613
+ MadeChange = true ;
1614
+ continue ;
1615
+ }
1612
1616
}
1613
1617
}
1614
-
1615
1618
// Look for a KAND+KORTEST and turn it into KTEST if only the zero flag is
1616
1619
// used. We're doing this late so we can prefer to fold the AND into masked
1617
1620
// comparisons. Doing that can be better for the live range of the mask
1618
1621
// register.
1619
- if ((Opc == X86::KORTESTBrr || Opc == X86::KORTESTWrr ||
1620
- Opc == X86::KORTESTDrr || Opc == X86::KORTESTQrr) &&
1621
- N->getOperand (0 ) == N->getOperand (1 ) &&
1622
- N->isOnlyUserOf (N->getOperand (0 ).getNode ()) &&
1623
- N->getOperand (0 ).isMachineOpcode () &&
1624
- onlyUsesZeroFlag (SDValue (N, 0 ))) {
1625
- SDValue And = N->getOperand (0 );
1626
- unsigned N0Opc = And.getMachineOpcode ();
1622
+ case X86::KORTESTBrr:
1623
+ case X86::KORTESTWrr:
1624
+ case X86::KORTESTDrr:
1625
+ case X86::KORTESTQrr: {
1626
+ SDValue Op0 = N->getOperand (0 );
1627
+ if (Op0 != N->getOperand (1 ) || !N->isOnlyUserOf (Op0.getNode ()) ||
1628
+ !Op0.isMachineOpcode () || !onlyUsesZeroFlag (SDValue (N, 0 )))
1629
+ continue ;
1630
+ #define CASE (A ) \
1631
+ case X86::A: \
1632
+ break ;
1633
+ switch (Op0.getMachineOpcode ()) {
1634
+ default :
1635
+ continue ;
1636
+ CASE (KANDBrr)
1637
+ CASE (KANDWrr)
1638
+ CASE (KANDDrr)
1639
+ CASE (KANDQrr)
1640
+ }
1641
+ unsigned NewOpc;
1642
+ #define FROM_TO (A, B ) \
1643
+ case X86::A: \
1644
+ NewOpc = X86::B; \
1645
+ break ;
1646
+ switch (Opc) {
1647
+ FROM_TO (KORTESTBrr, KTESTBrr)
1648
+ FROM_TO (KORTESTWrr, KTESTWrr)
1649
+ FROM_TO (KORTESTDrr, KTESTDrr)
1650
+ FROM_TO (KORTESTQrr, KTESTQrr)
1651
+ }
1627
1652
// KANDW is legal with AVX512F, but KTESTW requires AVX512DQ. The other
1628
1653
// KAND instructions and KTEST use the same ISA feature.
1629
- if (N0Opc == X86::KANDBrr ||
1630
- (N0Opc == X86::KANDWrr && Subtarget->hasDQI ()) ||
1631
- N0Opc == X86::KANDDrr || N0Opc == X86::KANDQrr) {
1632
- unsigned NewOpc;
1633
- switch (Opc) {
1634
- default : llvm_unreachable (" Unexpected opcode!" );
1635
- case X86::KORTESTBrr: NewOpc = X86::KTESTBrr; break ;
1636
- case X86::KORTESTWrr: NewOpc = X86::KTESTWrr; break ;
1637
- case X86::KORTESTDrr: NewOpc = X86::KTESTDrr; break ;
1638
- case X86::KORTESTQrr: NewOpc = X86::KTESTQrr; break ;
1639
- }
1640
- MachineSDNode *KTest = CurDAG->getMachineNode (NewOpc, SDLoc (N),
1641
- MVT::i32 ,
1642
- And.getOperand (0 ),
1643
- And.getOperand (1 ));
1644
- ReplaceUses (N, KTest);
1645
- MadeChange = true ;
1654
+ if (NewOpc == X86::KTESTWrr && !Subtarget->hasDQI ())
1646
1655
continue ;
1647
- }
1656
+ #undef FROM_TO
1657
+ MachineSDNode *KTest = CurDAG->getMachineNode (
1658
+ NewOpc, SDLoc (N), MVT::i32 , Op0.getOperand (0 ), Op0.getOperand (1 ));
1659
+ ReplaceUses (N, KTest);
1660
+ MadeChange = true ;
1661
+ continue ;
1648
1662
}
1649
-
1650
1663
// Attempt to remove vectors moves that were inserted to zero upper bits.
1651
- if (Opc != TargetOpcode::SUBREG_TO_REG)
1652
- continue ;
1653
-
1654
- unsigned SubRegIdx = N->getConstantOperandVal (2 );
1655
- if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1656
- continue ;
1664
+ case TargetOpcode::SUBREG_TO_REG: {
1665
+ unsigned SubRegIdx = N->getConstantOperandVal (2 );
1666
+ if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1667
+ continue ;
1657
1668
1658
- SDValue Move = N->getOperand (1 );
1659
- if (!Move.isMachineOpcode ())
1660
- continue ;
1669
+ SDValue Move = N->getOperand (1 );
1670
+ if (!Move.isMachineOpcode ())
1671
+ continue ;
1661
1672
1662
- // Make sure its one of the move opcodes we recognize.
1663
- switch (Move.getMachineOpcode ()) {
1664
- default :
1665
- continue ;
1666
- case X86::VMOVAPDrr: case X86:: VMOVUPDrr:
1667
- case X86::VMOVAPSrr: case X86:: VMOVUPSrr:
1668
- case X86::VMOVDQArr: case X86:: VMOVDQUrr:
1669
- case X86::VMOVAPDYrr: case X86:: VMOVUPDYrr:
1670
- case X86::VMOVAPSYrr: case X86:: VMOVUPSYrr:
1671
- case X86::VMOVDQAYrr: case X86:: VMOVDQUYrr:
1672
- case X86::VMOVAPDZ128rr: case X86:: VMOVUPDZ128rr:
1673
- case X86::VMOVAPSZ128rr: case X86:: VMOVUPSZ128rr:
1674
- case X86::VMOVDQA32Z128rr: case X86:: VMOVDQU32Z128rr:
1675
- case X86::VMOVDQA64Z128rr: case X86:: VMOVDQU64Z128rr:
1676
- case X86::VMOVAPDZ256rr: case X86:: VMOVUPDZ256rr:
1677
- case X86::VMOVAPSZ256rr: case X86:: VMOVUPSZ256rr:
1678
- case X86::VMOVDQA32Z256rr: case X86:: VMOVDQU32Z256rr:
1679
- case X86::VMOVDQA64Z256rr: case X86:: VMOVDQU64Z256rr:
1680
- break ;
1681
- }
1673
+ // Make sure its one of the move opcodes we recognize.
1674
+ switch (Move.getMachineOpcode ()) {
1675
+ default :
1676
+ continue ;
1677
+ CASE (VMOVAPDrr) CASE ( VMOVUPDrr)
1678
+ CASE (VMOVAPSrr) CASE ( VMOVUPSrr)
1679
+ CASE (VMOVDQArr) CASE ( VMOVDQUrr)
1680
+ CASE (VMOVAPDYrr) CASE ( VMOVUPDYrr)
1681
+ CASE (VMOVAPSYrr) CASE ( VMOVUPSYrr)
1682
+ CASE (VMOVDQAYrr) CASE ( VMOVDQUYrr)
1683
+ CASE (VMOVAPDZ128rr) CASE ( VMOVUPDZ128rr)
1684
+ CASE (VMOVAPSZ128rr) CASE ( VMOVUPSZ128rr)
1685
+ CASE (VMOVDQA32Z128rr) CASE ( VMOVDQU32Z128rr)
1686
+ CASE (VMOVDQA64Z128rr) CASE ( VMOVDQU64Z128rr)
1687
+ CASE (VMOVAPDZ256rr) CASE ( VMOVUPDZ256rr)
1688
+ CASE (VMOVAPSZ256rr) CASE ( VMOVUPSZ256rr)
1689
+ CASE (VMOVDQA32Z256rr) CASE ( VMOVDQU32Z256rr)
1690
+ CASE (VMOVDQA64Z256rr) CASE ( VMOVDQU64Z256rr)
1691
+ }
1692
+ # undef CASE
1682
1693
1683
1694
SDValue In = Move.getOperand (0 );
1684
1695
if (!In.isMachineOpcode () ||
@@ -1697,6 +1708,8 @@ void X86DAGToDAGISel::PostprocessISelDAG() {
1697
1708
// move.
1698
1709
CurDAG->UpdateNodeOperands (N, N->getOperand (0 ), In, N->getOperand (2 ));
1699
1710
MadeChange = true ;
1711
+ }
1712
+ }
1700
1713
}
1701
1714
1702
1715
if (MadeChange)
0 commit comments