; RUN: opt < %s -O2 -S -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC32 ; RUN: opt < %s -O2 -S -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC51 ; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-windows-msvc17 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC64 ; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC83 ; RUN: opt < %s -O2 -S -mtriple=i386-pc-mingw32 | FileCheck %s --check-prefixes=CHECK,MINGW32 ; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-mingw32 | FileCheck %s --check-prefixes=CHECK,MINGW64 ; x86 win32 msvcrt does not provide entry points for single-precision libm. ; x86-64 win32 msvcrt does, but with exceptions ; msvcrt does not provide all of C99 math, but mingw32 does. declare double @acos(double %x) define float @float_acos(float %x) nounwind readnone { ; CHECK-LABEL: @float_acos( ; MSVCXX-NOT: float @acosf ; MSVCXX: double @acos ; MSVC19-NOT: float @acosf ; MSVC19: 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 { ; CHECK-LABEL: @float_asin( ; MSVCXX-NOT: float @asinf ; MSVCXX: double @asin ; MSVC19-NOT: float @asinf ; MSVC19: 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 { ; CHECK-LABEL: @float_atan( ; MSVCXX-NOT: float @atanf ; MSVCXX: double @atan ; MSVC19-NOT: float @atanf ; MSVC19: 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 { ; CHECK-LABEL: @float_atan2( ; MSVCXX-NOT: float @atan2f ; MSVCXX: double @atan2 ; MSVC19-NOT: float @atan2f ; MSVC19: 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 { ; CHECK-LABEL: @float_ceil( ; MSVCXX-NOT: float @ceilf ; MSVCXX: float @llvm.ceil.f32 ; MSVC19-NOT: double @ceil ; MSVC19: float @llvm.ceil.f32 ; MINGW32-NOT: double @ceil ; MINGW32: float @llvm.ceil.f32 ; MINGW64-NOT: double @ceil ; MINGW64: float @llvm.ceil.f32 %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 { ; CHECK-LABEL: @float_copysign( ; MSVCXX-NOT: float @_copysignf ; MSVCXX: double @_copysign ; MSVC19-NOT: float @_copysignf ; MSVC19: 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 { ; CHECK-LABEL: @float_cos( ; MSVCXX-NOT: float @cosf ; MSVCXX: double @cos ; MSVC19-NOT: float @cosf ; MSVC19: 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 { ; CHECK-LABEL: @float_cosh( ; MSVCXX-NOT: float @coshf ; MSVCXX: double @cosh ; MSVC19-NOT: float @coshf ; MSVC19: 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 { ; CHECK-LABEL: @float_exp( ; MSVCXX-NOT: float @expf ; MSVCXX: double @exp ; MSVC19-NOT: float @expf ; MSVC19: 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 { ; CHECK-LABEL: @float_fabs( ; MSVCXX-NOT: float @fabsf ; MSVCXX: double @fabs ; MSVC19-NOT: float @fabsf ; MSVC19: 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 { ; CHECK-LABEL: @float_floor( ; MSVCXX-NOT: float @floorf ; MSVCXX: float @llvm.floor.f32 ; MSVC19-NOT: double @floor ; MSVC19: float @llvm.floor.f32 ; MINGW32-NOT: double @floor ; MINGW32: float @llvm.floor.f32 ; MINGW64-NOT: double @floor ; MINGW64: float @llvm.floor.f32 %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 { ; MSVCXX-LABEL: @float_fmod( ; MSVCXX-NOT: float @fmodf ; MSVCXX: double @fmod ; MSVC19-NOT: float @fmodf ; MSVC19: 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 { ; CHECK-LABEL: @float_log( ; MSVCXX-NOT: float @logf ; MSVCXX: double @log ; MSVC19-NOT: float @logf ; MSVC19: 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 @logb(double %x) define float @float_logb(float %x) nounwind readnone { ; CHECK-LABEL: @float_logb( ; MSVCXX-NOT: float @logbf ; MSVCXX: double @logb ; MSVC19-NOT: float @logbf ; MSVC19: double @logb %1 = fpext float %x to double %2 = call double @logb(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 { ; CHECK-LABEL: @float_pow( ; MSVCXX-NOT: float @powf ; MSVCXX: double @pow ; MSVC19-NOT: float @powf ; MSVC19: 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 { ; CHECK-LABEL: @float_sin( ; MSVCXX-NOT: float @sinf ; MSVCXX: double @sin ; MSVC19-NOT: float @sinf ; MSVC19: 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 { ; CHECK-LABEL: @float_sinh( ; MSVCXX-NOT: float @sinhf ; MSVCXX: double @sinh ; MSVC19-NOT: float @sinhf ; MSVC19: 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 { ; CHECK-LABEL: @float_sqrt( ; MSVC32-NOT: float @sqrtf ; MSVC32: double @sqrt ; MSVC51-NOT: float @sqrtf ; MSVC51: double @sqrt ; MSVC64-NOT: double @sqrt ; MSVC64: float @sqrtf ; MSVC83-NOT: double @sqrt ; MSVC83: float @sqrtf ; MINGW32-NOT: double @sqrt ; MINGW32: float @sqrtf ; MINGW64-NOT: double @sqrt ; MINGW64: float @sqrtf %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 { ; CHECK-LABEL: @float_tan( ; MSVCXX-NOT: float @tanf ; MSVCXX: double @tan ; MSVC19-NOT: float @tanf ; MSVC19: 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 { ; CHECK-LABEL: @float_tanh( ; MSVCXX-NOT: float @tanhf ; MSVCXX: double @tanh ; MSVC19-NOT: float @tanhf ; MSVC19: 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 roundf; mingw32 does declare double @round(double %x) define float @float_round(float %x) nounwind readnone { ; CHECK-LABEL: @float_round( ; MSVCXX-NOT: double @roundf ; MSVCXX: double @round ; MSVC19-NOT: double @round ; MSVC19: float @llvm.round.f32 ; MINGW32-NOT: double @round ; MINGW32: float @llvm.round.f32 ; MINGW64-NOT: double @round ; MINGW64: float @llvm.round.f32 %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 { ; CHECK-LABEL: @float_powsqrt( ; MSVC32-NOT: float @sqrtf ; MSVC32: float @powf ; MSVC51-NOT: float @sqrtf ; MSVC51: float @powf ; MSVC64-NOT: float @powf ; MSVC64: float @sqrtf ; MSVC64: float @llvm.fabs.f32( ; MSVC83-NOT: float @powf ; MSVC83: float @sqrtf ; MSVC83: float @llvm.fabs.f32( ; MINGW32-NOT: float @powf ; MINGW32: float @sqrtf ; MINGW32: float @llvm.fabs.f32 ; MINGW64-NOT: float @powf ; MINGW64: float @sqrtf ; MINGW64: float @llvm.fabs.f32( %1 = call ninf float @powf(float %x, float 0.5) ret float %1 }