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