[TargetLibraryInfo] Update run time support for Windows

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
diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp
index bc662d2..608ac66 100644
--- a/lib/Analysis/TargetLibraryInfo.cpp
+++ b/lib/Analysis/TargetLibraryInfo.cpp
@@ -160,8 +160,25 @@
   }
 
   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 @@
       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 @@
       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 @@
     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 @@
     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_log1pl);
-    TLI.setUnavailable(LibFunc_logb);
-    TLI.setUnavailable(LibFunc_logbf);
-    TLI.setUnavailable(LibFunc_logbl);
-    TLI.setUnavailable(LibFunc_nearbyint);
+    TLI.setUnavailable(LibFunc_log2f);
+    if (!hasPartialFloat || !hasPartialC99)
+      TLI.setUnavailable(LibFunc_logbf);
     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);
+
+    // 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_log2l);
+    TLI.setUnavailable(LibFunc_logbl);
+    TLI.setUnavailable(LibFunc_nearbyintl);
+    TLI.setUnavailable(LibFunc_rintl);
+    TLI.setUnavailable(LibFunc_roundl);
     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);
diff --git a/test/Transforms/InstCombine/double-float-shrink-1.ll b/test/Transforms/InstCombine/double-float-shrink-1.ll
index e3dc6bb..d76c64d 100644
--- a/test/Transforms/InstCombine/double-float-shrink-1.ll
+++ b/test/Transforms/InstCombine/double-float-shrink-1.ll
@@ -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
@@ -10,9 +12,11 @@
 
 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 @@
 ; 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 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 @@
 ; 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 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 @@
 ; 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 @@
 ; 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 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 @@
 ; 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 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 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 @@
 ; 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 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 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 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 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 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 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 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 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 @@
 ; 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
diff --git a/test/Transforms/InstCombine/double-float-shrink-2.ll b/test/Transforms/InstCombine/double-float-shrink-2.ll
index d509953..76e497b 100644
--- a/test/Transforms/InstCombine/double-float-shrink-2.ll
+++ b/test/Transforms/InstCombine/double-float-shrink-2.ll
@@ -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_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_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_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
diff --git a/test/Transforms/InstCombine/pow-1.ll b/test/Transforms/InstCombine/pow-1.ll
index 85f61b8..91b5cf9 100644
--- a/test/Transforms/InstCombine/pow-1.ll
+++ b/test/Transforms/InstCombine/pow-1.ll
@@ -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 @@
 
 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 <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 <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 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 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 @@
 ; 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 @@
 ; 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 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 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 @@
 ; 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 @@
 ; 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 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 <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 <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 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 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 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 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 <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 <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 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 @@
 ; 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 @@
 ; 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 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 @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 @@
 ; 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 @@
 ; 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 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 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 @@
   %retval = call double @pow(double 10.0, double %x)
   ret double %retval
 }
-
-; CHECK: attributes [[NUW_RO]] = { nounwind readonly }
diff --git a/test/Transforms/InstCombine/win-math.ll b/test/Transforms/InstCombine/win-math.ll
index 4f774e5..38ed949 100644
--- a/test/Transforms/InstCombine/win-math.ll
+++ b/test/Transforms/InstCombine/win-math.ll
@@ -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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 
 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