[llvm] r202469 - Swap PPC isel operands to allow for 0-folding

Hal Finkel hfinkel at anl.gov
Thu Feb 27 22:11:16 PST 2014


Author: hfinkel
Date: Fri Feb 28 00:11:16 2014
New Revision: 202469

URL: http://llvm.org/viewvc/llvm-project?rev=202469&view=rev
Log:
Swap PPC isel operands to allow for 0-folding

The PPC isel instruction can fold 0 into the first operand (thus eliminating
the need to materialize a zero-containing register when the 'true' result of
the isel is 0). When the isel is fed by a bit register operation that we can
invert, do so as part of the bit-register-operation peephole routine.

Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/PowerPC/crbits.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=202469&r1=202468&r2=202469&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Feb 28 00:11:16 2014
@@ -189,6 +189,9 @@ private:
 
     void PeepholePPC64();
     void PeepholdCROps();
+
+    bool AllUsersSelectZero(SDNode *N);
+    void SwapAllSelectUsers(SDNode *N);
   };
 }
 
@@ -1504,6 +1507,74 @@ void PPCDAGToDAGISel::PostprocessISelDAG
   PeepholdCROps();
 }
 
+// Check if all users of this node will become isel where the second operand
+// is the constant zero. If this is so, and if we can negate the condition,
+// then we can flip the true and false operands. This will allow the zero to
+// be folded with the isel so that we don't need to materialize a register
+// containing zero.
+bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *N) {
+  // If we're not using isel, then this does not matter.
+  if (!PPCSubTarget.hasISEL())
+    return false;
+
+  for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
+       UI != UE; ++UI) {
+    SDNode *User = *UI;
+    if (!User->isMachineOpcode())
+      return false;
+    if (User->getMachineOpcode() != PPC::SELECT_I4 &&
+        User->getMachineOpcode() != PPC::SELECT_I8)
+      return false;
+
+    SDNode *Op2 = User->getOperand(2).getNode();
+    if (!Op2->isMachineOpcode())
+      return false;
+
+    if (Op2->getMachineOpcode() != PPC::LI &&
+        Op2->getMachineOpcode() != PPC::LI8)
+      return false;
+
+    ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op2->getOperand(0));
+    if (!C)
+      return false;
+
+    if (!C->isNullValue())
+      return false;
+  }
+
+  return true;
+}
+
+void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *N) {
+  SmallVector<SDNode *, 4> ToReplace;
+  for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
+       UI != UE; ++UI) {
+    SDNode *User = *UI;
+    assert((User->getMachineOpcode() == PPC::SELECT_I4 ||
+            User->getMachineOpcode() == PPC::SELECT_I8) &&
+           "Must have all select users");
+    ToReplace.push_back(User);
+  }
+
+  for (SmallVector<SDNode *, 4>::iterator UI = ToReplace.begin(),
+       UE = ToReplace.end(); UI != UE; ++UI) {
+    SDNode *User = *UI;
+    SDNode *ResNode =
+      CurDAG->getMachineNode(User->getMachineOpcode(), SDLoc(User),
+                             User->getValueType(0), User->getOperand(0),
+                             User->getOperand(2),
+                             User->getOperand(1));
+
+      DEBUG(dbgs() << "CR Peephole replacing:\nOld:    ");
+      DEBUG(User->dump(CurDAG));
+      DEBUG(dbgs() << "\nNew: ");
+      DEBUG(ResNode->dump(CurDAG));
+      DEBUG(dbgs() << "\n");
+
+      ReplaceUses(User, ResNode);
+  }
+}
+
 void PPCDAGToDAGISel::PeepholdCROps() {
   bool IsModified;
   do {
@@ -1563,6 +1634,7 @@ void PPCDAGToDAGISel::PeepholdCROps() {
         break;
       }
 
+      bool SelectSwap = false;
       switch (Opcode) {
       default: break;
       case PPC::CRAND:
@@ -1591,6 +1663,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(0),
                                            MachineNode->getOperand(1).
                                              getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(0),
+                                           MachineNode->getOperand(1)),
+          SelectSwap = true;
         break;
       case PPC::CRNAND:
         if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
@@ -1624,6 +1701,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(1).
                                                       getOperand(0),
                                            MachineNode->getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CRAND, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(0),
+                                           MachineNode->getOperand(1)),
+          SelectSwap = true;
         break;
       case PPC::CROR:
         if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
@@ -1651,6 +1733,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(0),
                                            MachineNode->getOperand(1).
                                              getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CRNOR, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(0),
+                                           MachineNode->getOperand(1)),
+          SelectSwap = true;
         break;
       case PPC::CRXOR:
         if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
@@ -1685,6 +1772,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(0),
                                            MachineNode->getOperand(1).
                                              getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CREQV, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(0),
+                                           MachineNode->getOperand(1)),
+          SelectSwap = true;
         break;
       case PPC::CRNOR:
         if (Op1Set || Op2Set)
@@ -1713,6 +1805,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(1).
                                                       getOperand(0),
                                            MachineNode->getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CROR, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(0),
+                                           MachineNode->getOperand(1)),
+          SelectSwap = true;
         break;
       case PPC::CREQV:
         if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
@@ -1747,6 +1844,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(0),
                                            MachineNode->getOperand(1).
                                              getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CRXOR, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(0),
+                                           MachineNode->getOperand(1)),
+          SelectSwap = true;
         break;
       case PPC::CRANDC:
         if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
@@ -1777,6 +1879,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(0),
                                            MachineNode->getOperand(1).
                                              getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CRORC, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(1),
+                                           MachineNode->getOperand(0)),
+          SelectSwap = true;
         break;
       case PPC::CRORC:
         if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
@@ -1807,6 +1914,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
                                            MVT::i1, MachineNode->getOperand(0),
                                            MachineNode->getOperand(1).
                                              getOperand(0));
+        else if (AllUsersSelectZero(MachineNode))
+          ResNode = CurDAG->getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
+                                           MVT::i1, MachineNode->getOperand(1),
+                                           MachineNode->getOperand(0)),
+          SelectSwap = true;
         break;
       case PPC::SELECT_I4:
       case PPC::SELECT_I8:
@@ -1841,6 +1953,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
         break;
       }
 
+      // If we're inverting this node because it is used only by selects that
+      // we'd like to swap, then swap the selects before the node replacement.
+      if (SelectSwap)
+        SwapAllSelectUsers(MachineNode);
+
       if (ResNode != MachineNode) {
         DEBUG(dbgs() << "CR Peephole replacing:\nOld:    ");
         DEBUG(MachineNode->dump(CurDAG));

Modified: llvm/trunk/test/CodeGen/PowerPC/crbits.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/crbits.ll?rev=202469&r1=202468&r2=202469&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/crbits.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/crbits.ll Fri Feb 28 00:11:16 2014
@@ -2,10 +2,6 @@
 target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-unknown-linux-gnu"
 
-; FIXME: For a number of these we load (1, 0) for the isel into two registers,
-; whereas if we reverse the condition, we could use only one register (using ZERO
-; for 0 in the isel).
-
 ; Function Attrs: nounwind readnone
 define zeroext i1 @test1(float %v1, float %v2) #0 {
 entry:
@@ -18,12 +14,11 @@ entry:
 ; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
 ; CHECK-DAG: li [[REG1:[0-9]+]], 1
 ; CHECK-DAG: lfs [[REG2:[0-9]+]],
-; CHECK-DAG: li [[REG3:[0-9]+]], 0
 ; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
 ; CHECK: crnor
 ; CHECK: crnor
-; CHECK: crand [[REG4:[0-9]+]],
-; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
+; CHECK: crnand [[REG4:[0-9]+]],
+; CHECK: isel 3, 0, [[REG1]], [[REG4]]
 ; CHECK: blr
 }
 
@@ -39,12 +34,11 @@ entry:
 ; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
 ; CHECK-DAG: li [[REG1:[0-9]+]], 1
 ; CHECK-DAG: lfs [[REG2:[0-9]+]],
-; CHECK-DAG: li [[REG3:[0-9]+]], 0
 ; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
 ; CHECK: crnor
 ; CHECK: crnor
-; CHECK: crxor [[REG4:[0-9]+]],
-; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
+; CHECK: creqv [[REG4:[0-9]+]],
+; CHECK: isel 3, 0, [[REG1]], [[REG4]]
 ; CHECK: blr
 }
 
@@ -62,13 +56,12 @@ entry:
 ; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
 ; CHECK-DAG: li [[REG1:[0-9]+]], 1
 ; CHECK-DAG: lfs [[REG2:[0-9]+]],
-; CHECK-DAG: li [[REG3:[0-9]+]], 0
 ; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
 ; CHECK: crnor
 ; CHECK: crnor
 ; CHECK: crandc
-; CHECK: crxor [[REG4:[0-9]+]],
-; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
+; CHECK: creqv [[REG4:[0-9]+]],
+; CHECK: isel 3, 0, [[REG1]], [[REG4]]
 ; CHECK: blr
 }
 
@@ -96,11 +89,10 @@ entry:
 ; CHECK-LABEL: @test5
 ; CHECK-DAG: and [[REG1:[0-9]+]], 3, 4
 ; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
-; CHECK: li [[REG3:[0-9]+]], 1
-; CHECK: andi. {{[0-9]+}}, [[REG1]], 1
-; CHECK: li [[REG4:[0-9]+]], 0
-; CHECK: crorc [[REG5:[0-9]+]],
-; CHECK: isel 3, [[REG3]], [[REG4]], [[REG5]]
+; CHECK-DAG: li [[REG3:[0-9]+]], 1
+; CHECK-DAG: andi. {{[0-9]+}}, [[REG1]], 1
+; CHECK-DAG: crandc [[REG5:[0-9]+]],
+; CHECK: isel 3, 0, [[REG3]], [[REG5]]
 ; CHECK: blr
 }
 
@@ -116,12 +108,11 @@ entry:
 ; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
 ; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
 ; CHECK-DAG: cror [[REG1:[0-9]+]], 1, 1
-; CHECK: andi. {{[0-9]+}}, 4, 1
-; CHECK: li [[REG2:[0-9]+]], 1
-; CHECK: li [[REG3:[0-9]+]], 0
-; CHECK: crorc [[REG4:[0-9]+]], 1,
-; CHECK: crand [[REG5:[0-9]+]], [[REG4]], [[REG1]]
-; CHECK: isel 3, [[REG2]], [[REG3]], [[REG5]]
+; CHECK-DAG: andi. {{[0-9]+}}, 4, 1
+; CHECK-DAG: li [[REG2:[0-9]+]], 1
+; CHECK-DAG: crorc [[REG4:[0-9]+]], 1,
+; CHECK-DAG: crnand [[REG5:[0-9]+]], [[REG4]], [[REG1]]
+; CHECK: isel 3, 0, [[REG2]], [[REG5]]
 ; CHECK: blr
 }
 
@@ -163,10 +154,9 @@ entry:
 ; CHECK-LABEL: @test10
 ; CHECK-DAG: cmpwi {{[0-9]+}}, 3, 0
 ; CHECK-DAG: cmpwi {{[0-9]+}}, 4, 0
-; CHECK-DAG: li [[REG1:[0-9]+]], 0
 ; CHECK-DAG: li [[REG2:[0-9]+]], 1
-; CHECK: crandc [[REG3:[0-9]+]],
-; CHECK: isel 3, [[REG2]], [[REG1]], [[REG3]]
+; CHECK-DAG: crorc [[REG3:[0-9]+]],
+; CHECK: isel 3, 0, [[REG2]], [[REG3]]
 ; CHECK: blr
 }
 





More information about the llvm-commits mailing list