; RUN: opt -O2 -S -mtriple=i386-pc-win32 < %s | FileCheck %s -check-prefix=WIN32 ; RUN: opt -O2 -S -mtriple=x86_64-pc-win32 < %s | FileCheck %s -check-prefix=WIN64 ; RUN: opt -O2 -S -mtriple=i386-pc-mingw32 < %s | FileCheck %s -check-prefix=MINGW32 ; RUN: opt -O2 -S -mtriple=x86_64-pc-mingw32 < %s | FileCheck %s -check-prefix=MINGW64 ; x86 win32 msvcrt does not provide entry points for single-precision libm. ; x86-64 win32 msvcrt does (except for fabsf) ; msvcrt does not provide C99 math, but mingw32 does. declare double @acos(double %x) define float @float_acos(float %x) nounwind readnone { ; WIN32-LABEL: @float_acos( ; WIN32-NOT: float @acosf ; WIN32: double @acos %1 = fpext float %x to double %2 = call double @acos(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @asin(double %x) define float @float_asin(float %x) nounwind readnone { ; WIN32-LABEL: @float_asin( ; WIN32-NOT: float @asinf ; WIN32: double @asin %1 = fpext float %x to double %2 = call double @asin(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @atan(double %x) define float @float_atan(float %x) nounwind readnone { ; WIN32-LABEL: @float_atan( ; WIN32-NOT: float @atanf ; WIN32: double @atan %1 = fpext float %x to double %2 = call double @atan(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @atan2(double %x, double %y) define float @float_atan2(float %x, float %y) nounwind readnone { ; WIN32-LABEL: @float_atan2( ; WIN32-NOT: float @atan2f ; WIN32: double @atan2 %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @atan2(double %1, double %2) %4 = fptrunc double %3 to float ret float %4 } declare double @ceil(double %x) define float @float_ceil(float %x) nounwind readnone { ; WIN32-LABEL: @float_ceil( ; WIN32-NOT: float @ceilf ; WIN32: float @llvm.ceil.f32 ; WIN64-LABEL: @float_ceil( ; WIN64: float @llvm.ceil.f32 ; WIN64-NOT: double @ceil ; MINGW32-LABEL: @float_ceil( ; MINGW32: float @llvm.ceil.f32 ; MINGW32-NOT: double @ceil ; MINGW64-LABEL: @float_ceil( ; MINGW64: float @llvm.ceil.f32 ; MINGW64-NOT: double @ceil %1 = fpext float %x to double %2 = call double @ceil(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @_copysign(double %x) define float @float_copysign(float %x) nounwind readnone { ; WIN32-LABEL: @float_copysign( ; WIN32-NOT: float @copysignf ; WIN32-NOT: float @_copysignf ; WIN32: double @_copysign %1 = fpext float %x to double %2 = call double @_copysign(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @cos(double %x) define float @float_cos(float %x) nounwind readnone { ; WIN32-LABEL: @float_cos( ; WIN32-NOT: float @cosf ; WIN32: double @cos %1 = fpext float %x to double %2 = call double @cos(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @cosh(double %x) define float @float_cosh(float %x) nounwind readnone { ; WIN32-LABEL: @float_cosh( ; WIN32-NOT: float @coshf ; WIN32: double @cosh %1 = fpext float %x to double %2 = call double @cosh(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @exp(double %x, double %y) define float @float_exp(float %x, float %y) nounwind readnone { ; WIN32-LABEL: @float_exp( ; WIN32-NOT: float @expf ; WIN32: double @exp %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @exp(double %1, double %2) %4 = fptrunc double %3 to float ret float %4 } declare double @fabs(double %x, double %y) define float @float_fabs(float %x, float %y) nounwind readnone { ; WIN32-LABEL: @float_fabs( ; WIN32-NOT: float @fabsf ; WIN32: double @fabs ; WIN64-LABEL: @float_fabs( ; WIN64-NOT: float @fabsf ; WIN64: double @fabs %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @fabs(double %1, double %2) %4 = fptrunc double %3 to float ret float %4 } declare double @floor(double %x) define float @float_floor(float %x) nounwind readnone { ; WIN32-LABEL: @float_floor( ; WIN32-NOT: float @floorf ; WIN32: float @llvm.floor.f32 ; WIN64-LABEL: @float_floor( ; WIN64: float @llvm.floor.f32 ; WIN64-NOT: double @floor ; MINGW32-LABEL: @float_floor( ; MINGW32: float @llvm.floor.f32 ; MINGW32-NOT: double @floor ; MINGW64-LABEL: @float_floor( ; MINGW64: float @llvm.floor.f32 ; MINGW64-NOT: double @floor %1 = fpext float %x to double %2 = call double @floor(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @fmod(double %x, double %y) define float @float_fmod(float %x, float %y) nounwind readnone { ; WIN32-LABEL: @float_fmod( ; WIN32-NOT: float @fmodf ; WIN32: double @fmod %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @fmod(double %1, double %2) %4 = fptrunc double %3 to float ret float %4 } declare double @log(double %x) define float @float_log(float %x) nounwind readnone { ; WIN32-LABEL: @float_log( ; WIN32-NOT: float @logf ; WIN32: double @log %1 = fpext float %x to double %2 = call double @log(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @pow(double %x, double %y) define float @float_pow(float %x, float %y) nounwind readnone { ; WIN32-LABEL: @float_pow( ; WIN32-NOT: float @powf ; WIN32: double @pow %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @pow(double %1, double %2) %4 = fptrunc double %3 to float ret float %4 } declare double @sin(double %x) define float @float_sin(float %x) nounwind readnone { ; WIN32-LABEL: @float_sin( ; WIN32-NOT: float @sinf ; WIN32: double @sin %1 = fpext float %x to double %2 = call double @sin(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @sinh(double %x) define float @float_sinh(float %x) nounwind readnone { ; WIN32-LABEL: @float_sinh( ; WIN32-NOT: float @sinhf ; WIN32: double @sinh %1 = fpext float %x to double %2 = call double @sinh(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @sqrt(double %x) define float @float_sqrt(float %x) nounwind readnone { ; WIN32-LABEL: @float_sqrt( ; WIN32-NOT: float @sqrtf ; WIN32: double @sqrt ; WIN64-LABEL: @float_sqrt( ; WIN64: float @sqrtf ; WIN64-NOT: double @sqrt ; MINGW32-LABEL: @float_sqrt( ; MINGW32: float @sqrtf ; MINGW32-NOT: double @sqrt ; MINGW64-LABEL: @float_sqrt( ; MINGW64: float @sqrtf ; MINGW64-NOT: double @sqrt %1 = fpext float %x to double %2 = call double @sqrt(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @tan(double %x) define float @float_tan(float %x) nounwind readnone { ; WIN32-LABEL: @float_tan( ; WIN32-NOT: float @tanf ; WIN32: double @tan %1 = fpext float %x to double %2 = call double @tan(double %1) %3 = fptrunc double %2 to float ret float %3 } declare double @tanh(double %x) define float @float_tanh(float %x) nounwind readnone { ; WIN32-LABEL: @float_tanh( ; WIN32-NOT: float @tanhf ; WIN32: double @tanh %1 = fpext float %x to double %2 = call double @tanh(double %1) %3 = fptrunc double %2 to float ret float %3 } ; win32 does not have round; mingw32 does declare double @round(double %x) define float @float_round(float %x) nounwind readnone { ; WIN32-LABEL: @float_round( ; WIN32-NOT: float @roundf ; WIN32: double @round ; WIN64-LABEL: @float_round( ; WIN64-NOT: float @roundf ; WIN64: double @round ; MINGW32-LABEL: @float_round( ; MINGW32: float @llvm.round.f32 ; MINGW32-NOT: double @round ; MINGW64-LABEL: @float_round( ; MINGW64: float @llvm.round.f32 ; MINGW64-NOT: double @round %1 = fpext float %x to double %2 = call double @round(double %1) %3 = fptrunc double %2 to float ret float %3 } declare float @powf(float, float) ; win32 lacks sqrtf&fabsf, win64 lacks fabsf, but ; calls to the intrinsics can be emitted instead. define float @float_powsqrt(float %x) nounwind readnone { ; WIN32-LABEL: @float_powsqrt( ; WIN32-NOT: float @sqrtf ; WIN32: float @powf ; WIN64-LABEL: @float_powsqrt( ; WIN64: float @sqrtf ; WIN64: float @llvm.fabs.f32( ; WIN64-NOT: float @powf ; MINGW32-LABEL: @float_powsqrt( ; MINGW32: float @sqrtf ; MINGW32: float @llvm.fabs.f32 ; MINGW32-NOT: float @powf ; MINGW64-LABEL: @float_powsqrt( ; MINGW64: float @sqrtf ; MINGW64: float @llvm.fabs.f32( ; MINGW64-NOT: float @powf %1 = call float @powf(float %x, float 0.5) ret float %1 }