mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
[LegalizeDAG][X86] Add support for turning STRICT_FADD/SUB/MUL/DIV into libcalls. Use it for fp128 on x86-64.
This requires a minor hack for f32/f64 strict fadd/fsub to avoid turning those into libcalls.
This commit is contained in:
parent
1ec7d930a9
commit
aa342adaa5
@ -4019,6 +4019,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
|
|||||||
RTLIB::LLRINT_PPCF128, Results);
|
RTLIB::LLRINT_PPCF128, Results);
|
||||||
break;
|
break;
|
||||||
case ISD::FDIV:
|
case ISD::FDIV:
|
||||||
|
case ISD::STRICT_FDIV:
|
||||||
ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64,
|
ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64,
|
||||||
RTLIB::DIV_F80, RTLIB::DIV_F128,
|
RTLIB::DIV_F80, RTLIB::DIV_F128,
|
||||||
RTLIB::DIV_PPCF128, Results);
|
RTLIB::DIV_PPCF128, Results);
|
||||||
@ -4036,11 +4037,13 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
|
|||||||
RTLIB::FMA_PPCF128, Results);
|
RTLIB::FMA_PPCF128, Results);
|
||||||
break;
|
break;
|
||||||
case ISD::FADD:
|
case ISD::FADD:
|
||||||
|
case ISD::STRICT_FADD:
|
||||||
ExpandFPLibCall(Node, RTLIB::ADD_F32, RTLIB::ADD_F64,
|
ExpandFPLibCall(Node, RTLIB::ADD_F32, RTLIB::ADD_F64,
|
||||||
RTLIB::ADD_F80, RTLIB::ADD_F128,
|
RTLIB::ADD_F80, RTLIB::ADD_F128,
|
||||||
RTLIB::ADD_PPCF128, Results);
|
RTLIB::ADD_PPCF128, Results);
|
||||||
break;
|
break;
|
||||||
case ISD::FMUL:
|
case ISD::FMUL:
|
||||||
|
case ISD::STRICT_FMUL:
|
||||||
ExpandFPLibCall(Node, RTLIB::MUL_F32, RTLIB::MUL_F64,
|
ExpandFPLibCall(Node, RTLIB::MUL_F32, RTLIB::MUL_F64,
|
||||||
RTLIB::MUL_F80, RTLIB::MUL_F128,
|
RTLIB::MUL_F80, RTLIB::MUL_F128,
|
||||||
RTLIB::MUL_PPCF128, Results);
|
RTLIB::MUL_PPCF128, Results);
|
||||||
@ -4058,6 +4061,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ISD::FSUB:
|
case ISD::FSUB:
|
||||||
|
case ISD::STRICT_FSUB:
|
||||||
ExpandFPLibCall(Node, RTLIB::SUB_F32, RTLIB::SUB_F64,
|
ExpandFPLibCall(Node, RTLIB::SUB_F32, RTLIB::SUB_F64,
|
||||||
RTLIB::SUB_F80, RTLIB::SUB_F128,
|
RTLIB::SUB_F80, RTLIB::SUB_F128,
|
||||||
RTLIB::SUB_PPCF128, Results);
|
RTLIB::SUB_PPCF128, Results);
|
||||||
|
@ -611,6 +611,13 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
|||||||
addLegalFPImmediate(APFloat(+0.0)); // xorpd
|
addLegalFPImmediate(APFloat(+0.0)); // xorpd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Mark these legal to prevent them from being expanded to a
|
||||||
|
// libcall in LegalizeDAG. They'll be mutated by X86ISelDAGToDAG::Select.
|
||||||
|
setOperationAction(ISD::STRICT_FADD, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::STRICT_FADD, MVT::f64, Legal);
|
||||||
|
setOperationAction(ISD::STRICT_FSUB, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::STRICT_FSUB, MVT::f64, Legal);
|
||||||
|
|
||||||
// We don't support FMA.
|
// We don't support FMA.
|
||||||
setOperationAction(ISD::FMA, MVT::f64, Expand);
|
setOperationAction(ISD::FMA, MVT::f64, Expand);
|
||||||
setOperationAction(ISD::FMA, MVT::f32, Expand);
|
setOperationAction(ISD::FMA, MVT::f32, Expand);
|
||||||
@ -659,11 +666,15 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
|||||||
|
|
||||||
addLegalFPImmediate(APFloat::getZero(APFloat::IEEEquad())); // xorps
|
addLegalFPImmediate(APFloat::getZero(APFloat::IEEEquad())); // xorps
|
||||||
|
|
||||||
setOperationAction(ISD::FADD, MVT::f128, LibCall);
|
setOperationAction(ISD::FADD, MVT::f128, LibCall);
|
||||||
setOperationAction(ISD::FSUB, MVT::f128, LibCall);
|
setOperationAction(ISD::STRICT_FADD, MVT::f128, LibCall);
|
||||||
setOperationAction(ISD::FDIV, MVT::f128, LibCall);
|
setOperationAction(ISD::FSUB, MVT::f128, LibCall);
|
||||||
setOperationAction(ISD::FMUL, MVT::f128, LibCall);
|
setOperationAction(ISD::STRICT_FSUB, MVT::f128, LibCall);
|
||||||
setOperationAction(ISD::FMA, MVT::f128, Expand);
|
setOperationAction(ISD::FDIV, MVT::f128, LibCall);
|
||||||
|
setOperationAction(ISD::STRICT_FDIV, MVT::f128, LibCall);
|
||||||
|
setOperationAction(ISD::FMUL, MVT::f128, LibCall);
|
||||||
|
setOperationAction(ISD::STRICT_FMUL, MVT::f128, LibCall);
|
||||||
|
setOperationAction(ISD::FMA, MVT::f128, Expand);
|
||||||
|
|
||||||
setOperationAction(ISD::FABS, MVT::f128, Custom);
|
setOperationAction(ISD::FABS, MVT::f128, Custom);
|
||||||
setOperationAction(ISD::FNEG, MVT::f128, Custom);
|
setOperationAction(ISD::FNEG, MVT::f128, Custom);
|
||||||
|
62
test/CodeGen/X86/fp128-libcalls-strict.ll
Normal file
62
test/CodeGen/X86/fp128-libcalls-strict.ll
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
|
; RUN: llc < %s -O2 -mtriple=x86_64-linux-android -mattr=+mmx \
|
||||||
|
; RUN: -enable-legalize-types-checking | FileCheck %s
|
||||||
|
; RUN: llc < %s -O2 -mtriple=x86_64-linux-gnu -mattr=+mmx \
|
||||||
|
; RUN: -enable-legalize-types-checking | FileCheck %s
|
||||||
|
|
||||||
|
; Check all soft floating point library function calls.
|
||||||
|
|
||||||
|
define fp128 @add(fp128 %x, fp128 %y) nounwind strictfp {
|
||||||
|
; CHECK-LABEL: add:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: pushq %rax
|
||||||
|
; CHECK-NEXT: callq __addtf3
|
||||||
|
; CHECK-NEXT: popq %rax
|
||||||
|
; CHECK-NEXT: retq
|
||||||
|
entry:
|
||||||
|
%add = call fp128 @llvm.experimental.constrained.fadd.f128(fp128 %x, fp128 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
|
||||||
|
ret fp128 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
define fp128 @sub(fp128 %x, fp128 %y) nounwind strictfp {
|
||||||
|
; CHECK-LABEL: sub:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: pushq %rax
|
||||||
|
; CHECK-NEXT: callq __subtf3
|
||||||
|
; CHECK-NEXT: popq %rax
|
||||||
|
; CHECK-NEXT: retq
|
||||||
|
entry:
|
||||||
|
%sub = call fp128 @llvm.experimental.constrained.fsub.f128(fp128 %x, fp128 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
|
||||||
|
ret fp128 %sub
|
||||||
|
}
|
||||||
|
|
||||||
|
define fp128 @mul(fp128 %x, fp128 %y) nounwind strictfp {
|
||||||
|
; CHECK-LABEL: mul:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: pushq %rax
|
||||||
|
; CHECK-NEXT: callq __multf3
|
||||||
|
; CHECK-NEXT: popq %rax
|
||||||
|
; CHECK-NEXT: retq
|
||||||
|
entry:
|
||||||
|
%mul = call fp128 @llvm.experimental.constrained.fmul.f128(fp128 %x, fp128 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
|
||||||
|
ret fp128 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define fp128 @div(fp128 %x, fp128 %y) nounwind strictfp {
|
||||||
|
; CHECK-LABEL: div:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: pushq %rax
|
||||||
|
; CHECK-NEXT: callq __divtf3
|
||||||
|
; CHECK-NEXT: popq %rax
|
||||||
|
; CHECK-NEXT: retq
|
||||||
|
entry:
|
||||||
|
%div = call fp128 @llvm.experimental.constrained.fdiv.f128(fp128 %x, fp128 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
|
||||||
|
ret fp128 %div
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { strictfp }
|
||||||
|
|
||||||
|
declare fp128 @llvm.experimental.constrained.fadd.f128(fp128, fp128, metadata, metadata)
|
||||||
|
declare fp128 @llvm.experimental.constrained.fsub.f128(fp128, fp128, metadata, metadata)
|
||||||
|
declare fp128 @llvm.experimental.constrained.fmul.f128(fp128, fp128, metadata, metadata)
|
||||||
|
declare fp128 @llvm.experimental.constrained.fdiv.f128(fp128, fp128, metadata, metadata)
|
Loading…
Reference in New Issue
Block a user