aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-28 22:28:18 +0000
committerChris Lattner <sabre@nondot.org>2005-09-28 22:28:18 +0000
commit01b3d73c20f5afb8265ae943a8ba23c2238c5eea (patch)
tree068bdd7a7effd620fa1b0b735ffb37c6c2fa7319 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parenta5cac6f6eb939b033c020cc59499756d2b95b349 (diff)
Add FP versions of the binary operators, keeping the int and fp worlds seperate.
Though I have done extensive testing, it is possible that this will break things in configs I can't test. Please let me know if this causes a problem and I'll fix it ASAP. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23504 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp61
1 files changed, 40 insertions, 21 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e3706c157e..61fa31959c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -36,6 +36,8 @@ static bool isCommutativeBinOp(unsigned Opcode) {
switch (Opcode) {
case ISD::ADD:
case ISD::MUL:
+ case ISD::FADD:
+ case ISD::FMUL:
case ISD::AND:
case ISD::OR:
case ISD::XOR: return true;
@@ -869,8 +871,7 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
return getSetCC(VT, N1, N2, NewCond);
}
- if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
- MVT::isInteger(N1.getValueType())) {
+ if (Cond == ISD::SETEQ || Cond == ISD::SETNE) {
if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB ||
N1.getOpcode() == ISD::XOR) {
// Simplify (X+Y) == (X+Z) --> Y == Z
@@ -1187,8 +1188,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
}
break;
case ISD::FNEG:
- if (OpOpcode == ISD::SUB) // -(X-Y) -> (Y-X)
- return getNode(ISD::SUB, VT, Operand.Val->getOperand(1),
+ if (OpOpcode == ISD::FSUB) // -(X-Y) -> (Y-X)
+ return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1),
Operand.Val->getOperand(0));
if (OpOpcode == ISD::FNEG) // --X -> X
return Operand.Val->getOperand(0);
@@ -1236,6 +1237,13 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
case ISD::MUL:
case ISD::SDIV:
case ISD::SREM:
+ assert(MVT::isInteger(N1.getValueType()) && "Should use F* for FP ops");
+ // fall through.
+ case ISD::FADD:
+ case ISD::FSUB:
+ case ISD::FMUL:
+ case ISD::FDIV:
+ case ISD::FREM:
assert(N1.getValueType() == N2.getValueType() &&
N1.getValueType() == VT && "Binary operator types must match!");
break;
@@ -1513,13 +1521,13 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
if (N2CFP) {
double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
switch (Opcode) {
- case ISD::ADD: return getConstantFP(C1 + C2, VT);
- case ISD::SUB: return getConstantFP(C1 - C2, VT);
- case ISD::MUL: return getConstantFP(C1 * C2, VT);
- case ISD::SDIV:
+ case ISD::FADD: return getConstantFP(C1 + C2, VT);
+ case ISD::FSUB: return getConstantFP(C1 - C2, VT);
+ case ISD::FMUL: return getConstantFP(C1 * C2, VT);
+ case ISD::FDIV:
if (C2) return getConstantFP(C1 / C2, VT);
break;
- case ISD::SREM :
+ case ISD::FREM :
if (C2) return getConstantFP(fmod(C1, C2), VT);
break;
default: break;
@@ -1623,33 +1631,39 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
break;
case ISD::ADD:
if (!CombinerEnabled) {
- if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B
- return getNode(ISD::SUB, VT, N1, N2.getOperand(0));
- if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A
- return getNode(ISD::SUB, VT, N2, N1.getOperand(0));
if (N1.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N1.getOperand(0)) &&
cast<ConstantSDNode>(N1.getOperand(0))->getValue() == 0)
return getNode(ISD::SUB, VT, N2, N1.getOperand(1)); // (0-A)+B -> B-A
if (N2.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N2.getOperand(0)) &&
cast<ConstantSDNode>(N2.getOperand(0))->getValue() == 0)
return getNode(ISD::SUB, VT, N1, N2.getOperand(1)); // A+(0-B) -> A-B
- if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1) &&
- !MVT::isFloatingPoint(N2.getValueType()))
+ if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1))
return N2.Val->getOperand(0); // A+(B-A) -> B
}
break;
+ case ISD::FADD:
+ if (!CombinerEnabled) {
+ if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B
+ return getNode(ISD::FSUB, VT, N1, N2.getOperand(0));
+ if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A
+ return getNode(ISD::FSUB, VT, N2, N1.getOperand(0));
+ }
+ break;
+
case ISD::SUB:
if (!CombinerEnabled) {
if (N1.getOpcode() == ISD::ADD) {
- if (N1.Val->getOperand(0) == N2 &&
- !MVT::isFloatingPoint(N2.getValueType()))
+ if (N1.Val->getOperand(0) == N2)
return N1.Val->getOperand(1); // (A+B)-A == B
- if (N1.Val->getOperand(1) == N2 &&
- !MVT::isFloatingPoint(N2.getValueType()))
+ if (N1.Val->getOperand(1) == N2)
return N1.Val->getOperand(0); // (A+B)-B == A
}
+ }
+ break;
+ case ISD::FSUB:
+ if (!CombinerEnabled) {
if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B
- return getNode(ISD::ADD, VT, N1, N2.getOperand(0));
+ return getNode(ISD::FADD, VT, N1, N2.getOperand(0));
}
break;
case ISD::FP_ROUND_INREG:
@@ -2333,7 +2347,12 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::SHL: return "shl";
case ISD::SRA: return "sra";
case ISD::SRL: return "srl";
-
+ case ISD::FADD: return "fadd";
+ case ISD::FSUB: return "fsub";
+ case ISD::FMUL: return "fmul";
+ case ISD::FDIV: return "fdiv";
+ case ISD::FREM: return "frem";
+
case ISD::SETCC: return "setcc";
case ISD::SELECT: return "select";
case ISD::SELECT_CC: return "select_cc";