[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