1 Pull in r202422 from upstream llvm trunk (by Roman Divacky):
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.
7 Introduced here: http://svn.freebsd.org/changeset/base/262582
9 Index: 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
17 -static SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG,
18 - const SparcTargetLowering &TLI,
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);
26 +static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
27 + assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) && "invalid");
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)
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
42 SDValue SrcReg128 = Op.getOperand(0);
43 @@ -2671,7 +2663,7 @@ static SDValue LowerF128Store(SDValue Op, Selectio
45 Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64);
47 - Hi64 = LowerF64Op(Hi64, DAG, ISD::FABS);
48 + Hi64 = LowerF64Op(Hi64, DAG, Op.getOpcode());
50 SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
52 @@ -2792,7 +2784,6 @@ SDValue SparcTargetLowering::
53 LowerOperation(SDValue Op, SelectionDAG &DAG) const {
55 bool hasHardQuad = Subtarget->hasHardQuad();
56 - bool is64Bit = Subtarget->is64Bit();
57 bool isV9 = Subtarget->isV9();
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);
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);
71 Index: 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
80 +; SOFT-LABEL: f128_neg
83 +define void @f128_neg(fp128* noalias sret %scalar.result, fp128* byval %a) {
85 + %0 = load fp128* %a, align 8
86 + %1 = fsub fp128 0xL00000000000000008000000000000000, %0
87 + store fp128 %1, fp128* %scalar.result, align 8