freebsd-dev/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff
Dimitry Andric a1f8ad145e Add separate patch files for all the customizations we have currently
applied to our copy of llvm/clang.  These can be applied in alphabetical
order to a pristine llvm/clang 3.4 release source tree, to result in the
same version used in FreeBSD.

This is intended to clearly document all the changes until now, which
mostly consist of cherry pickings from the respective upstream trunks,
plus a number of hand-written FreeBSD-specific ones.  Hopefully those
can eventually be cleaned up and sent upstream too.

MFC after:	1 week
X-MFC-With:	r263313
2014-03-18 22:07:45 +00:00

90 lines
3.5 KiB
Diff

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.
Introduced here: http://svn.freebsd.org/changeset/base/262582
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
+}