patch-r262582-llvm-r202422-sparc.diff revision 269012
11590SrgrimesPull in r202422 from upstream llvm trunk (by Roman Divacky):
21590Srgrimes
31590Srgrimes  Lower FNEG just like FABS to fneg[ds] and fmov[ds], thus avoiding
41590Srgrimes  expensive libcall. Also, Qp_neg is not implemented on at least
51590Srgrimes  FreeBSD. This is also what gcc is doing.
61590Srgrimes
71590SrgrimesIntroduced here: http://svnweb.freebsd.org/changeset/base/262582
81590Srgrimes
91590SrgrimesIndex: lib/Target/Sparc/SparcISelLowering.cpp
101590Srgrimes===================================================================
111590Srgrimes--- lib/Target/Sparc/SparcISelLowering.cpp
121590Srgrimes+++ lib/Target/Sparc/SparcISelLowering.cpp
131590Srgrimes@@ -2643,24 +2643,16 @@ static SDValue LowerF128Store(SDValue Op, Selectio
141590Srgrimes                      &OutChains[0], 2);
151590Srgrimes }
161590Srgrimes 
171590Srgrimes-static SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG,
181590Srgrimes-                         const SparcTargetLowering &TLI,
191590Srgrimes-                         bool is64Bit) {
201590Srgrimes-  if (Op.getValueType() == MVT::f64)
211590Srgrimes-    return LowerF64Op(Op, DAG, ISD::FNEG);
221590Srgrimes-  if (Op.getValueType() == MVT::f128)
231590Srgrimes-    return TLI.LowerF128Op(Op, DAG, ((is64Bit) ? "_Qp_neg" : "_Q_neg"), 1);
241590Srgrimes-  return Op;
251590Srgrimes-}
261590Srgrimes+static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
271590Srgrimes+  assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) && "invalid");
281590Srgrimes 
2950477Speter-static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
301590Srgrimes   if (Op.getValueType() == MVT::f64)
311590Srgrimes-    return LowerF64Op(Op, DAG, ISD::FABS);
321590Srgrimes+    return LowerF64Op(Op, DAG, Op.getOpcode());
3379535Sru   if (Op.getValueType() != MVT::f128)
341590Srgrimes     return Op;
351590Srgrimes 
3687862Sru-  // Lower fabs on f128 to fabs on f64
3787862Sru-  // fabs f128 => fabs f64:sub_even64, fmov f64:sub_odd64
3887862Sru+  // Lower fabs/fneg on f128 to fabs/fneg on f64
391590Srgrimes+  // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64
4068963Sru 
4197577Stjr   SDLoc dl(Op);
421590Srgrimes   SDValue SrcReg128 = Op.getOperand(0);
43107276Sru@@ -2671,7 +2663,7 @@ static SDValue LowerF128Store(SDValue Op, Selectio
441590Srgrimes   if (isV9)
4587862Sru     Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64);
4687862Sru   else
4787862Sru-    Hi64 = LowerF64Op(Hi64, DAG, ISD::FABS);
4887862Sru+    Hi64 = LowerF64Op(Hi64, DAG, Op.getOpcode());
4987862Sru 
501590Srgrimes   SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
511590Srgrimes                                                  dl, MVT::f128), 0);
521590Srgrimes@@ -2792,7 +2784,6 @@ SDValue SparcTargetLowering::
5387862Sru LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5487862Sru 
5587862Sru   bool hasHardQuad = Subtarget->hasHardQuad();
561590Srgrimes-  bool is64Bit     = Subtarget->is64Bit();
571590Srgrimes   bool isV9        = Subtarget->isV9();
581590Srgrimes 
591590Srgrimes   switch (Op.getOpcode()) {
601590Srgrimes@@ -2835,8 +2826,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
6187862Sru                                        getLibcallName(RTLIB::DIV_F128), 2);
621590Srgrimes   case ISD::FSQRT:              return LowerF128Op(Op, DAG,
631590Srgrimes                                        getLibcallName(RTLIB::SQRT_F128),1);
641590Srgrimes-  case ISD::FNEG:               return LowerFNEG(Op, DAG, *this, is64Bit);
651590Srgrimes-  case ISD::FABS:               return LowerFABS(Op, DAG, isV9);
6668963Sru+  case ISD::FABS:
671590Srgrimes+  case ISD::FNEG:               return LowerFNEGorFABS(Op, DAG, isV9);
681590Srgrimes   case ISD::FP_EXTEND:          return LowerF128_FPEXTEND(Op, DAG, *this);
6987750Scharnier   case ISD::FP_ROUND:           return LowerF128_FPROUND(Op, DAG, *this);
7087750Scharnier   case ISD::ADDC:
7187750ScharnierIndex: test/CodeGen/SPARC/fp128.ll
721590Srgrimes===================================================================
7387750Scharnier--- test/CodeGen/SPARC/fp128.ll
741590Srgrimes+++ test/CodeGen/SPARC/fp128.ll
751590Srgrimes@@ -232,3 +232,14 @@ entry:
7687750Scharnier   store  i32 %3, i32* %4, align 8
771590Srgrimes   ret void
781590Srgrimes }
7997577Stjr+
8097577Stjr+; SOFT-LABEL:     f128_neg
811590Srgrimes+; SOFT:           fnegs
8287750Scharnier+
8387862Sru+define void @f128_neg(fp128* noalias sret %scalar.result, fp128* byval %a) {
841590Srgrimes+entry:
851590Srgrimes+  %0 = load fp128* %a, align 8
8687750Scharnier+  %1 = fsub fp128 0xL00000000000000008000000000000000, %0
871590Srgrimes+  store fp128 %1, fp128* %scalar.result, align 8
8887862Sru+  ret void
891590Srgrimes+}
901590Srgrimes