Skip to content

Commit 98deeda

Browse files
committed
[X86][CodeGen] Use switch-case for transform in X86DAGToDAGISel::PostprocessISelDAG, NFCI
This is to simplify code for #91747
1 parent a2590e0 commit 98deeda

File tree

1 file changed

+120
-107
lines changed

1 file changed

+120
-107
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 120 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,136 +1549,147 @@ void X86DAGToDAGISel::PostprocessISelDAG() {
15491549
continue;
15501550
}
15511551

1552-
// Look for a TESTrr+ANDrr pattern where both operands of the test are
1553-
// the same. Rewrite to remove the AND.
15541552
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())
15731564
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);
15811566
#define CASE_ND(OP) \
15821567
case X86::OP: \
15831568
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;
15841591
#define FROM_TO(A, B) \
15851592
CASE_ND(A) NewOpc = X86::B; \
15861593
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+
}
15931600
#undef FROM_TO
15941601
#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+
}
16121616
}
16131617
}
1614-
16151618
// Look for a KAND+KORTEST and turn it into KTEST if only the zero flag is
16161619
// used. We're doing this late so we can prefer to fold the AND into masked
16171620
// comparisons. Doing that can be better for the live range of the mask
16181621
// 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+
}
16271652
// KANDW is legal with AVX512F, but KTESTW requires AVX512DQ. The other
16281653
// 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())
16461655
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;
16481662
}
1649-
16501663
// 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;
16571668

1658-
SDValue Move = N->getOperand(1);
1659-
if (!Move.isMachineOpcode())
1660-
continue;
1669+
SDValue Move = N->getOperand(1);
1670+
if (!Move.isMachineOpcode())
1671+
continue;
16611672

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
16821693

16831694
SDValue In = Move.getOperand(0);
16841695
if (!In.isMachineOpcode() ||
@@ -1697,6 +1708,8 @@ void X86DAGToDAGISel::PostprocessISelDAG() {
16971708
// move.
16981709
CurDAG->UpdateNodeOperands(N, N->getOperand(0), In, N->getOperand(2));
16991710
MadeChange = true;
1711+
}
1712+
}
17001713
}
17011714

17021715
if (MadeChange)

0 commit comments

Comments
 (0)