diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff b/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff new file mode 100644 index 0000000..589dd47 --- /dev/null +++ b/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff @@ -0,0 +1,89 @@ +Pull in r202422 from upstream llvm trunk (by Roman Divacky): + + 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. + +Introduced here: http://svn.freebsd.org/changeset/base/262582 + +Index: lib/Target/Sparc/SparcISelLowering.cpp +=================================================================== +--- lib/Target/Sparc/SparcISelLowering.cpp ++++ lib/Target/Sparc/SparcISelLowering.cpp +@@ -2643,24 +2643,16 @@ static SDValue LowerF128Store(SDValue Op, Selectio + &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); +@@ -2671,7 +2663,7 @@ static SDValue LowerF128Store(SDValue Op, Selectio + 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); +@@ -2792,7 +2784,6 @@ SDValue SparcTargetLowering:: + LowerOperation(SDValue Op, SelectionDAG &DAG) const { + + bool hasHardQuad = Subtarget->hasHardQuad(); +- bool is64Bit = Subtarget->is64Bit(); + bool isV9 = Subtarget->isV9(); + + switch (Op.getOpcode()) { +@@ -2835,8 +2826,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons + 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: +Index: test/CodeGen/SPARC/fp128.ll +=================================================================== +--- test/CodeGen/SPARC/fp128.ll ++++ 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 ++} |