[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Mar 4 21:31:08 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.120 -> 1.121
SelectionDAG.cpp updated: 1.266 -> 1.267
---
Log message:
Add some simple copysign folds
---
Diffs of the changes: (+61 -7)
DAGCombiner.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++------
SelectionDAG.cpp | 2 +
2 files changed, 61 insertions(+), 7 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.120 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.121
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.120 Sat Mar 4 17:33:26 2006
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Mar 4 23:30:57 2006
@@ -195,6 +195,7 @@
SDOperand visitFMUL(SDNode *N);
SDOperand visitFDIV(SDNode *N);
SDOperand visitFREM(SDNode *N);
+ SDOperand visitFCOPYSIGN(SDNode *N);
SDOperand visitSINT_TO_FP(SDNode *N);
SDOperand visitUINT_TO_FP(SDNode *N);
SDOperand visitFP_TO_SINT(SDNode *N);
@@ -627,6 +628,7 @@
case ISD::FMUL: return visitFMUL(N);
case ISD::FDIV: return visitFDIV(N);
case ISD::FREM: return visitFREM(N);
+ case ISD::FCOPYSIGN: return visitFCOPYSIGN(N);
case ISD::SINT_TO_FP: return visitSINT_TO_FP(N);
case ISD::UINT_TO_FP: return visitUINT_TO_FP(N);
case ISD::FP_TO_SINT: return visitFP_TO_SINT(N);
@@ -1999,6 +2001,54 @@
return SDOperand();
}
+SDOperand DAGCombiner::visitFCOPYSIGN(SDNode *N) {
+ SDOperand N0 = N->getOperand(0);
+ SDOperand N1 = N->getOperand(1);
+ ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
+ ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
+ MVT::ValueType VT = N->getValueType(0);
+
+ if (N0CFP && N1CFP) // Constant fold
+ return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1);
+
+ if (N1CFP) {
+ // copysign(x, c1) -> fabs(x) iff ispos(c1)
+ // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1)
+ union {
+ double d;
+ int64_t i;
+ } u;
+ u.d = N1CFP->getValue();
+ if (u.i >= 0)
+ return DAG.getNode(ISD::FABS, VT, N0);
+ else
+ return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0));
+ }
+
+ // copysign(fabs(x), y) -> copysign(x, y)
+ // copysign(fneg(x), y) -> copysign(x, y)
+ // copysign(copysign(x,z), y) -> copysign(x, y)
+ if (N0.getOpcode() == ISD::FABS || N0.getOpcode() == ISD::FNEG ||
+ N0.getOpcode() == ISD::FCOPYSIGN)
+ return DAG.getNode(ISD::FCOPYSIGN, VT, N0.getOperand(0), N1);
+
+ // copysign(x, abs(y)) -> abs(x)
+ if (N1.getOpcode() == ISD::FABS)
+ return DAG.getNode(ISD::FABS, VT, N0);
+
+ // copysign(x, copysign(y,z)) -> copysign(x, z)
+ if (N1.getOpcode() == ISD::FCOPYSIGN)
+ return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(1));
+
+ // copysign(x, fp_extend(y)) -> copysign(x, y)
+ // copysign(x, fp_round(y)) -> copysign(x, y)
+ if (N1.getOpcode() == ISD::FP_EXTEND || N1.getOpcode() == ISD::FP_ROUND)
+ return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(0));
+
+ return SDOperand();
+}
+
+
SDOperand DAGCombiner::visitSINT_TO_FP(SDNode *N) {
SDOperand N0 = N->getOperand(0);
@@ -2089,11 +2139,11 @@
if (N0CFP)
return DAG.getNode(ISD::FNEG, VT, N0);
// fold (fneg (sub x, y)) -> (sub y, x)
- if (N->getOperand(0).getOpcode() == ISD::SUB)
- return DAG.getNode(ISD::SUB, VT, N->getOperand(1), N->getOperand(0));
+ if (N0.getOpcode() == ISD::SUB)
+ return DAG.getNode(ISD::SUB, VT, N0.getOperand(1), N0.getOperand(0));
// fold (fneg (fneg x)) -> x
- if (N->getOperand(0).getOpcode() == ISD::FNEG)
- return N->getOperand(0).getOperand(0);
+ if (N0.getOpcode() == ISD::FNEG)
+ return N0.getOperand(0);
return SDOperand();
}
@@ -2106,11 +2156,13 @@
if (N0CFP)
return DAG.getNode(ISD::FABS, VT, N0);
// fold (fabs (fabs x)) -> (fabs x)
- if (N->getOperand(0).getOpcode() == ISD::FABS)
+ if (N0.getOpcode() == ISD::FABS)
return N->getOperand(0);
// fold (fabs (fneg x)) -> (fabs x)
- if (N->getOperand(0).getOpcode() == ISD::FNEG)
- return DAG.getNode(ISD::FABS, VT, N->getOperand(0).getOperand(0));
+ // fold (fabs (fcopysign x, y)) -> (fabs x)
+ if (N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN)
+ return DAG.getNode(ISD::FABS, VT, N0.getOperand(0));
+
return SDOperand();
}
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.266 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.267
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.266 Sat Mar 4 23:09:38 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Mar 4 23:30:57 2006
@@ -1250,6 +1250,8 @@
case ISD::FREM :
if (C2) return getConstantFP(fmod(C1, C2), VT);
break;
+ case ISD::FCOPYSIGN:
+ return getConstantFP(copysign(C1, C2), VT);
default: break;
}
} else { // Cannonicalize constant to RHS if commutative
More information about the llvm-commits
mailing list