[llvm] r322087 - [SelectionDAG] lower math intrinsics to finite version of libcalls when possible (PR35672)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 9 07:41:00 PST 2018
Author: spatel
Date: Tue Jan 9 07:41:00 2018
New Revision: 322087
URL: http://llvm.org/viewvc/llvm-project?rev=322087&view=rev
Log:
[SelectionDAG] lower math intrinsics to finite version of libcalls when possible (PR35672)
Ingredients in this patch:
1. Add HANDLE_LIBCALL defs for finite mathlib functions that correspond to LLVM intrinsics.
2. Plumbing to send TargetLibraryInfo down to SelectionDAGLegalize.
3. Relaxed math and library checking in SelectionDAGLegalize::ConvertNodeToLibcall() to choose finite libcalls.
There was a bug about determining the availability of the finite calls that should be fixed with:
rL322010
Not in this patch:
This doesn't resolve the question/bug of clang creating the intrinsic IR in the first place.
There's likely follow-up work needed to support the long double variants better.
There's room for improvement to reduce the code duplication.
Create finite calls that don't originate from a corresponding intrinsic or DAG node?
Differential Revision: https://reviews.llvm.org/D41338
Modified:
llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.def
llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/test/CodeGen/X86/finite-libcalls.ll
Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.def?rev=322087&r1=322086&r2=322087&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.def (original)
+++ llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.def Tue Jan 9 07:41:00 2018
@@ -130,26 +130,51 @@ HANDLE_LIBCALL(LOG_F64, "log")
HANDLE_LIBCALL(LOG_F80, "logl")
HANDLE_LIBCALL(LOG_F128, "logl")
HANDLE_LIBCALL(LOG_PPCF128, "logl")
+HANDLE_LIBCALL(LOG_FINITE_F32, "__logf_finite")
+HANDLE_LIBCALL(LOG_FINITE_F64, "__log_finite")
+HANDLE_LIBCALL(LOG_FINITE_F80, "__logl_finite")
+HANDLE_LIBCALL(LOG_FINITE_F128, "__logl_finite")
+HANDLE_LIBCALL(LOG_FINITE_PPCF128, "__logl_finite")
HANDLE_LIBCALL(LOG2_F32, "log2f")
HANDLE_LIBCALL(LOG2_F64, "log2")
HANDLE_LIBCALL(LOG2_F80, "log2l")
HANDLE_LIBCALL(LOG2_F128, "log2l")
HANDLE_LIBCALL(LOG2_PPCF128, "log2l")
+HANDLE_LIBCALL(LOG2_FINITE_F32, "__log2f_finite")
+HANDLE_LIBCALL(LOG2_FINITE_F64, "__log2_finite")
+HANDLE_LIBCALL(LOG2_FINITE_F80, "__log2l_finite")
+HANDLE_LIBCALL(LOG2_FINITE_F128, "__log2l_finite")
+HANDLE_LIBCALL(LOG2_FINITE_PPCF128, "__log2l_finite")
HANDLE_LIBCALL(LOG10_F32, "log10f")
HANDLE_LIBCALL(LOG10_F64, "log10")
HANDLE_LIBCALL(LOG10_F80, "log10l")
HANDLE_LIBCALL(LOG10_F128, "log10l")
HANDLE_LIBCALL(LOG10_PPCF128, "log10l")
+HANDLE_LIBCALL(LOG10_FINITE_F32, "__log10f_finite")
+HANDLE_LIBCALL(LOG10_FINITE_F64, "__log10_finite")
+HANDLE_LIBCALL(LOG10_FINITE_F80, "__log10l_finite")
+HANDLE_LIBCALL(LOG10_FINITE_F128, "__log10l_finite")
+HANDLE_LIBCALL(LOG10_FINITE_PPCF128, "__log10l_finite")
HANDLE_LIBCALL(EXP_F32, "expf")
HANDLE_LIBCALL(EXP_F64, "exp")
HANDLE_LIBCALL(EXP_F80, "expl")
HANDLE_LIBCALL(EXP_F128, "expl")
HANDLE_LIBCALL(EXP_PPCF128, "expl")
+HANDLE_LIBCALL(EXP_FINITE_F32, "__expf_finite")
+HANDLE_LIBCALL(EXP_FINITE_F64, "__exp_finite")
+HANDLE_LIBCALL(EXP_FINITE_F80, "__expl_finite")
+HANDLE_LIBCALL(EXP_FINITE_F128, "__expl_finite")
+HANDLE_LIBCALL(EXP_FINITE_PPCF128, "__expl_finite")
HANDLE_LIBCALL(EXP2_F32, "exp2f")
HANDLE_LIBCALL(EXP2_F64, "exp2")
HANDLE_LIBCALL(EXP2_F80, "exp2l")
HANDLE_LIBCALL(EXP2_F128, "exp2l")
HANDLE_LIBCALL(EXP2_PPCF128, "exp2l")
+HANDLE_LIBCALL(EXP2_FINITE_F32, "__exp2f_finite")
+HANDLE_LIBCALL(EXP2_FINITE_F64, "__exp2_finite")
+HANDLE_LIBCALL(EXP2_FINITE_F80, "__exp2l_finite")
+HANDLE_LIBCALL(EXP2_FINITE_F128, "__exp2l_finite")
+HANDLE_LIBCALL(EXP2_FINITE_PPCF128, "__exp2l_finite")
HANDLE_LIBCALL(SIN_F32, "sinf")
HANDLE_LIBCALL(SIN_F64, "sin")
HANDLE_LIBCALL(SIN_F80, "sinl")
@@ -172,6 +197,11 @@ HANDLE_LIBCALL(POW_F64, "pow")
HANDLE_LIBCALL(POW_F80, "powl")
HANDLE_LIBCALL(POW_F128, "powl")
HANDLE_LIBCALL(POW_PPCF128, "powl")
+HANDLE_LIBCALL(POW_FINITE_F32, "__powf_finite")
+HANDLE_LIBCALL(POW_FINITE_F64, "__pow_finite")
+HANDLE_LIBCALL(POW_FINITE_F80, "__powl_finite")
+HANDLE_LIBCALL(POW_FINITE_F128, "__powl_finite")
+HANDLE_LIBCALL(POW_FINITE_PPCF128, "__powl_finite")
HANDLE_LIBCALL(CEIL_F32, "ceilf")
HANDLE_LIBCALL(CEIL_F64, "ceil")
HANDLE_LIBCALL(CEIL_F80, "ceill")
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=322087&r1=322086&r2=322087&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Jan 9 07:41:00 2018
@@ -73,6 +73,7 @@ class OptimizationRemarkEmitter;
class SDDbgValue;
class SelectionDAG;
class SelectionDAGTargetInfo;
+class TargetLibraryInfo;
class TargetLowering;
class TargetMachine;
class TargetSubtargetInfo;
@@ -210,6 +211,7 @@ class SelectionDAG {
const TargetMachine &TM;
const SelectionDAGTargetInfo *TSI = nullptr;
const TargetLowering *TLI = nullptr;
+ const TargetLibraryInfo *LibInfo = nullptr;
MachineFunction *MF;
Pass *SDAGISelPass = nullptr;
LLVMContext *Context;
@@ -376,7 +378,7 @@ public:
/// Prepare this SelectionDAG to process code in the given MachineFunction.
void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE,
- Pass *PassPtr);
+ Pass *PassPtr, const TargetLibraryInfo *LibraryInfo);
/// Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
@@ -389,6 +391,7 @@ public:
const TargetMachine &getTarget() const { return TM; }
const TargetSubtargetInfo &getSubtarget() const { return MF->getSubtarget(); }
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
+ const TargetLibraryInfo &getLibInfo() const { return *LibInfo; }
const SelectionDAGTargetInfo &getSelectionDAGInfo() const { return *TSI; }
LLVMContext *getContext() const {return Context; }
OptimizationRemarkEmitter &getORE() const { return *ORE; }
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=322087&r1=322086&r2=322087&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 9 07:41:00 2018
@@ -3932,6 +3932,8 @@ void SelectionDAGLegalize::ConvertNodeTo
DEBUG(dbgs() << "Trying to convert node to libcall\n");
SmallVector<SDValue, 8> Results;
SDLoc dl(Node);
+ // FIXME: Check flags on the node to see if we can use a finite call.
+ bool CanUseFiniteLibCall = TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath;
unsigned Opc = Node->getOpcode();
switch (Opc) {
case ISD::ATOMIC_FENCE: {
@@ -4026,33 +4028,68 @@ void SelectionDAGLegalize::ConvertNodeTo
break;
case ISD::FLOG:
case ISD::STRICT_FLOG:
- Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64,
- RTLIB::LOG_F80, RTLIB::LOG_F128,
- RTLIB::LOG_PPCF128));
+ if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_log_finite))
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_FINITE_F32,
+ RTLIB::LOG_FINITE_F64,
+ RTLIB::LOG_FINITE_F80,
+ RTLIB::LOG_FINITE_F128,
+ RTLIB::LOG_FINITE_PPCF128));
+ else
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64,
+ RTLIB::LOG_F80, RTLIB::LOG_F128,
+ RTLIB::LOG_PPCF128));
break;
case ISD::FLOG2:
case ISD::STRICT_FLOG2:
- Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64,
- RTLIB::LOG2_F80, RTLIB::LOG2_F128,
- RTLIB::LOG2_PPCF128));
+ if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_log2_finite))
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_FINITE_F32,
+ RTLIB::LOG2_FINITE_F64,
+ RTLIB::LOG2_FINITE_F80,
+ RTLIB::LOG2_FINITE_F128,
+ RTLIB::LOG2_FINITE_PPCF128));
+ else
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64,
+ RTLIB::LOG2_F80, RTLIB::LOG2_F128,
+ RTLIB::LOG2_PPCF128));
break;
case ISD::FLOG10:
case ISD::STRICT_FLOG10:
- Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64,
- RTLIB::LOG10_F80, RTLIB::LOG10_F128,
- RTLIB::LOG10_PPCF128));
+ if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_log10_finite))
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_FINITE_F32,
+ RTLIB::LOG10_FINITE_F64,
+ RTLIB::LOG10_FINITE_F80,
+ RTLIB::LOG10_FINITE_F128,
+ RTLIB::LOG10_FINITE_PPCF128));
+ else
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64,
+ RTLIB::LOG10_F80, RTLIB::LOG10_F128,
+ RTLIB::LOG10_PPCF128));
break;
case ISD::FEXP:
case ISD::STRICT_FEXP:
- Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64,
- RTLIB::EXP_F80, RTLIB::EXP_F128,
- RTLIB::EXP_PPCF128));
+ if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_exp_finite))
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_FINITE_F32,
+ RTLIB::EXP_FINITE_F64,
+ RTLIB::EXP_FINITE_F80,
+ RTLIB::EXP_FINITE_F128,
+ RTLIB::EXP_FINITE_PPCF128));
+ else
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64,
+ RTLIB::EXP_F80, RTLIB::EXP_F128,
+ RTLIB::EXP_PPCF128));
break;
case ISD::FEXP2:
case ISD::STRICT_FEXP2:
- Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64,
- RTLIB::EXP2_F80, RTLIB::EXP2_F128,
- RTLIB::EXP2_PPCF128));
+ if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_exp2_finite))
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_FINITE_F32,
+ RTLIB::EXP2_FINITE_F64,
+ RTLIB::EXP2_FINITE_F80,
+ RTLIB::EXP2_FINITE_F128,
+ RTLIB::EXP2_FINITE_PPCF128));
+ else
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64,
+ RTLIB::EXP2_F80, RTLIB::EXP2_F128,
+ RTLIB::EXP2_PPCF128));
break;
case ISD::FTRUNC:
Results.push_back(ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
@@ -4098,9 +4135,16 @@ void SelectionDAGLegalize::ConvertNodeTo
break;
case ISD::FPOW:
case ISD::STRICT_FPOW:
- Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64,
- RTLIB::POW_F80, RTLIB::POW_F128,
- RTLIB::POW_PPCF128));
+ if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_pow_finite))
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_FINITE_F32,
+ RTLIB::POW_FINITE_F64,
+ RTLIB::POW_FINITE_F80,
+ RTLIB::POW_FINITE_F128,
+ RTLIB::POW_FINITE_PPCF128));
+ else
+ Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64,
+ RTLIB::POW_F80, RTLIB::POW_F128,
+ RTLIB::POW_PPCF128));
break;
case ISD::FDIV:
Results.push_back(ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64,
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=322087&r1=322086&r2=322087&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Jan 9 07:41:00 2018
@@ -903,12 +903,13 @@ SelectionDAG::SelectionDAG(const TargetM
void SelectionDAG::init(MachineFunction &NewMF,
OptimizationRemarkEmitter &NewORE,
- Pass *PassPtr) {
+ Pass *PassPtr, const TargetLibraryInfo *LibraryInfo) {
MF = &NewMF;
SDAGISelPass = PassPtr;
ORE = &NewORE;
TLI = getSubtarget().getTargetLowering();
TSI = getSubtarget().getSelectionDAGInfo();
+ LibInfo = LibraryInfo;
Context = &MF->getFunction().getContext();
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=322087&r1=322086&r2=322087&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jan 9 07:41:00 2018
@@ -414,7 +414,7 @@ bool SelectionDAGISel::runOnMachineFunct
SplitCriticalSideEffectEdges(const_cast<Function &>(Fn), DT, LI);
- CurDAG->init(*MF, *ORE, this);
+ CurDAG->init(*MF, *ORE, this, LibInfo);
FuncInfo->set(Fn, *MF, CurDAG);
// Now get the optional analyzes if we want to.
Modified: llvm/trunk/test/CodeGen/X86/finite-libcalls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/finite-libcalls.ll?rev=322087&r1=322086&r2=322087&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/finite-libcalls.ll (original)
+++ llvm/trunk/test/CodeGen/X86/finite-libcalls.ll Tue Jan 9 07:41:00 2018
@@ -1,24 +1,41 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=GNU
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefix=CHECK --check-prefix=WIN
+; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s --check-prefix=CHECK --check-prefix=MAC
; PR35672 - https://bugs.llvm.org/show_bug.cgi?id=35672
; FIXME: We would not need the function-level attributes if FMF were propagated to DAG nodes for this case.
define float @exp_f32(float %x) #0 {
-; CHECK-LABEL: exp_f32:
-; CHECK: # %bb.0:
-; CHECK-NEXT: jmp expf # TAILCALL
- %exp = tail call nnan ninf float @llvm.exp.f32(float %x)
- ret float %exp
+; GNU-LABEL: exp_f32:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __expf_finite # TAILCALL
+;
+; WIN-LABEL: exp_f32:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp expf # TAILCALL
+;
+; MAC-LABEL: exp_f32:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _expf ## TAILCALL
+ %r = tail call nnan ninf float @llvm.exp.f32(float %x)
+ ret float %r
}
define double @exp_f64(double %x) #0 {
-; CHECK-LABEL: exp_f64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: jmp exp # TAILCALL
- %exp = tail call nnan ninf double @llvm.exp.f64(double %x)
- ret double %exp
+; GNU-LABEL: exp_f64:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __exp_finite # TAILCALL
+;
+; WIN-LABEL: exp_f64:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp exp # TAILCALL
+;
+; MAC-LABEL: exp_f64:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _exp ## TAILCALL
+ %r = tail call nnan ninf double @llvm.exp.f64(double %x)
+ ret double %r
}
define x86_fp80 @exp_f80(x86_fp80 %x) #0 {
@@ -27,7 +44,7 @@ define x86_fp80 @exp_f80(x86_fp80 %x) #0
; GNU-NEXT: subq $24, %rsp
; GNU-NEXT: fldt {{[0-9]+}}(%rsp)
; GNU-NEXT: fstpt (%rsp)
-; GNU-NEXT: callq expl
+; GNU-NEXT: callq __expl_finite
; GNU-NEXT: addq $24, %rsp
; GNU-NEXT: retq
;
@@ -39,14 +56,370 @@ define x86_fp80 @exp_f80(x86_fp80 %x) #0
; WIN-NEXT: callq expl
; WIN-NEXT: addq $56, %rsp
; WIN-NEXT: retq
- %exp = tail call nnan ninf x86_fp80 @llvm.exp.f80(x86_fp80 %x)
- ret x86_fp80 %exp
+;
+; MAC-LABEL: exp_f80:
+; MAC: ## %bb.0:
+; MAC-NEXT: subq $24, %rsp
+; MAC-NEXT: fldt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fstpt (%rsp)
+; MAC-NEXT: callq _expl
+; MAC-NEXT: addq $24, %rsp
+; MAC-NEXT: retq
+ %r = tail call nnan ninf x86_fp80 @llvm.exp.f80(x86_fp80 %x)
+ ret x86_fp80 %r
+}
+
+define float @exp2_f32(float %x) #0 {
+; GNU-LABEL: exp2_f32:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __exp2f_finite # TAILCALL
+;
+; WIN-LABEL: exp2_f32:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp exp2f # TAILCALL
+;
+; MAC-LABEL: exp2_f32:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _exp2f ## TAILCALL
+ %r = tail call nnan ninf float @llvm.exp2.f32(float %x)
+ ret float %r
+}
+
+define double @exp2_f64(double %x) #0 {
+; GNU-LABEL: exp2_f64:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __exp2_finite # TAILCALL
+;
+; WIN-LABEL: exp2_f64:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp exp2 # TAILCALL
+;
+; MAC-LABEL: exp2_f64:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _exp2 ## TAILCALL
+ %r = tail call nnan ninf double @llvm.exp2.f64(double %x)
+ ret double %r
+}
+
+define x86_fp80 @exp2_f80(x86_fp80 %x) #0 {
+; GNU-LABEL: exp2_f80:
+; GNU: # %bb.0:
+; GNU-NEXT: subq $24, %rsp
+; GNU-NEXT: fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT: fstpt (%rsp)
+; GNU-NEXT: callq __exp2l_finite
+; GNU-NEXT: addq $24, %rsp
+; GNU-NEXT: retq
+;
+; WIN-LABEL: exp2_f80:
+; WIN: # %bb.0:
+; WIN-NEXT: subq $56, %rsp
+; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
+; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
+; WIN-NEXT: callq exp2l
+; WIN-NEXT: addq $56, %rsp
+; WIN-NEXT: retq
+;
+; MAC-LABEL: exp2_f80:
+; MAC: ## %bb.0:
+; MAC-NEXT: subq $24, %rsp
+; MAC-NEXT: fldt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fstpt (%rsp)
+; MAC-NEXT: callq _exp2l
+; MAC-NEXT: addq $24, %rsp
+; MAC-NEXT: retq
+ %r = tail call nnan ninf x86_fp80 @llvm.exp2.f80(x86_fp80 %x)
+ ret x86_fp80 %r
+}
+
+define float @log_f32(float %x) #0 {
+; GNU-LABEL: log_f32:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __logf_finite # TAILCALL
+;
+; WIN-LABEL: log_f32:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp logf # TAILCALL
+;
+; MAC-LABEL: log_f32:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _logf ## TAILCALL
+ %r = tail call nnan ninf float @llvm.log.f32(float %x)
+ ret float %r
+}
+
+define double @log_f64(double %x) #0 {
+; GNU-LABEL: log_f64:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __log_finite # TAILCALL
+;
+; WIN-LABEL: log_f64:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp log # TAILCALL
+;
+; MAC-LABEL: log_f64:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _log ## TAILCALL
+ %r = tail call nnan ninf double @llvm.log.f64(double %x)
+ ret double %r
+}
+
+define x86_fp80 @log_f80(x86_fp80 %x) #0 {
+; GNU-LABEL: log_f80:
+; GNU: # %bb.0:
+; GNU-NEXT: subq $24, %rsp
+; GNU-NEXT: fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT: fstpt (%rsp)
+; GNU-NEXT: callq __logl_finite
+; GNU-NEXT: addq $24, %rsp
+; GNU-NEXT: retq
+;
+; WIN-LABEL: log_f80:
+; WIN: # %bb.0:
+; WIN-NEXT: subq $56, %rsp
+; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
+; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
+; WIN-NEXT: callq logl
+; WIN-NEXT: addq $56, %rsp
+; WIN-NEXT: retq
+;
+; MAC-LABEL: log_f80:
+; MAC: ## %bb.0:
+; MAC-NEXT: subq $24, %rsp
+; MAC-NEXT: fldt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fstpt (%rsp)
+; MAC-NEXT: callq _logl
+; MAC-NEXT: addq $24, %rsp
+; MAC-NEXT: retq
+ %r = tail call nnan ninf x86_fp80 @llvm.log.f80(x86_fp80 %x)
+ ret x86_fp80 %r
+}
+
+define float @log2_f32(float %x) #0 {
+; GNU-LABEL: log2_f32:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __log2f_finite # TAILCALL
+;
+; WIN-LABEL: log2_f32:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp log2f # TAILCALL
+;
+; MAC-LABEL: log2_f32:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _log2f ## TAILCALL
+ %r = tail call nnan ninf float @llvm.log2.f32(float %x)
+ ret float %r
+}
+
+define double @log2_f64(double %x) #0 {
+; GNU-LABEL: log2_f64:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __log2_finite # TAILCALL
+;
+; WIN-LABEL: log2_f64:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp log2 # TAILCALL
+;
+; MAC-LABEL: log2_f64:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _log2 ## TAILCALL
+ %r = tail call nnan ninf double @llvm.log2.f64(double %x)
+ ret double %r
+}
+
+define x86_fp80 @log2_f80(x86_fp80 %x) #0 {
+; GNU-LABEL: log2_f80:
+; GNU: # %bb.0:
+; GNU-NEXT: subq $24, %rsp
+; GNU-NEXT: fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT: fstpt (%rsp)
+; GNU-NEXT: callq __log2l_finite
+; GNU-NEXT: addq $24, %rsp
+; GNU-NEXT: retq
+;
+; WIN-LABEL: log2_f80:
+; WIN: # %bb.0:
+; WIN-NEXT: subq $56, %rsp
+; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
+; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
+; WIN-NEXT: callq log2l
+; WIN-NEXT: addq $56, %rsp
+; WIN-NEXT: retq
+;
+; MAC-LABEL: log2_f80:
+; MAC: ## %bb.0:
+; MAC-NEXT: subq $24, %rsp
+; MAC-NEXT: fldt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fstpt (%rsp)
+; MAC-NEXT: callq _log2l
+; MAC-NEXT: addq $24, %rsp
+; MAC-NEXT: retq
+ %r = tail call nnan ninf x86_fp80 @llvm.log2.f80(x86_fp80 %x)
+ ret x86_fp80 %r
+}
+
+define float @log10_f32(float %x) #0 {
+; GNU-LABEL: log10_f32:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __log10f_finite # TAILCALL
+;
+; WIN-LABEL: log10_f32:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp log10f # TAILCALL
+;
+; MAC-LABEL: log10_f32:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _log10f ## TAILCALL
+ %r = tail call nnan ninf float @llvm.log10.f32(float %x)
+ ret float %r
+}
+
+define double @log10_f64(double %x) #0 {
+; GNU-LABEL: log10_f64:
+; GNU: # %bb.0:
+; GNU-NEXT: jmp __log10_finite # TAILCALL
+;
+; WIN-LABEL: log10_f64:
+; WIN: # %bb.0:
+; WIN-NEXT: jmp log10 # TAILCALL
+;
+; MAC-LABEL: log10_f64:
+; MAC: ## %bb.0:
+; MAC-NEXT: jmp _log10 ## TAILCALL
+ %r = tail call nnan ninf double @llvm.log10.f64(double %x)
+ ret double %r
+}
+
+define x86_fp80 @log10_f80(x86_fp80 %x) #0 {
+; GNU-LABEL: log10_f80:
+; GNU: # %bb.0:
+; GNU-NEXT: subq $24, %rsp
+; GNU-NEXT: fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT: fstpt (%rsp)
+; GNU-NEXT: callq __log10l_finite
+; GNU-NEXT: addq $24, %rsp
+; GNU-NEXT: retq
+;
+; WIN-LABEL: log10_f80:
+; WIN: # %bb.0:
+; WIN-NEXT: subq $56, %rsp
+; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
+; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
+; WIN-NEXT: callq log10l
+; WIN-NEXT: addq $56, %rsp
+; WIN-NEXT: retq
+;
+; MAC-LABEL: log10_f80:
+; MAC: ## %bb.0:
+; MAC-NEXT: subq $24, %rsp
+; MAC-NEXT: fldt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fstpt (%rsp)
+; MAC-NEXT: callq _log10l
+; MAC-NEXT: addq $24, %rsp
+; MAC-NEXT: retq
+ %r = tail call nnan ninf x86_fp80 @llvm.log10.f80(x86_fp80 %x)
+ ret x86_fp80 %r
+}
+
+define float @pow_f32(float %x) #0 {
+; GNU-LABEL: pow_f32:
+; GNU: # %bb.0:
+; GNU-NEXT: movaps %xmm0, %xmm1
+; GNU-NEXT: jmp __powf_finite # TAILCALL
+;
+; WIN-LABEL: pow_f32:
+; WIN: # %bb.0:
+; WIN-NEXT: movaps %xmm0, %xmm1
+; WIN-NEXT: jmp powf # TAILCALL
+;
+; MAC-LABEL: pow_f32:
+; MAC: ## %bb.0:
+; MAC-NEXT: movaps %xmm0, %xmm1
+; MAC-NEXT: jmp _powf ## TAILCALL
+ %r = tail call nnan ninf float @llvm.pow.f32(float %x, float %x)
+ ret float %r
+}
+
+define double @pow_f64(double %x) #0 {
+; GNU-LABEL: pow_f64:
+; GNU: # %bb.0:
+; GNU-NEXT: movaps %xmm0, %xmm1
+; GNU-NEXT: jmp __pow_finite # TAILCALL
+;
+; WIN-LABEL: pow_f64:
+; WIN: # %bb.0:
+; WIN-NEXT: movaps %xmm0, %xmm1
+; WIN-NEXT: jmp pow # TAILCALL
+;
+; MAC-LABEL: pow_f64:
+; MAC: ## %bb.0:
+; MAC-NEXT: movaps %xmm0, %xmm1
+; MAC-NEXT: jmp _pow ## TAILCALL
+ %r = tail call nnan ninf double @llvm.pow.f64(double %x, double %x)
+ ret double %r
+}
+
+define x86_fp80 @pow_f80(x86_fp80 %x) #0 {
+; GNU-LABEL: pow_f80:
+; GNU: # %bb.0:
+; GNU-NEXT: subq $40, %rsp
+; GNU-NEXT: fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT: fld %st(0)
+; GNU-NEXT: fstpt {{[0-9]+}}(%rsp)
+; GNU-NEXT: fstpt (%rsp)
+; GNU-NEXT: callq __powl_finite
+; GNU-NEXT: addq $40, %rsp
+; GNU-NEXT: retq
+;
+; WIN-LABEL: pow_f80:
+; WIN: # %bb.0:
+; WIN-NEXT: subq $72, %rsp
+; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
+; WIN-NEXT: fld %st(0)
+; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
+; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
+; WIN-NEXT: callq powl
+; WIN-NEXT: addq $72, %rsp
+; WIN-NEXT: retq
+;
+; MAC-LABEL: pow_f80:
+; MAC: ## %bb.0:
+; MAC-NEXT: subq $40, %rsp
+; MAC-NEXT: fldt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fld %st(0)
+; MAC-NEXT: fstpt {{[0-9]+}}(%rsp)
+; MAC-NEXT: fstpt (%rsp)
+; MAC-NEXT: callq _powl
+; MAC-NEXT: addq $40, %rsp
+; MAC-NEXT: retq
+ %r = tail call nnan ninf x86_fp80 @llvm.pow.f80(x86_fp80 %x, x86_fp80 %x)
+ ret x86_fp80 %r
}
declare float @llvm.exp.f32(float) #1
declare double @llvm.exp.f64(double) #1
declare x86_fp80 @llvm.exp.f80(x86_fp80) #1
+declare float @llvm.exp2.f32(float) #1
+declare double @llvm.exp2.f64(double) #1
+declare x86_fp80 @llvm.exp2.f80(x86_fp80) #1
+
+declare float @llvm.log.f32(float) #1
+declare double @llvm.log.f64(double) #1
+declare x86_fp80 @llvm.log.f80(x86_fp80) #1
+
+declare float @llvm.log2.f32(float) #1
+declare double @llvm.log2.f64(double) #1
+declare x86_fp80 @llvm.log2.f80(x86_fp80) #1
+
+declare float @llvm.log10.f32(float) #1
+declare double @llvm.log10.f64(double) #1
+declare x86_fp80 @llvm.log10.f80(x86_fp80) #1
+
+declare float @llvm.pow.f32(float, float) #1
+declare double @llvm.pow.f64(double, double) #1
+declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) #1
+
attributes #0 = { nounwind "no-infs-fp-math"="true" "no-nans-fp-math"="true" }
attributes #1 = { nounwind readnone speculatable }
More information about the llvm-commits
mailing list