]> granicus.if.org Git - llvm/commitdiff
[TargetLibraryInfo] Update run time support for Windows
authorEvandro Menezes <e.menezes@samsung.com>
Mon, 11 Feb 2019 19:02:28 +0000 (19:02 +0000)
committerEvandro Menezes <e.menezes@samsung.com>
Mon, 11 Feb 2019 19:02:28 +0000 (19:02 +0000)
It seems that the run time for Windows has changed and supports more math
functions than it used to, especially on AArch64, ARM, and AMD64.

Fixes PR40541.

Differential revision: https://reviews.llvm.org/D57625

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353733 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/TargetLibraryInfo.cpp
test/Transforms/InstCombine/double-float-shrink-1.ll
test/Transforms/InstCombine/double-float-shrink-2.ll
test/Transforms/InstCombine/pow-1.ll
test/Transforms/InstCombine/win-math.ll

index bc662d2dfe098a4f4eb59ee720f9a34ddc811099..608ac6680e6d3ff6257e47dbdfb151ea766374c5 100644 (file)
@@ -160,8 +160,25 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
   }
 
   if (T.isOSWindows() && !T.isOSCygMing()) {
-    if (T.getArch() == Triple::x86) {
-      // Win32 does not support float math functions, in general.
+    // XXX: The earliest documentation available at the moment is for VS2015/VC19:
+    // https://docs.microsoft.com/en-us/cpp/c-runtime-library/floating-point-support?view=vs-2015
+    // XXX: In order to use an MSVCRT older than VC19,
+    // the specific library version must be explicit in the target triple,
+    // e.g., x86_64-pc-windows-msvc18.
+    bool hasPartialC99 = true;
+    if (T.isKnownWindowsMSVCEnvironment()) {
+      unsigned Major, Minor, Micro;
+      T.getEnvironmentVersion(Major, Minor, Micro);
+      hasPartialC99 = (Major == 0 || Major >= 19);
+    }
+
+    // Latest targets support float math functions, in part.
+    bool hasPartialFloat = (T.getArch() == Triple::aarch64 ||
+                            T.getArch() == Triple::arm ||
+                            T.getArch() == Triple::x86_64);
+
+    // Win32 does not support float math functions, in general.
+    if (!hasPartialFloat) {
       TLI.setUnavailable(LibFunc_acosf);
       TLI.setUnavailable(LibFunc_asinf);
       TLI.setUnavailable(LibFunc_atanf);
@@ -172,8 +189,6 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
       TLI.setUnavailable(LibFunc_coshf);
       TLI.setUnavailable(LibFunc_expf);
       TLI.setUnavailable(LibFunc_floorf);
-      TLI.setUnavailable(LibFunc_fminf);
-      TLI.setUnavailable(LibFunc_fmaxf);
       TLI.setUnavailable(LibFunc_fmodf);
       TLI.setUnavailable(LibFunc_logf);
       TLI.setUnavailable(LibFunc_log10f);
@@ -185,11 +200,13 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
       TLI.setUnavailable(LibFunc_tanf);
       TLI.setUnavailable(LibFunc_tanhf);
     }
-    TLI.setUnavailable(LibFunc_fabsf); // Win32 and Win64 both lack fabsf
+    TLI.setUnavailable(LibFunc_fabsf);
+    TLI.setUnavailable(LibFunc_fmaxf);
+    TLI.setUnavailable(LibFunc_fminf);
     TLI.setUnavailable(LibFunc_frexpf);
     TLI.setUnavailable(LibFunc_ldexpf);
 
-    // Win32 does not support long double.
+    // Win32 does not support long double math functions.
     TLI.setUnavailable(LibFunc_acosl);
     TLI.setUnavailable(LibFunc_asinl);
     TLI.setUnavailable(LibFunc_atanl);
@@ -207,6 +224,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
     TLI.setUnavailable(LibFunc_frexpl);
     TLI.setUnavailable(LibFunc_ldexpl);
     TLI.setUnavailable(LibFunc_logl);
+    TLI.setUnavailable(LibFunc_log10l);
     TLI.setUnavailable(LibFunc_modfl);
     TLI.setUnavailable(LibFunc_powl);
     TLI.setUnavailable(LibFunc_sinl);
@@ -216,51 +234,62 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
     TLI.setUnavailable(LibFunc_tanhl);
 
     // Win32 does not fully support C99 math functions.
-    TLI.setUnavailable(LibFunc_acosh);
+    if (!hasPartialC99) {
+      TLI.setUnavailable(LibFunc_acosh);
+      TLI.setUnavailable(LibFunc_asinh);
+      TLI.setUnavailable(LibFunc_atanh);
+      TLI.setUnavailable(LibFunc_cbrt);
+      TLI.setUnavailable(LibFunc_exp2);
+      TLI.setUnavailable(LibFunc_expm1);
+      TLI.setUnavailable(LibFunc_log1p);
+      TLI.setUnavailable(LibFunc_log2);
+      TLI.setUnavailable(LibFunc_logb);
+      TLI.setUnavailable(LibFunc_nearbyint);
+      TLI.setUnavailable(LibFunc_rint);
+      TLI.setUnavailable(LibFunc_round);
+      TLI.setUnavailable(LibFunc_trunc);
+    }
+
+    // Win32 does not support float C99 math functions, in general.
     TLI.setUnavailable(LibFunc_acoshf);
-    TLI.setUnavailable(LibFunc_acoshl);
-    TLI.setUnavailable(LibFunc_asinh);
     TLI.setUnavailable(LibFunc_asinhf);
-    TLI.setUnavailable(LibFunc_asinhl);
-    TLI.setUnavailable(LibFunc_atanh);
     TLI.setUnavailable(LibFunc_atanhf);
-    TLI.setUnavailable(LibFunc_atanhl);
-    TLI.setUnavailable(LibFunc_cabs);
     TLI.setUnavailable(LibFunc_cabsf);
-    TLI.setUnavailable(LibFunc_cabsl);
-    TLI.setUnavailable(LibFunc_cbrt);
     TLI.setUnavailable(LibFunc_cbrtf);
-    TLI.setUnavailable(LibFunc_cbrtl);
-    TLI.setUnavailable(LibFunc_exp2);
     TLI.setUnavailable(LibFunc_exp2f);
-    TLI.setUnavailable(LibFunc_exp2l);
-    TLI.setUnavailable(LibFunc_expm1);
     TLI.setUnavailable(LibFunc_expm1f);
-    TLI.setUnavailable(LibFunc_expm1l);
-    TLI.setUnavailable(LibFunc_log2);
-    TLI.setUnavailable(LibFunc_log2f);
-    TLI.setUnavailable(LibFunc_log2l);
-    TLI.setUnavailable(LibFunc_log1p);
     TLI.setUnavailable(LibFunc_log1pf);
+    TLI.setUnavailable(LibFunc_log2f);
+    if (!hasPartialFloat || !hasPartialC99)
+      TLI.setUnavailable(LibFunc_logbf);
+    TLI.setUnavailable(LibFunc_nearbyintf);
+    TLI.setUnavailable(LibFunc_rintf);
+    TLI.setUnavailable(LibFunc_roundf);
+    TLI.setUnavailable(LibFunc_truncf);
+
+    // Win32 does not support long double C99 math functions.
+    TLI.setUnavailable(LibFunc_acoshl);
+    TLI.setUnavailable(LibFunc_asinhl);
+    TLI.setUnavailable(LibFunc_atanhl);
+    TLI.setUnavailable(LibFunc_cabsl);
+    TLI.setUnavailable(LibFunc_cbrtl);
+    TLI.setUnavailable(LibFunc_exp2l);
+    TLI.setUnavailable(LibFunc_expm1l);
     TLI.setUnavailable(LibFunc_log1pl);
-    TLI.setUnavailable(LibFunc_logb);
-    TLI.setUnavailable(LibFunc_logbf);
+    TLI.setUnavailable(LibFunc_log2l);
     TLI.setUnavailable(LibFunc_logbl);
-    TLI.setUnavailable(LibFunc_nearbyint);
-    TLI.setUnavailable(LibFunc_nearbyintf);
     TLI.setUnavailable(LibFunc_nearbyintl);
-    TLI.setUnavailable(LibFunc_rint);
-    TLI.setUnavailable(LibFunc_rintf);
     TLI.setUnavailable(LibFunc_rintl);
-    TLI.setUnavailable(LibFunc_round);
-    TLI.setUnavailable(LibFunc_roundf);
     TLI.setUnavailable(LibFunc_roundl);
-    TLI.setUnavailable(LibFunc_trunc);
-    TLI.setUnavailable(LibFunc_truncf);
     TLI.setUnavailable(LibFunc_truncl);
 
-    // Win32 supports some C99 math functions, but with mangled names.
+    // Win32 supports some C89 and C99 math functions, but with mangled names.
+    TLI.setAvailableWithName(LibFunc_cabs, "_cabs");
     TLI.setAvailableWithName(LibFunc_copysign, "_copysign");
+    if (hasPartialFloat)
+      TLI.setAvailableWithName(LibFunc_copysignf, "_copysignf");
+    if (hasPartialFloat && hasPartialC99)
+      TLI.setAvailableWithName(LibFunc_logbf, "_logbf");
 
     // Win32 does not support these C99 functions.
     TLI.setUnavailable(LibFunc_atoll);
index e3dc6bb54ed5bc9253eaf286a7a85ad7e31d0e48..d76c64d8ec8514f0dc2b8cf71ee3ba02ce1e9040 100644 (file)
@@ -1,6 +1,8 @@
-; RUN: opt < %s -instcombine -S -mtriple x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK,LINUX,LIN64
-; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-win32          | FileCheck %s --check-prefixes=CHECK,WIN64,WIN96,LIN64
-; RUN: opt < %s -instcombine -S -mtriple i386-pc-win32            | FileCheck %s --check-prefixes=CHECK,WIN32,WIN96
+; RUN: opt < %s -instcombine -S -mtriple x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK,LINUX,LINMS
+; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-win32          | FileCheck %s --check-prefixes=CHECK,MSVC,LINMS
+; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-windows-msvc16 | FileCheck %s --check-prefixes=CHECK,MSVC,MS64
+; RUN: opt < %s -instcombine -S -mtriple i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,MSVC,MS32
+; RUN: opt < %s -instcombine -S -mtriple i686-pc-windows-msvc17   | FileCheck %s --check-prefixes=CHECK,MSVC,MS32
 
 ; Check for and against shrinkage when using the
 ; unsafe-fp-math function attribute on a math lib
 
 define float @acos_test1(float %f)   {
 ; CHECK-LABEL: @acos_test1(
-; LIN64-NEXT:    [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[ACOSF]]
-; WIN32:         [[ACOSF:%.*]] = call fast double @acos(double [[F:%.*]])
+; LINMS-NEXT:    [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[ACOSF]]
+; MS64-NEXT:     [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[ACOSF]]
+; MS32:          [[ACOSF:%.*]] = call fast double @acos(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @acos(double %conv)
@@ -35,7 +39,7 @@ define float @acosh_test1(float %f)   {
 ; CHECK-LABEL: @acosh_test1(
 ; LINUX-NEXT:    [[ACOSHF:%.*]] = call fast float @acoshf(float [[F:%.*]])
 ; LINUX-NEXT:    ret float [[ACOSHF]]
-; WIN96:         [[ACOSHF:%.*]] = call fast double @acosh(double [[F:%.*]])
+; MSVC:          [[ACOSHF:%.*]] = call fast double @acosh(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @acosh(double %conv)
@@ -56,9 +60,11 @@ define double @acosh_test2(float %f)   {
 
 define float @asin_test1(float %f)   {
 ; CHECK-LABEL: @asin_test1(
-; LIN64-NEXT:    [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[ASINF]]
-; WIN32:         [[ASINF:%.*]] = call fast double @asin(double [[F:%.*]])
+; LINMS-NEXT:    [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[ASINF]]
+; MS64-NEXT:     [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[ASINF]]
+; MS32:          [[ASINF:%.*]] = call fast double @asin(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @asin(double %conv)
@@ -81,7 +87,7 @@ define float @asinh_test1(float %f)   {
 ; CHECK-LABEL: @asinh_test1(
 ; LINUX-NEXT:   [[ASINHF:%.*]] = call fast float @asinhf(float [[F:%.*]])
 ; LINUX-NEXT:   ret float [[ASINHF]]
-; WIN96:        [[ASINHF:%.*]] = call fast double @asinh(double [[F:%.*]])
+; MSVC:         [[ASINHF:%.*]] = call fast double @asinh(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @asinh(double %conv)
@@ -102,9 +108,11 @@ define double @asinh_test2(float %f)   {
 
 define float @atan_test1(float %f)   {
 ; CHECK-LABEL: @atan_test1(
-; LIN64-NEXT:    [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[ATANF]]
-; WIN32:         [[ATANF:%.*]] = call fast double @atan(double [[F:%.*]])
+; LINMS-NEXT:    [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[ATANF]]
+; MS64-NEXT:     [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[ATANF]]
+; MS32:          [[ATANF:%.*]] = call fast double @atan(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @atan(double %conv)
@@ -127,7 +135,7 @@ define float @atanh_test1(float %f)   {
 ; CHECK-LABEL: @atanh_test1(
 ; LINUX-NEXT:    [[ATANHF:%.*]] = call fast float @atanhf(float [[F:%.*]])
 ; LINUX-NEXT:    ret float [[ATANHF]]
-; WIN96:         [[ATANHF:%.*]] = call fast double @atanh(double [[F:%.*]])
+; MSVC:          [[ATANHF:%.*]] = call fast double @atanh(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @atanh(double %conv)
@@ -150,7 +158,7 @@ define float @cbrt_test1(float %f)   {
 ; CHECK-LABEL: @cbrt_test1(
 ; LINUX-NEXT:    [[CBRTF:%.*]] = call fast float @cbrtf(float [[F:%.*]])
 ; LINUX-NEXT:    ret float [[CBRTF]]
-; WIN96:         [[CBRTF:%.*]] = call fast double @cbrt(double [[F:%.*]])
+; MSVC:          [[CBRTF:%.*]] = call fast double @cbrt(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @cbrt(double %conv)
@@ -171,9 +179,11 @@ define double @cbrt_test2(float %f)   {
 
 define float @exp_test1(float %f)   {
 ; CHECK-LABEL: @exp_test1(
-; LIN64-NEXT:    [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[EXPF]]
-; WIN32:         [[EXPF:%.*]] = call fast double @exp(double [[F:%.*]])
+; LINMS-NEXT:    [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[EXPF]]
+; MS64-NEXT:     [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[EXPF]]
+; MS32:          [[EXPF:%.*]] = call fast double @exp(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @exp(double %conv)
@@ -196,7 +206,7 @@ define float @expm1_test1(float %f)   {
 ; CHECK-LABEL: @expm1_test1(
 ; LINUX-NEXT:    [[EXPM1F:%.*]] = call fast float @expm1f(float [[F:%.*]])
 ; LINUX-NEXT:    ret float [[EXPM1F]]
-; WIN96:         [[EXPM1F:%.*]] = call fast double @expm1(double [[F:%.*]])
+; MSVC:          [[EXPM1F:%.*]] = call fast double @expm1(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @expm1(double %conv)
@@ -243,9 +253,11 @@ define double @exp10_test2(float %f)   {
 
 define float @log_test1(float %f)   {
 ; CHECK-LABEL: @log_test1(
-; LIN64-NEXT:    [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[LOGF]]
-; WIN32:         [[LOGF:%.*]] = call fast double @log(double [[F:%.*]])
+; LINMS-NEXT:    [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[LOGF]]
+; MS64-NEXT:     [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[LOGF]]
+; MS32:          [[LOGF:%.*]] = call fast double @log(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @log(double %conv)
@@ -266,9 +278,11 @@ define double @log_test2(float %f)   {
 
 define float @log10_test1(float %f)   {
 ; CHECK-LABEL: @log10_test1(
-; LIN64-NEXT:    [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[LOG10F]]
-; WIN32:         [[LOG10F:%.*]] = call fast double @log10(double [[F:%.*]])
+; LINMS-NEXT:    [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[LOG10F]]
+; MS64-NEXT:     [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
+; MS64-NEXT:     ret float [[LOG10F]]
+; MS32:          [[LOG10F:%.*]] = call fast double @log10(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @log10(double %conv)
@@ -291,7 +305,7 @@ define float @log1p_test1(float %f)   {
 ; CHECK-LABEL: @log1p_test1(
 ; LINUX-NEXT:    [[LOG1PF:%.*]] = call fast float @log1pf(float [[F:%.*]])
 ; LINUX-NEXT:    ret float [[LOG1PF]]
-; WIN96:         [[LOG1PF:%.*]] = call fast double @log1p(double [[F:%.*]])
+; MSVC:          [[LOG1PF:%.*]] = call fast double @log1p(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @log1p(double %conv)
@@ -313,8 +327,8 @@ define double @log1p_test2(float %f)   {
 define float @log2_test1(float %f)   {
 ; CHECK-LABEL: @log2_test1(
 ; LINUX-NEXT:    [[LOG2F:%.*]] = call fast float @log2f(float [[F:%.*]])
-; LINUX-NEXT:     ret float [[LOG2F]]
-; WIN96:         [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
+; LINUX-NEXT:    ret float [[LOG2F]]
+; MSVC:          [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @log2(double %conv)
@@ -335,9 +349,9 @@ define double @log2_test2(float %f)   {
 
 define float @logb_test1(float %f)   {
 ; CHECK-LABEL: @logb_test1(
-; LINUX-NEXT:    [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]])
-; LINUX-NEXT:    ret float [[LOGBF]]
-; WIN96:         [[LOGBF:%.*]] = call fast double @logb(double [[F:%.*]])
+; LINMS-NEXT:    [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[LOGBF]]
+; MS64:          [[LOGBF:%.*]] = call fast double @logb(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @logb(double %conv)
@@ -358,9 +372,11 @@ define double @logb_test2(float %f)   {
 
 define float @pow_test1(float %f, float %g)   {
 ; CHECK-LABEL: @pow_test1(
-; LIN64-NEXT:    [[POWF:%.*]] = call fast float @powf(float %f, float %g)
-; LIN64-NEXT:    ret float [[POWF]]
-; WIN32:         [[POWF:%.*]] = call fast double @pow(double %df, double %dg)
+; LINMS-NEXT:    [[POWF:%.*]] = call fast float @powf(float %f, float %g)
+; LINMS-NEXT:    ret float [[POWF]]
+; MS64-NEXT:     [[POWF:%.*]] = call fast float @powf(float %f, float %g)
+; MS64-NEXT:     ret float [[POWF]]
+; MS32:          [[POWF:%.*]] = call fast double @pow(double %df, double %dg)
 ;
   %df = fpext float %f to double
   %dg = fpext float %g to double
@@ -382,9 +398,11 @@ define double @pow_test2(float %f, float %g) {
 
 define float @sin_test1(float %f)   {
 ; CHECK-LABEL: @sin_test1(
-; LIN64-NEXT:    [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[SINF]]
-; WIN32:         [[SINF:%.*]] = call fast double @sin(double [[F:%.*]])
+; LINMS-NEXT:    [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[SINF]]
+; MS64-NEXT:     [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[SINF]]
+; MS32:          [[SINF:%.*]] = call fast double @sin(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @sin(double %conv)
@@ -405,9 +423,11 @@ define double @sin_test2(float %f) {
 
 define float @sqrt_test1(float %f) {
 ; CHECK-LABEL: @sqrt_test1(
-; LIN64-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[SQRTF]]
-; WIN32:         [[SQRTF:%.*]] = call double @sqrt(double [[F:%.*]])
+; LINMS-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[SQRTF]]
+; MS64-NEXT:     [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[SQRTF]]
+; MS32:          [[SQRTF:%.*]] = call double @sqrt(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call double @sqrt(double %conv)
@@ -428,9 +448,11 @@ define double @sqrt_test2(float %f) {
 
 define float @sqrt_int_test1(float %f) {
 ; CHECK-LABEL: @sqrt_int_test1(
-; LIN64-NEXT:    [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[TMP1]]
-; WIN32:         [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
+; LINMS-NEXT:    [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[TMP1]]
+; MS64-NEXT:     [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
+; MS64-NEXT:     ret float [[TMP1]]
+; MS32:          [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call double @llvm.sqrt.f64(double %conv)
@@ -451,9 +473,11 @@ define double @sqrt_int_test2(float %f) {
 
 define float @tan_test1(float %f) {
 ; CHECK-LABEL: @tan_test1(
-; LIN64-NEXT:    [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[TANF]]
-; WIN32:         [[TANF:%.*]] = call fast double @tan(double [[F:%.*]])
+; LINMS-NEXT:    [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[TANF]]
+; MS64-NEXT:     [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[TANF]]
+; MS32:          [[TANF:%.*]] = call fast double @tan(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @tan(double %conv)
@@ -473,9 +497,11 @@ define double @tan_test2(float %f) {
 }
 define float @tanh_test1(float %f) {
 ; CHECK-LABEL: @tanh_test1(
-; LIN64-NEXT:    [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
-; LIN64-NEXT:    ret float [[TANHF]]
-; WIN32:         [[TANHF:%.*]] = call fast double @tanh(double [[F:%.*]])
+; LINMS-NEXT:    [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
+; LINMS-NEXT:    ret float [[TANHF]]
+; MS64-NEXT:     [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
+; MS64-NEXT:     ret float [[TANHF]]
+; MS32:          [[TANHF:%.*]] = call fast double @tanh(double [[F:%.*]])
 ;
   %conv = fpext float %f to double
   %call = call fast double @tanh(double %conv)
@@ -498,9 +524,9 @@ define double @tanh_test2(float %f) {
 ; flags are propagated for shrunken *binary* double FP calls.
 define float @max1(float %a, float %b) {
 ; CHECK-LABEL: @max1(
-; LIN64-NEXT:    [[FMAXF:%.*]] = call arcp float @fmaxf(float [[A:%.*]], float [[B:%.*]])
-; LIN64-NEXT:    ret float [[FMAXF]]
-; WIN32:         [[FMAXF:%.*]] = call arcp double @fmax(double [[A:%.*]], double [[B:%.*]])
+; LINUX-NEXT:    [[FMAXF:%.*]] = call arcp float @fmaxf(float [[A:%.*]], float [[B:%.*]])
+; LINUX-NEXT:    ret float [[FMAXF]]
+; MSVC:          [[FMAXF:%.*]] = call arcp double @fmax(double [[A:%.*]], double [[B:%.*]])
 ;
   %c = fpext float %a to double
   %d = fpext float %b to double
index d5099531af9fb38c99798506f7c8e037d973acfd..76e497bd68fc7949e4b57336b6d2e64dc3c1195b 100644 (file)
@@ -1,10 +1,10 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -instcombine -S -mtriple "i386-pc-linux"     | FileCheck --check-prefixes=CHECK,DO-SIMPLIFY %s
-; RUN: opt < %s -instcombine -S -mtriple "i386-pc-win32"     | FileCheck --check-prefixes=CHECK,DONT-SIMPLIFY %s
-; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32"   | FileCheck --check-prefixes=CHECK,C89-SIMPLIFY %s
-; RUN: opt < %s -instcombine -S -mtriple "i386-pc-mingw32"   | FileCheck --check-prefixes=CHECK,DO-SIMPLIFY %s
-; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck --check-prefixes=CHECK,DO-SIMPLIFY %s
-; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck --check-prefixes=CHECK,DO-SIMPLIFY %s
+; RUN: opt < %s -instcombine -S -mtriple "i386-pc-linux"     | FileCheck %s
+; RUN: opt < %s -instcombine -S -mtriple "i386-pc-win32"     | FileCheck %s
+; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32"   | FileCheck %s
+; RUN: opt < %s -instcombine -S -mtriple "i386-pc-mingw32"   | FileCheck %s
+; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck %s
+; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck %s
 ; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" -enable-debugify 2>&1 | FileCheck --check-prefix=DBG-VALID %s
 
 declare double @floor(double)
@@ -61,19 +61,8 @@ define float @test_shrink_libcall_ceil(float %C) {
 
 define float @test_shrink_libcall_round(float %C) {
 ; CHECK-LABEL: @test_shrink_libcall_round(
-
-; DO-SIMPLIFY-NEXT:    [[F:%.*]] = call float @llvm.round.f32(float [[C:%.*]])
-; DO-SIMPLIFY-NEXT:    ret float [[F]]
-;
-; DONT-SIMPLIFY-NEXT:    [[D:%.*]] = fpext float [[C:%.*]] to double
-; DONT-SIMPLIFY-NEXT:    [[E:%.*]] = call double @round(double [[D]])
-; DONT-SIMPLIFY-NEXT:    [[F:%.*]] = fptrunc double [[E]] to float
-; DONT-SIMPLIFY-NEXT:    ret float [[F]]
-;
-; C89-SIMPLIFY-NEXT:    [[D:%.*]] = fpext float [[C:%.*]] to double
-; C89-SIMPLIFY-NEXT:    [[E:%.*]] = call double @round(double [[D]])
-; C89-SIMPLIFY-NEXT:    [[F:%.*]] = fptrunc double [[E]] to float
-; C89-SIMPLIFY-NEXT:    ret float [[F]]
+; CHECK-NEXT:    [[F:%.*]] = call float @llvm.round.f32(float [[C:%.*]])
+; CHECK-NEXT:    ret float [[F]]
 ;
   %D = fpext float %C to double
   ; --> roundf
@@ -84,19 +73,8 @@ define float @test_shrink_libcall_round(float %C) {
 
 define float @test_shrink_libcall_nearbyint(float %C) {
 ; CHECK-LABEL: @test_shrink_libcall_nearbyint(
-
-; DO-SIMPLIFY-NEXT:    [[F:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]])
-; DO-SIMPLIFY-NEXT:    ret float [[F]]
-;
-; DONT-SIMPLIFY-NEXT:    [[D:%.*]] = fpext float [[C:%.*]] to double
-; DONT-SIMPLIFY-NEXT:    [[E:%.*]] = call double @nearbyint(double [[D]])
-; DONT-SIMPLIFY-NEXT:    [[F:%.*]] = fptrunc double [[E]] to float
-; DONT-SIMPLIFY-NEXT:    ret float [[F]]
-;
-; C89-SIMPLIFY-NEXT:    [[D:%.*]] = fpext float [[C:%.*]] to double
-; C89-SIMPLIFY-NEXT:    [[E:%.*]] = call double @nearbyint(double [[D]])
-; C89-SIMPLIFY-NEXT:    [[F:%.*]] = fptrunc double [[E]] to float
-; C89-SIMPLIFY-NEXT:    ret float [[F]]
+; CHECK-NEXT:    [[F:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]])
+; CHECK-NEXT:    ret float [[F]]
 ;
   %D = fpext float %C to double
   ; --> nearbyintf
@@ -107,19 +85,8 @@ define float @test_shrink_libcall_nearbyint(float %C) {
 
 define float @test_shrink_libcall_trunc(float %C) {
 ; CHECK-LABEL: @test_shrink_libcall_trunc(
-
-; DO-SIMPLIFY-NEXT:    [[F:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]])
-; DO-SIMPLIFY-NEXT:    ret float [[F]]
-;
-; DONT-SIMPLIFY-NEXT:    [[D:%.*]] = fpext float [[C:%.*]] to double
-; DONT-SIMPLIFY-NEXT:    [[E:%.*]] = call double @trunc(double [[D]])
-; DONT-SIMPLIFY-NEXT:    [[F:%.*]] = fptrunc double [[E]] to float
-; DONT-SIMPLIFY-NEXT:    ret float [[F]]
-;
-; C89-SIMPLIFY-NEXT:    [[D:%.*]] = fpext float [[C:%.*]] to double
-; C89-SIMPLIFY-NEXT:    [[E:%.*]] = call double @trunc(double [[D]])
-; C89-SIMPLIFY-NEXT:    [[F:%.*]] = fptrunc double [[E]] to float
-; C89-SIMPLIFY-NEXT:    ret float [[F]]
+; CHECK-NEXT:    [[F:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]])
+; CHECK-NEXT:    ret float [[F]]
 ;
   %D = fpext float %C to double
   ; --> truncf
index 85f61b886c5812073d0e7cdda20c62c8a305075d..91b5cf9f1c6a5b6fe78890fcdb6e1d9109d7c9a0 100644 (file)
@@ -1,15 +1,18 @@
 ; Test that the pow library call simplifier works correctly.
 ;
-; RUN: opt -instcombine -S < %s                                  | FileCheck %s --check-prefixes=CHECK,ANY
-; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
-; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0        | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
-; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
-; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0        | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
-; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd           | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
-; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0       | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
-; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0    | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
+; RUN: opt -instcombine -S < %s                                   | FileCheck %s --check-prefixes=CHECK,ANY
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9  | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0         | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8  | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0         | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd            | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0        | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0     | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
 ; rdar://7251832
-; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc  | FileCheck %s --check-prefixes=CHECK,WIN,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18   | FileCheck %s --check-prefixes=CHECK,MSVC,VC32,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,MSVC,VC19,VC51,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC64,VC83,CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc   | FileCheck %s --check-prefixes=CHECK,MSVC,VC19,VC83,CHECK-NO-EXP10
 
 ; NOTE: The readonly attribute on the pow call should be preserved
 ; in the cases below where pow is transformed into another function call.
@@ -24,7 +27,12 @@ declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readon
 
 define float @test_simplify1(float %x) {
 ; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT:  ret float 1.000000e+00
+; ANY-NEXT:    ret float 1.000000e+00
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]])
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]])
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   ret float 1.000000e+00
 ;
   %retval = call float @powf(float 1.0, float %x)
   ret float %retval
@@ -33,8 +41,8 @@ define float @test_simplify1(float %x) {
 define <2 x float> @test_simplify1v(<2 x float> %x) {
 ; CHECK-LABEL: @test_simplify1v(
 ; ANY-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> %x)
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]])
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x)
   ret <2 x float> %retval
@@ -51,8 +59,8 @@ define double @test_simplify2(double %x) {
 define <2 x double> @test_simplify2v(<2 x double> %x) {
 ; CHECK-LABEL: @test_simplify2v(
 ; ANY-NEXT:    ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
-; WIN-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x double> %x)
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x double> [[X:%.*]])
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x)
   ret <2 x double> %retval
@@ -62,10 +70,10 @@ define <2 x double> @test_simplify2v(<2 x double> %x) {
 
 define float @test_simplify3(float %x) {
 ; CHECK-LABEL: @test_simplify3(
-; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) [[NUW_RO:#[0-9]+]]
+; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]])
 ; ANY-NEXT:    ret float [[EXP2F]]
-; WIN-NEXT:    [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
-; WIN-NEXT:    ret float [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
+; MSVC-NEXT:   ret float [[POW]]
 ;
   %retval = call float @powf(float 2.0, float %x)
   ret float %retval
@@ -74,10 +82,13 @@ define float @test_simplify3(float %x) {
 define double @test_simplify3n(double %x) {
 ; CHECK-LABEL: @test_simplify3n(
 ; ANY-NEXT:    [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00
-; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[MUL]]) [[NUW_RO]]
+; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[MUL]])
 ; ANY-NEXT:    ret double [[EXP2]]
-; WIN-NEXT:    [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
-; WIN-NEXT:    ret double [[POW]]
+; VC64-NEXT:   [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
+; VC64-NEXT:   ret double [[POW]]
+; VC19-NEXT:   [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00
+; VC19-NEXT:   [[EXP2:%.*]] = call double @exp2(double [[MUL]])
+; VC19-NEXT:   ret double [[EXP2]]
 ;
   %retval = call double @pow(double 0.25, double %x)
   ret double %retval
@@ -87,8 +98,8 @@ define <2 x float> @test_simplify3v(<2 x float> %x) {
 ; CHECK-LABEL: @test_simplify3v(
 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]])
 ; ANY-NEXT:    ret <2 x float> [[EXP2]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]])
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]])
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x)
   ret <2 x float> %retval
@@ -99,8 +110,8 @@ define <2 x double> @test_simplify3vn(<2 x double> %x) {
 ; ANY-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], <double 2.000000e+00, double 2.000000e+00>
 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
 ; ANY-NEXT:    ret <2 x double> [[EXP2]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> %x)
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]])
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x)
   ret <2 x double> %retval
@@ -108,10 +119,12 @@ define <2 x double> @test_simplify3vn(<2 x double> %x) {
 
 define double @test_simplify4(double %x) {
 ; CHECK-LABEL: @test_simplify4(
-; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[X:%.*]]) [[NUW_RO]]
+; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[X:%.*]])
 ; ANY-NEXT:    ret double [[EXP2]]
-; WIN-NEXT:    [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
-; WIN-NEXT:    ret double [[POW]]
+; VC64-NEXT:   [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
+; VC64-NEXT:   ret double [[POW]]
+; VC19-NEXT:   [[EXP2:%.*]] = call double @exp2(double [[X:%.*]])
+; VC19-NEXT:   ret double [[EXP2]]
 ;
   %retval = call double @pow(double 2.0, double %x)
   ret double %retval
@@ -120,10 +133,10 @@ define double @test_simplify4(double %x) {
 define float @test_simplify4n(float %x) {
 ; CHECK-LABEL: @test_simplify4n(
 ; ANY-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00
-; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) [[NUW_RO]]
+; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
 ; ANY-NEXT:    ret float [[EXP2F]]
-; WIN-NEXT:    [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
-; WIN-NEXT:    ret float [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
+; MSVC-NEXT:   ret float [[POW]]
 ;
   %retval = call float @powf(float 8.0, float %x)
   ret float %retval
@@ -133,8 +146,8 @@ define <2 x double> @test_simplify4v(<2 x double> %x) {
 ; CHECK-LABEL: @test_simplify4v(
 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]])
 ; ANY-NEXT:    ret <2 x double> [[EXP2]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]])
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]])
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x)
   ret <2 x double> %retval
@@ -145,8 +158,8 @@ define <2 x float> @test_simplify4vn(<2 x float> %x) {
 ; ANY-NEXT:    [[MUL:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
 ; ANY-NEXT:    ret <2 x float> [[EXP2]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]])
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]])
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x)
   ret <2 x float> %retval
@@ -156,7 +169,12 @@ define <2 x float> @test_simplify4vn(<2 x float> %x) {
 
 define float @test_simplify5(float %x) {
 ; CHECK-LABEL: @test_simplify5(
-; CHECK-NEXT:  ret float 1.000000e+00
+; ANY-NEXT:    ret float 1.000000e+00
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   ret float 1.000000e+00
 ;
   %retval = call float @powf(float %x, float 0.0)
   ret float %retval
@@ -165,8 +183,8 @@ define float @test_simplify5(float %x) {
 define <2 x float> @test_simplify5v(<2 x float> %x) {
 ; CHECK-LABEL: @test_simplify5v(
 ; ANY-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer)
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer)
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
   ret <2 x float> %retval
@@ -183,8 +201,8 @@ define double @test_simplify6(double %x) {
 define <2 x double> @test_simplify6v(<2 x double> %x) {
 ; CHECK-LABEL: @test_simplify6v(
 ; ANY-NEXT:    ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
-; WIN-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer)
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer)
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>)
   ret <2 x double> %retval
@@ -194,12 +212,20 @@ define <2 x double> @test_simplify6v(<2 x double> %x) {
 
 define float @test_simplify7(float %x) {
 ; CHECK-LABEL: @test_simplify7(
-; ANY-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]]) [[NUW_RO]]
-; WIN-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]]) [[NUW_RO:#[0-9]+]]
-; CHECK-NEXT:  [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]])
-; CHECK-NEXT:  [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000
-; CHECK-NEXT:  [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]]
-; CHECK-NEXT:  ret float [[TMP1]]
+; ANY-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]])
+; ANY-NEXT:    [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]])
+; ANY-NEXT:    [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000
+; ANY-NEXT:    [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]]
+; ANY-NEXT:    ret float [[TMP1]]
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]])
+; VC83-NEXT:   [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]])
+; VC83-NEXT:   [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000
+; VC83-NEXT:   [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]]
+; VC83-NEXT:   ret float [[TMP1]]
 ;
   %retval = call float @powf(float %x, float 0.5)
   ret float %retval
@@ -207,7 +233,7 @@ define float @test_simplify7(float %x) {
 
 define double @test_simplify8(double %x) {
 ; CHECK-LABEL: @test_simplify8(
-; CHECK-NEXT:  [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]]) [[NUW_RO]]
+; CHECK-NEXT:  [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]])
 ; CHECK-NEXT:  [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
 ; CHECK-NEXT:  [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
 ; CHECK-NEXT:  [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
@@ -221,7 +247,12 @@ define double @test_simplify8(double %x) {
 
 define float @test_simplify9(float %x) {
 ; CHECK-LABEL: @test_simplify9(
-; CHECK-NEXT:  ret float 0x7FF0000000000000
+; ANY-NEXT:    ret float 0x7FF0000000000000
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   ret float 0x7FF0000000000000
 ;
   %retval = call float @powf(float 0xFFF0000000000000, float 0.5)
   ret float %retval
@@ -239,7 +270,12 @@ define double @test_simplify10(double %x) {
 
 define float @test_simplify11(float %x) {
 ; CHECK-LABEL: @test_simplify11(
-; CHECK-NEXT:  ret float [[X:%.*]]
+; ANY-NEXT:    ret float [[X:%.*]]
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   ret float [[X:%.*]]
 ;
   %retval = call float @powf(float %x, float 1.0)
   ret float %retval
@@ -248,8 +284,8 @@ define float @test_simplify11(float %x) {
 define <2 x float> @test_simplify11v(<2 x float> %x) {
 ; CHECK-LABEL: @test_simplify11v(
 ; ANY-NEXT:    ret <2 x float> [[X:%.*]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>)
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>)
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
   ret <2 x float> %retval
@@ -266,8 +302,8 @@ define double @test_simplify12(double %x) {
 define <2 x double> @test_simplify12v(<2 x double> %x) {
 ; CHECK-LABEL: @test_simplify12v(
 ; ANY-NEXT:    ret <2 x double> [[X:%.*]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 1.000000e+00, double 1.000000e+00>)
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 1.000000e+00, double 1.000000e+00>)
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
   ret <2 x double> %retval
@@ -277,8 +313,14 @@ define <2 x double> @test_simplify12v(<2 x double> %x) {
 
 define float @pow2_strict(float %x) {
 ; CHECK-LABEL: @pow2_strict(
-; CHECK-NEXT:  [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
-; CHECK-NEXT:  ret float [[SQUARE]]
+; ANY-NEXT:    [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
+; ANY-NEXT:    ret float [[SQUARE]]
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
+; VC83-NEXT:   ret float [[SQUARE]]
 ;
   %r = call float @powf(float %x, float 2.0)
   ret float %r
@@ -288,8 +330,8 @@ define <2 x float> @pow2_strictv(<2 x float> %x) {
 ; CHECK-LABEL: @pow2_strictv(
 ; ANY-NEXT:    [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]]
 ; ANY-NEXT:    ret <2 x float> [[SQUARE]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 2.000000e+00, float 2.000000e+00>)
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 2.000000e+00, float 2.000000e+00>)
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
   ret <2 x float> %r
@@ -308,8 +350,8 @@ define <2 x double> @pow2_double_strictv(<2 x double> %x) {
 ; CHECK-LABEL: @pow2_double_strictv(
 ; ANY-NEXT:    [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]]
 ; ANY-NEXT:    ret <2 x double> [[SQUARE]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 2.000000e+00, double 2.000000e+00>)
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 2.000000e+00, double 2.000000e+00>)
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
   ret <2 x double> %r
@@ -319,8 +361,14 @@ define <2 x double> @pow2_double_strictv(<2 x double> %x) {
 
 define float @pow2_fast(float %x) {
 ; CHECK-LABEL: @pow2_fast(
-; CHECK-NEXT:  [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
-; CHECK-NEXT:  ret float [[SQUARE]]
+; ANY-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
+; ANY-NEXT:    ret float [[SQUARE]]
+; VC32-NEXT:   [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
+; VC83-NEXT:   ret float [[SQUARE]]
 ;
   %r = call fast float @powf(float %x, float 2.0)
   ret float %r
@@ -330,8 +378,14 @@ define float @pow2_fast(float %x) {
 
 define float @pow_neg1_strict(float %x) {
 ; CHECK-LABEL: @pow_neg1_strict(
-; CHECK-NEXT:  [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
-; CHECK-NEXT:  ret float [[RECIPROCAL]]
+; ANY-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
+; ANY-NEXT:    ret float [[RECIPROCAL]]
+; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
+; VC32-NEXT:   ret float [[POW]]
+; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
+; VC51-NEXT:   ret float [[POW]]
+; VC83-NEXT:   [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
+; VC83-NEXT:   ret float [[RECIPROCAL]]
 ;
   %r = call float @powf(float %x, float -1.0)
   ret float %r
@@ -341,8 +395,8 @@ define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
 ; CHECK-LABEL: @pow_neg1_strictv(
 ; ANY-NEXT:    [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X:%.*]]
 ; ANY-NEXT:    ret <2 x float> [[RECIPROCAL]]
-; WIN-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float -1.000000e+00, float -1.000000e+00>)
-; WIN-NEXT:    ret <2 x float> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float -1.000000e+00, float -1.000000e+00>)
+; MSVC-NEXT:   ret <2 x float> [[POW]]
 ;
   %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
   ret <2 x float> %r
@@ -361,8 +415,8 @@ define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
 ; CHECK-LABEL: @pow_neg1_double_fastv(
 ; ANY-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X:%.*]]
 ; ANY-NEXT:    ret <2 x double> [[RECIPROCAL]]
-; WIN-NEXT:    [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double -1.000000e+00, double -1.000000e+00>)
-; WIN-NEXT:    ret <2 x double> [[POW]]
+; MSVC-NEXT:   [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double -1.000000e+00, double -1.000000e+00>)
+; MSVC-NEXT:   ret <2 x double> [[POW]]
 ;
   %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
   ret <2 x double> %r
@@ -384,7 +438,7 @@ define double @test_simplify17(double %x) {
 
 define float @test_simplify18(float %x) {
 ; CHECK-LABEL:          @test_simplify18(
-; CHECK-EXP10-NEXT:     [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]]) [[NUW_RO]]
+; CHECK-EXP10-NEXT:     [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]])
 ; CHECK-EXP10-NEXT:     ret float [[__EXP10F]]
 ; CHECK-NO-EXP10-NEXT:  [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X:%.*]])
 ; CHECK-NO-EXP10-NEXT:  ret float [[RETVAL]]
@@ -395,7 +449,7 @@ define float @test_simplify18(float %x) {
 
 define double @test_simplify19(double %x) {
 ; CHECK-LABEL:          @test_simplify19(
-; CHECK-EXP10-NEXT:     [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]]) [[NUW_RO]]
+; CHECK-EXP10-NEXT:     [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]])
 ; CHECK-EXP10-NEXT:     ret double [[__EXP10]]
 ; CHECK-NO-EXP10-NEXT:  [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X:%.*]])
 ; CHECK-NO-EXP10-NEXT:  ret double [[RETVAL]]
@@ -403,5 +457,3 @@ define double @test_simplify19(double %x) {
   %retval = call double @pow(double 10.0, double %x)
   ret double %retval
 }
-
-; CHECK: attributes [[NUW_RO]] = { nounwind readonly }
index 4f774e5f6d51563a4b8d652e676a0a63e7cc65f1..38ed949e949dcef4f01822c81ede9495cbde3805 100644 (file)
@@ -1,19 +1,21 @@
-; RUN: opt -O2 -S -mtriple=i386-pc-win32 < %s     | FileCheck %s --check-prefixes=CHECK,WIN32
-; RUN: opt -O2 -S -mtriple=x86_64-pc-win32 < %s   | FileCheck %s --check-prefixes=CHECK,WIN64
-; RUN: opt -O2 -S -mtriple=i386-pc-mingw32 < %s   | FileCheck %s --check-prefixes=CHECK,MINGW32
-; RUN: opt -O2 -S -mtriple=x86_64-pc-mingw32 < %s | FileCheck %s --check-prefixes=CHECK,MINGW64
+; 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 (except for fabsf)
-; msvcrt does not provide C99 math, but mingw32 does.
+; 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(
-; WIN32-NOT: float @acosf
-; WIN32: double @acos
-; WIN64-NOT: float @acosf
-; WIN64: double @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
@@ -23,10 +25,10 @@ define float @float_acos(float %x) nounwind readnone {
 declare double @asin(double %x)
 define float @float_asin(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_asin(
-; WIN32-NOT: float @asinf
-; WIN32: double @asin
-; WIN64-NOT: float @asinf
-; WIN64: double @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
@@ -36,10 +38,10 @@ define float @float_asin(float %x) nounwind readnone {
 declare double @atan(double %x)
 define float @float_atan(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_atan(
-; WIN32-NOT: float @atanf
-; WIN32: double @atan
-; WIN64-NOT: float @atanf
-; WIN64: double @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
@@ -49,10 +51,10 @@ define float @float_atan(float %x) nounwind readnone {
 declare double @atan2(double %x, double %y)
 define float @float_atan2(float %x, float %y) nounwind readnone {
 ; CHECK-LABEL: @float_atan2(
-; WIN32-NOT: float @atan2f
-; WIN32: double @atan2
-; WIN64-NOT: float @atan2f
-; WIN64: double @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)
@@ -63,10 +65,10 @@ define float @float_atan2(float %x, float %y) nounwind readnone {
 declare double @ceil(double %x)
 define float @float_ceil(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_ceil(
-; WIN32-NOT: float @ceilf
-; WIN32: float @llvm.ceil.f32
-; WIN64-NOT: double @ceil
-; WIN64: float @llvm.ceil.f32
+; 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
@@ -80,10 +82,10 @@ define float @float_ceil(float %x) nounwind readnone {
 declare double @_copysign(double %x)
 define float @float_copysign(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_copysign(
-; WIN32-NOT: float @_copysignf
-; WIN32: double @_copysign
-; WIN64-NOT: float @_copysignf
-; WIN64: double @_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
@@ -93,10 +95,10 @@ define float @float_copysign(float %x) nounwind readnone {
 declare double @cos(double %x)
 define float @float_cos(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_cos(
-; WIN32-NOT: float @cosf
-; WIN32: double @cos
-; WIN64-NOT: float @cosf
-; WIN64: double @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
@@ -106,10 +108,10 @@ define float @float_cos(float %x) nounwind readnone {
 declare double @cosh(double %x)
 define float @float_cosh(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_cosh(
-; WIN32-NOT: float @coshf
-; WIN32: double @cosh
-; WIN64-NOT: float @coshf
-; WIN64: double @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
@@ -119,10 +121,10 @@ define float @float_cosh(float %x) nounwind readnone {
 declare double @exp(double %x, double %y)
 define float @float_exp(float %x, float %y) nounwind readnone {
 ; CHECK-LABEL: @float_exp(
-; WIN32-NOT: float @expf
-; WIN32: double @exp
-; WIN64-NOT: float @expf
-; WIN64: double @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)
@@ -133,10 +135,10 @@ define float @float_exp(float %x, float %y) nounwind readnone {
 declare double @fabs(double %x, double %y)
 define float @float_fabs(float %x, float %y) nounwind readnone {
 ; CHECK-LABEL: @float_fabs(
-; WIN32-NOT: float @fabsf
-; WIN32: double @fabs
-; WIN64-NOT: float @fabsf
-; WIN64: double @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)
@@ -147,10 +149,10 @@ define float @float_fabs(float %x, float %y) nounwind readnone {
 declare double @floor(double %x)
 define float @float_floor(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_floor(
-; WIN32-NOT: float @floorf
-; WIN32: float @llvm.floor.f32
-; WIN64-NOT: double @floor
-; WIN64: float @llvm.floor.f32
+; 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
@@ -163,11 +165,11 @@ define float @float_floor(float %x) nounwind readnone {
 
 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
-; WIN64-NOT: float @fmodf
-; WIN64: double @fmod
+; 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)
@@ -178,23 +180,36 @@ define float @float_fmod(float %x, float %y) nounwind readnone {
 declare double @log(double %x)
 define float @float_log(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_log(
-; WIN32-NOT: float @logf
-; WIN32: double @log
-; WIN64-NOT: float @logf
-; WIN64: double @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(
-; WIN32-NOT: float @powf
-; WIN32: double @pow
-; WIN64-NOT: float @powf
-; WIN64: double @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)
@@ -205,10 +220,10 @@ define float @float_pow(float %x, float %y) nounwind readnone {
 declare double @sin(double %x)
 define float @float_sin(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_sin(
-; WIN32-NOT: float @sinf
-; WIN32: double @sin
-; WIN64-NOT: float @sinf
-; WIN64: double @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
@@ -218,10 +233,10 @@ define float @float_sin(float %x) nounwind readnone {
 declare double @sinh(double %x)
 define float @float_sinh(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_sinh(
-; WIN32-NOT: float @sinhf
-; WIN32: double @sinh
-; WIN64-NOT: float @sinhf
-; WIN64: double @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
@@ -231,10 +246,14 @@ define float @float_sinh(float %x) nounwind readnone {
 declare double @sqrt(double %x)
 define float @float_sqrt(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_sqrt(
-; WIN32-NOT: float @sqrtf
-; WIN32: double @sqrt
-; WIN64-NOT: double @sqrt
-; WIN64: float @sqrtf
+; 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
@@ -248,10 +267,10 @@ define float @float_sqrt(float %x) nounwind readnone {
 declare double @tan(double %x)
 define float @float_tan(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_tan(
-; WIN32-NOT: float @tanf
-; WIN32: double @tan
-; WIN64-NOT: float @tanf
-; WIN64: double @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
@@ -261,24 +280,24 @@ define float @float_tan(float %x) nounwind readnone {
 declare double @tanh(double %x)
 define float @float_tanh(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_tanh(
-; WIN32-NOT: float @tanhf
-; WIN32: double @tanh
-; WIN64-NOT: float @tanhf
-; WIN64: double @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 round; mingw32 does
+; win32 does not have roundf; mingw32 does
 declare double @round(double %x)
 define float @float_round(float %x) nounwind readnone {
 ; CHECK-LABEL: @float_round(
-; WIN32-NOT: float @roundf
-; WIN32: double @round
-; WIN64-NOT: float @roundf
-; WIN64: double @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
@@ -291,15 +310,20 @@ define float @float_round(float %x) nounwind readnone {
 
 declare float @powf(float, float)
 
-; win32 lacks sqrtf&fabsf, win64 lacks fabsf, but
+; 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(
-; WIN32-NOT: float @sqrtf
-; WIN32: float @powf
-; WIN64-NOT: float @powf
-; WIN64: float @sqrtf
-; WIN64: float @llvm.fabs.f32(
+; 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