a1f8ad145e
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
90 lines
3.5 KiB
Diff
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
|
|
+}
|