1Pull in r202422 from upstream llvm trunk (by Roman Divacky):
2
3  Lower FNEG just like FABS to fneg[ds] and fmov[ds], thus avoiding
4  expensive libcall. Also, Qp_neg is not implemented on at least
5  FreeBSD. This is also what gcc is doing.
6
7Introduced here: http://svn.freebsd.org/changeset/base/262582
8
9Index: lib/Target/Sparc/SparcISelLowering.cpp
10===================================================================
11--- lib/Target/Sparc/SparcISelLowering.cpp
12+++ lib/Target/Sparc/SparcISelLowering.cpp
13@@ -2643,24 +2643,16 @@ static SDValue LowerF128Store(SDValue Op, Selectio
14                      &OutChains[0], 2);
15 }
16 
17-static SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG,
18-                         const SparcTargetLowering &TLI,
19-                         bool is64Bit) {
20-  if (Op.getValueType() == MVT::f64)
21-    return LowerF64Op(Op, DAG, ISD::FNEG);
22-  if (Op.getValueType() == MVT::f128)
23-    return TLI.LowerF128Op(Op, DAG, ((is64Bit) ? "_Qp_neg" : "_Q_neg"), 1);
24-  return Op;
25-}
26+static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
27+  assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) && "invalid");
28 
29-static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
30   if (Op.getValueType() == MVT::f64)
31-    return LowerF64Op(Op, DAG, ISD::FABS);
32+    return LowerF64Op(Op, DAG, Op.getOpcode());
33   if (Op.getValueType() != MVT::f128)
34     return Op;
35 
36-  // Lower fabs on f128 to fabs on f64
37-  // fabs f128 => fabs f64:sub_even64, fmov f64:sub_odd64
38+  // Lower fabs/fneg on f128 to fabs/fneg on f64
39+  // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64
40 
41   SDLoc dl(Op);
42   SDValue SrcReg128 = Op.getOperand(0);
43@@ -2671,7 +2663,7 @@ static SDValue LowerF128Store(SDValue Op, Selectio
44   if (isV9)
45     Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64);
46   else
47-    Hi64 = LowerF64Op(Hi64, DAG, ISD::FABS);
48+    Hi64 = LowerF64Op(Hi64, DAG, Op.getOpcode());
49 
50   SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
51                                                  dl, MVT::f128), 0);
52@@ -2792,7 +2784,6 @@ SDValue SparcTargetLowering::
53 LowerOperation(SDValue Op, SelectionDAG &DAG) const {
54 
55   bool hasHardQuad = Subtarget->hasHardQuad();
56-  bool is64Bit     = Subtarget->is64Bit();
57   bool isV9        = Subtarget->isV9();
58 
59   switch (Op.getOpcode()) {
60@@ -2835,8 +2826,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
61                                        getLibcallName(RTLIB::DIV_F128), 2);
62   case ISD::FSQRT:              return LowerF128Op(Op, DAG,
63                                        getLibcallName(RTLIB::SQRT_F128),1);
64-  case ISD::FNEG:               return LowerFNEG(Op, DAG, *this, is64Bit);
65-  case ISD::FABS:               return LowerFABS(Op, DAG, isV9);
66+  case ISD::FABS:
67+  case ISD::FNEG:               return LowerFNEGorFABS(Op, DAG, isV9);
68   case ISD::FP_EXTEND:          return LowerF128_FPEXTEND(Op, DAG, *this);
69   case ISD::FP_ROUND:           return LowerF128_FPROUND(Op, DAG, *this);
70   case ISD::ADDC:
71Index: test/CodeGen/SPARC/fp128.ll
72===================================================================
73--- test/CodeGen/SPARC/fp128.ll
74+++ test/CodeGen/SPARC/fp128.ll
75@@ -232,3 +232,14 @@ entry:
76   store  i32 %3, i32* %4, align 8
77   ret void
78 }
79+
80+; SOFT-LABEL:     f128_neg
81+; SOFT:           fnegs
82+
83+define void @f128_neg(fp128* noalias sret %scalar.result, fp128* byval %a) {
84+entry:
85+  %0 = load fp128* %a, align 8
86+  %1 = fsub fp128 0xL00000000000000008000000000000000, %0
87+  store fp128 %1, fp128* %scalar.result, align 8
88+  ret void
89+}
90