From 8f73a93b2deb77f08822e3d34a7c144687a19c80 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 27 Nov 2019 17:25:26 -0800 Subject: [PATCH] [X86] Add support for STRICT_FP_TO_UINT/SINT from fp128. --- llvm/lib/Target/X86/X86ISelLowering.cpp | 13 ++-- llvm/test/CodeGen/X86/fp128-cast-strict.ll | 108 +++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 535493a..c4ad263 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -19712,15 +19712,20 @@ SDValue X86TargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const { // fp128 needs to use a libcall. if (SrcVT == MVT::f128) { RTLIB::Libcall LC; - if (Op.getOpcode() == ISD::FP_TO_SINT) + if (IsSigned) LC = RTLIB::getFPTOSINT(SrcVT, VT); else LC = RTLIB::getFPTOUINT(SrcVT, VT); - // FIXME: Strict fp! - assert(!IsStrict && "Unhandled strict operation!"); + SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue(); MakeLibCallOptions CallOptions; - return makeLibCall(DAG, LC, VT, Src, CallOptions, SDLoc(Op)).first; + std::pair Tmp = makeLibCall(DAG, LC, VT, Src, CallOptions, + SDLoc(Op), Chain); + + if (IsStrict) + return DAG.getMergeValues({ Tmp.first, Tmp.second }, dl); + + return Tmp.first; } // Fall back to X87. diff --git a/llvm/test/CodeGen/X86/fp128-cast-strict.ll b/llvm/test/CodeGen/X86/fp128-cast-strict.ll index 84964d7..99bca70 100644 --- a/llvm/test/CodeGen/X86/fp128-cast-strict.ll +++ b/llvm/test/CodeGen/X86/fp128-cast-strict.ll @@ -165,6 +165,106 @@ entry: ret void } +define i8 @fptosi_i8(fp128 %x) nounwind strictfp { +; X64-LABEL: fptosi_i8: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixtfsi +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i8 @llvm.experimental.constrained.fptosi.i8.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i8 %conv +} + +define i16 @fptosi_i16(fp128 %x) nounwind strictfp { +; X64-LABEL: fptosi_i16: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixtfsi +; X64-NEXT: # kill: def $ax killed $ax killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i16 @llvm.experimental.constrained.fptosi.i16.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i16 %conv +} + +define i32 @fptosi_i32(fp128 %x) nounwind strictfp { +; X64-LABEL: fptosi_i32: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixtfsi +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i32 %conv +} + +define i64 @fptosi_i64(fp128 %x) nounwind strictfp { +; X64-LABEL: fptosi_i64: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixtfdi +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i64 %conv +} + +define i8 @fptoui_i8(fp128 %x) nounwind strictfp { +; X64-LABEL: fptoui_i8: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixtfsi +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i8 @llvm.experimental.constrained.fptoui.i8.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i8 %conv +} + +define i16 @fptoui_i16(fp128 %x) nounwind strictfp { +; X64-LABEL: fptoui_i16: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixtfsi +; X64-NEXT: # kill: def $ax killed $ax killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i16 @llvm.experimental.constrained.fptoui.i16.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i16 %conv +} + +define i32 @fptoui_i32(fp128 %x) nounwind strictfp { +; X64-LABEL: fptoui_i32: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixunstfsi +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i32 @llvm.experimental.constrained.fptoui.i32.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i32 %conv +} + +define i64 @fptoui_i64(fp128 %x) nounwind strictfp { +; X64-LABEL: fptoui_i64: +; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rax +; X64-NEXT: callq __fixunstfdi +; X64-NEXT: popq %rcx +; X64-NEXT: retq +entry: + %conv = call i64 @llvm.experimental.constrained.fptoui.i64.f128(fp128 %x, metadata !"fpexcept.strict") #0 + ret i64 %conv +} + attributes #0 = { strictfp } declare float @llvm.experimental.constrained.fptrunc.f32.f128(fp128, metadata, metadata) @@ -173,3 +273,11 @@ declare x86_fp80 @llvm.experimental.constrained.fptrunc.f80.f128(fp128, metadata declare fp128 @llvm.experimental.constrained.fpext.f128.f32(float, metadata) declare fp128 @llvm.experimental.constrained.fpext.f128.f64(double, metadata) declare fp128 @llvm.experimental.constrained.fpext.f128.f80(x86_fp80, metadata) +declare i8 @llvm.experimental.constrained.fptosi.i8.f128(fp128, metadata) +declare i16 @llvm.experimental.constrained.fptosi.i16.f128(fp128, metadata) +declare i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128, metadata) +declare i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128, metadata) +declare i8 @llvm.experimental.constrained.fptoui.i8.f128(fp128, metadata) +declare i16 @llvm.experimental.constrained.fptoui.i16.f128(fp128, metadata) +declare i32 @llvm.experimental.constrained.fptoui.i32.f128(fp128, metadata) +declare i64 @llvm.experimental.constrained.fptoui.i64.f128(fp128, metadata) -- 2.7.4