From f36febf578af586eda2eaab1a0b212ec641a7c94 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Thu, 27 Feb 2014 19:26:29 +0000 Subject: [PATCH] Lower FNEG just like FABS to fneg[ds] and fmov[ds], thus avoiding expensive libcall. Also, Qp_neg is not implemented on at least FreeBSD. This is also what gcc is doing. llvm-svn: 202422 --- lib/Target/Sparc/SparcISelLowering.cpp | 25 ++++++++----------------- test/CodeGen/SPARC/fp128.ll | 11 +++++++++++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 2ac5b7e8c22..632cc2b8b7f 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -2648,24 +2648,16 @@ static SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG) { &OutChains[0], 2); } -static SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG, - const SparcTargetLowering &TLI, - bool is64Bit) { - if (Op.getValueType() == MVT::f64) - return LowerF64Op(Op, DAG, ISD::FNEG); - if (Op.getValueType() == MVT::f128) - return TLI.LowerF128Op(Op, DAG, ((is64Bit) ? "_Qp_neg" : "_Q_neg"), 1); - return Op; -} +static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) { + assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) && "invalid"); -static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG, bool isV9) { if (Op.getValueType() == MVT::f64) - return LowerF64Op(Op, DAG, ISD::FABS); + return LowerF64Op(Op, DAG, Op.getOpcode()); if (Op.getValueType() != MVT::f128) return Op; - // Lower fabs on f128 to fabs on f64 - // fabs f128 => fabs f64:sub_even64, fmov f64:sub_odd64 + // Lower fabs/fneg on f128 to fabs/fneg on f64 + // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64 SDLoc dl(Op); SDValue SrcReg128 = Op.getOperand(0); @@ -2676,7 +2668,7 @@ static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG, bool isV9) { if (isV9) Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64); else - Hi64 = LowerF64Op(Hi64, DAG, ISD::FABS); + Hi64 = LowerF64Op(Hi64, DAG, Op.getOpcode()); SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::f128), 0); @@ -2797,7 +2789,6 @@ SDValue SparcTargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG) const { bool hasHardQuad = Subtarget->hasHardQuad(); - bool is64Bit = Subtarget->is64Bit(); bool isV9 = Subtarget->isV9(); switch (Op.getOpcode()) { @@ -2840,8 +2831,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const { getLibcallName(RTLIB::DIV_F128), 2); case ISD::FSQRT: return LowerF128Op(Op, DAG, getLibcallName(RTLIB::SQRT_F128),1); - case ISD::FNEG: return LowerFNEG(Op, DAG, *this, is64Bit); - case ISD::FABS: return LowerFABS(Op, DAG, isV9); + case ISD::FABS: + case ISD::FNEG: return LowerFNEGorFABS(Op, DAG, isV9); case ISD::FP_EXTEND: return LowerF128_FPEXTEND(Op, DAG, *this); case ISD::FP_ROUND: return LowerF128_FPROUND(Op, DAG, *this); case ISD::ADDC: diff --git a/test/CodeGen/SPARC/fp128.ll b/test/CodeGen/SPARC/fp128.ll index 37e759ff9eb..abd89bf264e 100644 --- a/test/CodeGen/SPARC/fp128.ll +++ b/test/CodeGen/SPARC/fp128.ll @@ -232,3 +232,14 @@ entry: store i32 %3, i32* %4, align 8 ret void } + +; SOFT-LABEL: f128_neg +; SOFT: fnegs + +define void @f128_neg(fp128* noalias sret %scalar.result, fp128* byval %a) { +entry: + %0 = load fp128* %a, align 8 + %1 = fsub fp128 0xL00000000000000008000000000000000, %0 + store fp128 %1, fp128* %scalar.result, align 8 + ret void +}