aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCISelPattern.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-04-07 20:30:01 +0000
committerNate Begeman <natebegeman@mac.com>2005-04-07 20:30:01 +0000
commit7e7fadd2ea20f8b78bf9d6d7ff9ac4488df67152 (patch)
tree12099ac4ae5655fe7cd5a2c53c638ec699c19d52 /lib/Target/PowerPC/PPCISelPattern.cpp
parentd3355e22a7e5a2bb1254a4ac18f81175cab40a2e (diff)
Optimized code sequences for setcc reg, 0
Optimized code sequence for (a < 0) ? b : 0 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21150 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCISelPattern.cpp')
-rw-r--r--lib/Target/PowerPC/PPCISelPattern.cpp81
1 files changed, 77 insertions, 4 deletions
diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp
index 3c3b14e132..046045ad4f 100644
--- a/lib/Target/PowerPC/PPCISelPattern.cpp
+++ b/lib/Target/PowerPC/PPCISelPattern.cpp
@@ -1898,8 +1898,64 @@ unsigned ISel::SelectExpr(SDOperand N) {
case ISD::SETCC:
if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
+ // We can codegen setcc op, 0 very efficiently compared to a conditional
+ // branch. Check for that here.
+ if (ConstantSDNode *CN =
+ dyn_cast<ConstantSDNode>(SetCC->getOperand(1).Val)) {
+ if (CN->getValue() == 0) {
+ Tmp1 = SelectExpr(SetCC->getOperand(0));
+ switch (SetCC->getCondition()) {
+ default: assert(0 && "Unhandled SetCC condition"); abort();
+ case ISD::SETEQ:
+ case ISD::SETULE:
+ Tmp2 = MakeReg(MVT::i32);
+ BuildMI(BB, PPC::CNTLZW, 1, Tmp2).addReg(Tmp1);
+ BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp2).addImm(27)
+ .addImm(5).addImm(31);
+ break;
+ case ISD::SETNE:
+ case ISD::SETUGT:
+ Tmp2 = MakeReg(MVT::i32);
+ BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(-1);
+ BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp2).addReg(Tmp1);
+ break;
+ case ISD::SETULT:
+ BuildMI(BB, PPC::LI, 1, Result).addSImm(0);
+ break;
+ case ISD::SETLT:
+ BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(1)
+ .addImm(31).addImm(31);
+ break;
+ case ISD::SETLE:
+ Tmp2 = MakeReg(MVT::i32);
+ Tmp3 = MakeReg(MVT::i32);
+ BuildMI(BB, PPC::NEG, 2, Tmp2).addReg(Tmp1);
+ BuildMI(BB, PPC::ORC, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+ BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1)
+ .addImm(31).addImm(31);
+ break;
+ case ISD::SETGT:
+ Tmp2 = MakeReg(MVT::i32);
+ Tmp3 = MakeReg(MVT::i32);
+ BuildMI(BB, PPC::NEG, 2, Tmp2).addReg(Tmp1);
+ BuildMI(BB, PPC::ANDC, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
+ BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1)
+ .addImm(31).addImm(31);
+ break;
+ case ISD::SETUGE:
+ BuildMI(BB, PPC::LI, 1, Result).addSImm(1);
+ break;
+ case ISD::SETGE:
+ BuildMI(BB, PPC::RLWINM, 4, Tmp2).addReg(Tmp1).addImm(1)
+ .addImm(31).addImm(31);
+ BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp2).addImm(1);
+ break;
+ }
+ return Result;
+ }
+ }
+
Opc = SelectSetCR0(N);
-
unsigned TrueValue = MakeReg(MVT::i32);
BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1);
unsigned FalseValue = MakeReg(MVT::i32);
@@ -1946,6 +2002,25 @@ unsigned ISel::SelectExpr(SDOperand N) {
return 0;
case ISD::SELECT: {
+ // We can codegen select (a < 0) ? b : 0 very efficiently compared to a
+ // conditional branch. Check for that here.
+ if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(N.getOperand(0).Val)) {
+ if (ConstantSDNode *CN =
+ dyn_cast<ConstantSDNode>(SetCC->getOperand(1).Val)) {
+ if (ConstantSDNode *CNF =
+ dyn_cast<ConstantSDNode>(N.getOperand(2).Val)) {
+ if (CN->getValue() == 0 && CNF->getValue() == 0 &&
+ SetCC->getCondition() == ISD::SETLT) {
+ Tmp1 = SelectExpr(N.getOperand(1)); // TRUE value
+ Tmp2 = SelectExpr(SetCC->getOperand(0));
+ Tmp3 = MakeReg(MVT::i32);
+ BuildMI(BB, PPC::SRAWI, 2, Tmp3).addReg(Tmp2).addImm(31);
+ BuildMI(BB, PPC::AND, 2, Result).addReg(Tmp1).addReg(Tmp3);
+ return Result;
+ }
+ }
+ }
+ }
unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
Opc = SelectSetCR0(N.getOperand(0));
@@ -1986,8 +2061,6 @@ unsigned ISel::SelectExpr(SDOperand N) {
BB = sinkMBB;
BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
.addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
-
- // FIXME: Select i64?
return Result;
}
@@ -2123,7 +2196,7 @@ void ISel::Select(SDOperand N) {
} else { //ISD::TRUNCSTORE
switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
default: assert(0 && "unknown Type in store");
- case MVT::i1: //FIXME: DAG does not promote this load
+ case MVT::i1:
case MVT::i8: Opc = PPC::STB; break;
case MVT::i16: Opc = PPC::STH; break;
}