summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff89
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
++}
OpenPOWER on IntegriCloud