Skip to content

Commit

Permalink
[X86][FPEnv] Promote some float strictfp operations to double on i686…
Browse files Browse the repository at this point in the history
…-pc-windows-msvc to match what we do for non-strict.

The float libcalls are inlined in MSVC's math header where they
just cast to double and use the double libcall. Do the same when
we emit libcalls.
  • Loading branch information
topperc committed Dec 27, 2019
1 parent e647ff0 commit 53ee806
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 38 deletions.
31 changes: 31 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Expand Up @@ -4487,6 +4487,21 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
Results.push_back(DAG.getNode(ISD::FP_ROUND, dl, OVT,
Tmp3, DAG.getIntPtrConstant(0, dl)));
break;
case ISD::STRICT_FREM:
case ISD::STRICT_FPOW:
Tmp1 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other},
{Node->getOperand(0), Node->getOperand(1)});
Tmp2 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other},
{Node->getOperand(0), Node->getOperand(2)});
Tmp3 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1.getValue(1),
Tmp2.getValue(1));
Tmp1 = DAG.getNode(Node->getOpcode(), dl, {NVT, MVT::Other},
{Tmp3, Tmp1, Tmp2});
Tmp1 = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {OVT, MVT::Other},
{Tmp1.getValue(1), Tmp1, DAG.getIntPtrConstant(0, dl)});
Results.push_back(Tmp1);
Results.push_back(Tmp1.getValue(1));
break;
case ISD::FMA:
Tmp1 = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(0));
Tmp2 = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(1));
Expand Down Expand Up @@ -4533,6 +4548,22 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
Results.push_back(DAG.getNode(ISD::FP_ROUND, dl, OVT,
Tmp2, DAG.getIntPtrConstant(0, dl)));
break;
case ISD::STRICT_FFLOOR:
case ISD::STRICT_FCEIL:
case ISD::STRICT_FSIN:
case ISD::STRICT_FCOS:
case ISD::STRICT_FLOG:
case ISD::STRICT_FLOG10:
case ISD::STRICT_FEXP:
Tmp1 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other},
{Node->getOperand(0), Node->getOperand(1)});
Tmp2 = DAG.getNode(Node->getOpcode(), dl, {NVT, MVT::Other},
{Tmp1.getValue(1), Tmp1});
Tmp3 = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {OVT, MVT::Other},
{Tmp2.getValue(1), Tmp2, DAG.getIntPtrConstant(0, dl)});
Results.push_back(Tmp3);
Results.push_back(Tmp3.getValue(1));
break;
case ISD::BUILD_VECTOR: {
MVT EltVT = OVT.getVectorElementType();
MVT NewEltVT = NVT.getVectorElementType();
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -1947,8 +1947,15 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
if (Subtarget.is32Bit() &&
(Subtarget.isTargetWindowsMSVC() || Subtarget.isTargetWindowsItanium()))
for (ISD::NodeType Op :
{ISD::FCEIL, ISD::FCOS, ISD::FEXP, ISD::FFLOOR, ISD::FREM, ISD::FLOG,
ISD::FLOG10, ISD::FPOW, ISD::FSIN})
{ISD::FCEIL, ISD::STRICT_FCEIL,
ISD::FCOS, ISD::STRICT_FCOS,
ISD::FEXP, ISD::STRICT_FEXP,
ISD::FFLOOR, ISD::STRICT_FFLOOR,
ISD::FREM, ISD::STRICT_FREM,
ISD::FLOG, ISD::STRICT_FLOG,
ISD::FLOG10, ISD::STRICT_FLOG10,
ISD::FPOW, ISD::STRICT_FPOW,
ISD::FSIN, ISD::STRICT_FSIN})
if (isOperationExpand(Op, MVT::f32))
setOperationAction(Op, MVT::f32, Promote);

Expand Down
92 changes: 56 additions & 36 deletions llvm/test/CodeGen/X86/fp-strict-libcalls-msvc32.ll
Expand Up @@ -4,11 +4,13 @@
define float @ceil(float %x) #0 {
; CHECK-LABEL: ceil:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _ceilf
; CHECK-NEXT: popl %eax
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _ceil
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.ceil.f32(float %x, metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -17,11 +19,13 @@ define float @ceil(float %x) #0 {
define float @cos(float %x) #0 {
; CHECK-LABEL: cos:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _cos
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _cosf
; CHECK-NEXT: popl %eax
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.cos.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -30,11 +34,13 @@ define float @cos(float %x) #0 {
define float @exp(float %x) #0 {
; CHECK-LABEL: exp:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _expf
; CHECK-NEXT: popl %eax
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _exp
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.exp.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -43,11 +49,13 @@ define float @exp(float %x) #0 {
define float @floor(float %x) #0 {
; CHECK-LABEL: floor:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _floor
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _floorf
; CHECK-NEXT: popl %eax
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.floor.f32(float %x, metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -56,13 +64,16 @@ define float @floor(float %x) #0 {
define float @frem(float %x, float %y) #0 {
; CHECK-LABEL: frem:
; CHECK: # %bb.0:
; CHECK-NEXT: subl $8, %esp
; CHECK-NEXT: subl $20, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fxch %st(1)
; CHECK-NEXT: fstpl {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _fmod
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _fmodf
; CHECK-NEXT: addl $8, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: addl $20, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.frem.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -71,11 +82,13 @@ define float @frem(float %x, float %y) #0 {
define float @log(float %x) #0 {
; CHECK-LABEL: log:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _log
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _logf
; CHECK-NEXT: popl %eax
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.log.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -84,11 +97,13 @@ define float @log(float %x) #0 {
define float @log10(float %x) #0 {
; CHECK-LABEL: log10:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _log10
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _log10f
; CHECK-NEXT: popl %eax
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.log10.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -97,13 +112,16 @@ define float @log10(float %x) #0 {
define float @pow(float %x, float %y) #0 {
; CHECK-LABEL: pow:
; CHECK: # %bb.0:
; CHECK-NEXT: subl $8, %esp
; CHECK-NEXT: subl $20, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fxch %st(1)
; CHECK-NEXT: fstpl {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _pow
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _powf
; CHECK-NEXT: addl $8, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: addl $20, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.pow.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand All @@ -112,11 +130,13 @@ define float @pow(float %x, float %y) #0 {
define float @sin(float %x) #0 {
; CHECK-LABEL: sin:
; CHECK: # %bb.0:
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstpl (%esp)
; CHECK-NEXT: calll _sin
; CHECK-NEXT: fstps {{[0-9]+}}(%esp)
; CHECK-NEXT: flds {{[0-9]+}}(%esp)
; CHECK-NEXT: fstps (%esp)
; CHECK-NEXT: calll _sinf
; CHECK-NEXT: popl %eax
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
%result = call float @llvm.experimental.constrained.sin.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
ret float %result
Expand Down

0 comments on commit 53ee806

Please sign in to comment.