diff options
author | Andrew Wei <weiwei64@huawei.com> | 2020-01-14 00:16:23 +0800 |
---|---|---|
committer | Andrew Wei <weiwei64@huawei.com> | 2020-01-14 01:01:56 +0800 |
commit | 05366870eed154c7eb48c7cc3873ea5188f54cc9 (patch) | |
tree | 64f3ff2a1a5dafde905ec56de059a34773f7b08e | |
parent | 38e2c01221a9751c0b797417747200d2e9513b9f (diff) | |
download | bcm5719-llvm-05366870eed154c7eb48c7cc3873ea5188f54cc9.tar.gz bcm5719-llvm-05366870eed154c7eb48c7cc3873ea5188f54cc9.zip |
[LegalizeTypes] Add SoftenFloatResult support for STRICT_SINT_TO_FP/STRICT_UINT_TO_FP
Some target like arm/riscv with soft-float will have compiling crash when using -fno-unsafe-math-optimization option.
This patch will add the missing strict FP support to SoftenFloatRes_XINT_TO_FP.
Differential Revision: https://reviews.llvm.org/D72277
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 24 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/fp-intrinsics.ll | 18 |
2 files changed, 34 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index f1edb3d0d98..f191160dee4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -125,6 +125,8 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break; case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; + case ISD::STRICT_SINT_TO_FP: + case ISD::STRICT_UINT_TO_FP: case ISD::SINT_TO_FP: case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break; @@ -715,8 +717,10 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode *N) { } SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { - bool Signed = N->getOpcode() == ISD::SINT_TO_FP; - EVT SVT = N->getOperand(0).getValueType(); + bool IsStrict = N->isStrictFPOpcode(); + bool Signed = N->getOpcode() == ISD::SINT_TO_FP || + N->getOpcode() == ISD::STRICT_SINT_TO_FP; + EVT SVT = N->getOperand(IsStrict ? 1 : 0).getValueType(); EVT RVT = N->getValueType(0); EVT NVT = EVT(); SDLoc dl(N); @@ -734,16 +738,20 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { } assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); + SDValue Chain = IsStrict ? N->getOperand(0) : SDValue(); // Sign/zero extend the argument if the libcall takes a larger type. SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, - NVT, N->getOperand(0)); + NVT, N->getOperand(IsStrict ? 1 : 0)); TargetLowering::MakeLibCallOptions CallOptions; CallOptions.setSExt(Signed); - EVT OpsVT[1] = { N->getOperand(0).getValueType() }; - CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true); - return TLI.makeLibCall(DAG, LC, - TLI.getTypeToTransformTo(*DAG.getContext(), RVT), - Op, CallOptions, dl).first; + CallOptions.setTypeListBeforeSoften(SVT, RVT, true); + std::pair<SDValue, SDValue> Tmp = + TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT), + Op, CallOptions, dl, Chain); + + if (IsStrict) + ReplaceValueWith(SDValue(N, 1), Tmp.second); + return Tmp.first; } diff --git a/llvm/test/CodeGen/ARM/fp-intrinsics.ll b/llvm/test/CodeGen/ARM/fp-intrinsics.ll index 5eb20166483..9a15a626e28 100644 --- a/llvm/test/CodeGen/ARM/fp-intrinsics.ll +++ b/llvm/test/CodeGen/ARM/fp-intrinsics.ll @@ -488,6 +488,22 @@ define double @fpext_f32(float %x) #0 { ret double %val } +; CHECK-LABEL: sitofp_f32_i32: +; CHECK-NOSP: bl __aeabi_i2f +; CHECK-SP: vcvt.f32.s32 +define float @sitofp_f32_i32(i32 %x) #0 { + %val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0 + ret float %val +} + +; CHECK-LABEL: sitofp_f64_i32: +; CHECK-NODP: bl __aeabi_i2d +; CHECK-DP: vcvt.f64.s32 +define double @sitofp_f64_i32(i32 %x) #0 { + %val = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0 + ret double %val +} + attributes #0 = { strictfp } @@ -555,3 +571,5 @@ declare double @llvm.experimental.constrained.trunc.f64(double, metadata) declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata) declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata) +declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) +declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata) |