diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 75352982034..052daa29c4e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -314,7 +314,7 @@ public: // void visitBinary(User &I, unsigned Opcode); void visitAdd(User &I) { visitBinary(I, ISD::ADD); } - void visitSub(User &I) { visitBinary(I, ISD::SUB); } + void visitSub(User &I); void visitMul(User &I) { visitBinary(I, ISD::MUL); } void visitDiv(User &I) { visitBinary(I, I.getType()->isUnsigned() ? ISD::UDIV : ISD::SDIV); @@ -454,6 +454,18 @@ void SelectionDAGLowering::visitBr(BranchInst &I) { } } +void SelectionDAGLowering::visitSub(User &I) { + // -0.0 - X --> fneg + if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) + if (CFP->isExactlyValue(-0.0)) { + SDOperand Op2 = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2)); + return; + } + + visitBinary(I, ISD::SUB); +} + void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode) { SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1));