2014-03-18 22:07:45 +00:00
|
|
|
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.
|
|
|
|
|
2014-05-24 22:27:31 +00:00
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/262582
|
2014-03-18 22:07:45 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
+}
|