diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 0ed1112fff2..6f4d923cff9 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -259,6 +259,7 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::FNEG, (MVT::ValueType)VT, Expand); setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand); @@ -523,6 +524,16 @@ bool PPC::isSplatShuffleMask(SDNode *N, unsigned EltSize) { return true; } +/// isAllNegativeZeroVector - Returns true if all elements of build_vector +/// are -0.0. +bool PPC::isAllNegativeZeroVector(SDNode *N) { + assert(N->getOpcode() == ISD::BUILD_VECTOR); + if (PPC::isSplatShuffleMask(N, N->getNumOperands())) + if (ConstantFPSDNode *CFP = dyn_cast(N)) + return CFP->isExactlyValue(-0.0); + return false; +} + /// getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the /// specified isSplatShuffleMask VECTOR_SHUFFLE mask. unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize) { diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 05818652b6e..245fe53e5a7 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -160,6 +160,10 @@ namespace llvm { /// VSPLTB/VSPLTH/VSPLTW. bool isSplatShuffleMask(SDNode *N, unsigned EltSize); + /// isAllNegativeZeroVector - Returns true if all elements of build_vector + /// are -0.0. + bool isAllNegativeZeroVector(SDNode *N); + /// getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the /// specified isSplatShuffleMask VECTOR_SHUFFLE mask. unsigned getVSPLTImmediate(SDNode *N, unsigned EltSize); diff --git a/lib/Target/PowerPC/PPCInstrAltivec.td b/lib/Target/PowerPC/PPCInstrAltivec.td index 572be98825b..7a404adee62 100644 --- a/lib/Target/PowerPC/PPCInstrAltivec.td +++ b/lib/Target/PowerPC/PPCInstrAltivec.td @@ -70,7 +70,6 @@ def VMRGHW_unary_shuffle_mask : PatLeaf<(build_vector), [{ return PPC::isVMRGHShuffleMask(N, 4, true); }]>; - def VSLDOI_get_imm : SDNodeXForm; @@ -133,6 +132,10 @@ def vecspltisw : PatLeaf<(build_vector), [{ return PPC::get_VSPLTI_elt(N, 4, *CurDAG).Val != 0; }], VSPLTISW_get_imm>; +def V_immneg0 : PatLeaf<(build_vector), [{ + return PPC::isAllNegativeZeroVector(N); +}]>; + //===----------------------------------------------------------------------===// // Helpers for defining instructions that directly correspond to intrinsics. @@ -228,7 +231,8 @@ def VMADDFP : VAForm_1<46, (outs VRRC:$vD), (ins VRRC:$vA, VRRC:$vC, VRRC:$vB), Requires<[FPContractions]>; def VNMSUBFP: VAForm_1<47, (outs VRRC:$vD), (ins VRRC:$vA, VRRC:$vC, VRRC:$vB), "vnmsubfp $vD, $vA, $vC, $vB", VecFP, - [(set VRRC:$vD, (fneg (fsub (fmul VRRC:$vA, VRRC:$vC), + [(set VRRC:$vD, (fsub V_immneg0, + (fsub (fmul VRRC:$vA, VRRC:$vC), VRRC:$vB)))]>, Requires<[FPContractions]>;