diff options
author | Craig Topper <craig.topper@intel.com> | 2019-11-26 10:59:18 -0800 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2019-11-26 10:59:41 -0800 |
commit | cfce8f2cfba42edd3eb49e6b6484d60fb6aeeb43 (patch) | |
tree | f4b1129f70f829c0613d00756adb84a022a58088 /llvm/lib/Target | |
parent | b8cb73dd38664b6e4ff6bbb0a4143c6e209038f0 (diff) | |
download | bcm5719-llvm-cfce8f2cfba42edd3eb49e6b6484d60fb6aeeb43.tar.gz bcm5719-llvm-cfce8f2cfba42edd3eb49e6b6484d60fb6aeeb43.zip |
[X86] Add strict fp support for operations of X87 instructions
This is the following patch of D68854.
This patch adds basic operations of X87 instructions, including +, -, *, / , fp extensions and fp truncations.
Patch by Chen Liu(LiuChen3)
Differential Revision: https://reviews.llvm.org/D68857
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrFPStack.td | 34 |
3 files changed, 47 insertions, 19 deletions
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index d8f9c5f7270..709ad90c22d 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -5222,12 +5222,20 @@ void X86DAGToDAGISel::Select(SDNode *Node) { } case ISD::STRICT_FADD: case ISD::STRICT_FSUB: + case ISD::STRICT_FP_ROUND: { + // X87 instructions has enabled these strict fp operation. + bool UsingFp80 = Node->getSimpleValueType(0) == MVT::f80 || + Node->getOperand(1).getSimpleValueType() == MVT::f80; + if (UsingFp80 || (!Subtarget->hasSSE1() && Subtarget->hasX87())) + break; + LLVM_FALLTHROUGH; + } case ISD::STRICT_FP_TO_SINT: case ISD::STRICT_FP_TO_UINT: - case ISD::STRICT_FP_ROUND: // FIXME: Remove when we have isel patterns for strict versions of these // nodes. - CurDAG->mutateStrictFPToFP(Node); + if (!TLI->isStrictFPEnabled()) + CurDAG->mutateStrictFPToFP(Node); break; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 32072df268d..535493a8322 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -587,6 +587,15 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FSIN , VT, Expand); setOperationAction(ISD::FCOS , VT, Expand); setOperationAction(ISD::FSINCOS, VT, Expand); + + // Handle constrained floating-point operations of scalar. + setOperationAction(ISD::STRICT_FMUL , VT, Legal); + setOperationAction(ISD::STRICT_FDIV , VT, Legal); + setOperationAction(ISD::STRICT_FSQRT , VT, Legal); + setOperationAction(ISD::STRICT_FP_EXTEND, VT, Legal); + // FIXME: When the target is 64-bit, STRICT_FP_ROUND will be overwritten + // as Custom. + setOperationAction(ISD::STRICT_FP_ROUND, VT, Legal); } } @@ -657,6 +666,17 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::LLROUND, MVT::f80, Expand); setOperationAction(ISD::LRINT, MVT::f80, Expand); setOperationAction(ISD::LLRINT, MVT::f80, Expand); + + // Handle constrained floating-point operations of scalar. + setOperationAction(ISD::STRICT_FADD , MVT::f80, Legal); + setOperationAction(ISD::STRICT_FSUB , MVT::f80, Legal); + setOperationAction(ISD::STRICT_FMUL , MVT::f80, Legal); + setOperationAction(ISD::STRICT_FDIV , MVT::f80, Legal); + setOperationAction(ISD::STRICT_FSQRT , MVT::f80, Legal); + setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f80, Legal); + // FIXME: When the target is 64-bit, STRICT_FP_ROUND will be overwritten + // as Custom. + setOperationAction(ISD::STRICT_FP_ROUND, MVT::f80, Legal); } // f128 uses xmm registers, but most operations require libcalls. diff --git a/llvm/lib/Target/X86/X86InstrFPStack.td b/llvm/lib/Target/X86/X86InstrFPStack.td index 1b7a2ccde51..d9cf5608313 100644 --- a/llvm/lib/Target/X86/X86InstrFPStack.td +++ b/llvm/lib/Target/X86/X86InstrFPStack.td @@ -286,26 +286,26 @@ let Uses = [FPCW], mayRaiseFPException = 1 in { // FPBinary_rr just defines pseudo-instructions, no need to set a scheduling // resources. let hasNoSchedulingInfo = 1 in { -defm ADD : FPBinary_rr<fadd>; -defm SUB : FPBinary_rr<fsub>; -defm MUL : FPBinary_rr<fmul>; -defm DIV : FPBinary_rr<fdiv>; +defm ADD : FPBinary_rr<any_fadd>; +defm SUB : FPBinary_rr<any_fsub>; +defm MUL : FPBinary_rr<any_fmul>; +defm DIV : FPBinary_rr<any_fdiv>; } // Sets the scheduling resources for the actual NAME#_F<size>m defintions. let SchedRW = [WriteFAddLd] in { -defm ADD : FPBinary<fadd, MRM0m, "add">; -defm SUB : FPBinary<fsub, MRM4m, "sub">; -defm SUBR: FPBinary<fsub ,MRM5m, "subr", 0>; +defm ADD : FPBinary<any_fadd, MRM0m, "add">; +defm SUB : FPBinary<any_fsub, MRM4m, "sub">; +defm SUBR: FPBinary<any_fsub ,MRM5m, "subr", 0>; } let SchedRW = [WriteFMulLd] in { -defm MUL : FPBinary<fmul, MRM1m, "mul">; +defm MUL : FPBinary<any_fmul, MRM1m, "mul">; } let SchedRW = [WriteFDivLd] in { -defm DIV : FPBinary<fdiv, MRM6m, "div">; -defm DIVR: FPBinary<fdiv, MRM7m, "divr", 0>; +defm DIV : FPBinary<any_fdiv, MRM6m, "div">; +defm DIVR: FPBinary<any_fdiv, MRM7m, "divr", 0>; } } // Uses = [FPCW], mayRaiseFPException = 1 @@ -366,7 +366,7 @@ defm ABS : FPUnary<fabs, MRM_E1, "fabs">; let Uses = [FPCW], mayRaiseFPException = 1 in { let SchedRW = [WriteFSqrt80] in -defm SQRT: FPUnary<fsqrt,MRM_FA, "fsqrt">; +defm SQRT: FPUnary<any_fsqrt,MRM_FA, "fsqrt">; let SchedRW = [WriteFCom] in { let hasSideEffects = 0 in { @@ -790,19 +790,19 @@ def : Pat<(X86fist64 RFP80:$src, addr:$op), (IST_Fp64m80 addr:$op, RFP80:$src)>; // FP extensions map onto simple pseudo-value conversions if they are to/from // the FP stack. -def : Pat<(f64 (fpextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP64)>, +def : Pat<(f64 (any_fpextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP64)>, Requires<[FPStackf32]>; -def : Pat<(f80 (fpextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP80)>, +def : Pat<(f80 (any_fpextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP80)>, Requires<[FPStackf32]>; -def : Pat<(f80 (fpextend RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP80)>, +def : Pat<(f80 (any_fpextend RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP80)>, Requires<[FPStackf64]>; // FP truncations map onto simple pseudo-value conversions if they are to/from // the FP stack. We have validated that only value-preserving truncations make // it through isel. -def : Pat<(f32 (fpround RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP32)>, +def : Pat<(f32 (any_fpround RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP32)>, Requires<[FPStackf32]>; -def : Pat<(f32 (fpround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP32)>, +def : Pat<(f32 (any_fpround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP32)>, Requires<[FPStackf32]>; -def : Pat<(f64 (fpround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP64)>, +def : Pat<(f64 (any_fpround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP64)>, Requires<[FPStackf64]>; |