Index: lib/Support/Windows/DynamicLibrary.inc =================================================================== --- lib/Support/Windows/DynamicLibrary.inc +++ lib/Support/Windows/DynamicLibrary.inc @@ -115,10 +115,28 @@ extern "C" { extern void *SYM; } #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO) +#ifdef _M_IX86 +// Win32 on x86 implements certain single-precision math functions as macros. +// These functions are not exported by the DLL, but will still be needed +// for symbol-resolution by the JIT loader. Therefore, this Support libray +// provides helper functions with the same implementation. + +#define INLINE_DEF_SYMBOL1(TYP, SYM) \ + extern "C" { \ + TYP inline_##SYM(TYP _X) { return SYM(_X); } \ + } +#define INLINE_DEF_SYMBOL2(TYP, SYM) \ + extern "C" { \ + TYP inline_##SYM(TYP _X, TYP _Y) { return SYM(_X, _Y); } \ + } +#endif + #include "explicit_symbols.inc" #undef EXPLICIT_SYMBOL #undef EXPLICIT_SYMBOL2 +#undef INLINE_DEF_SYMBOL1 +#undef INLINE_DEF_SYMBOL2 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { SmartScopedLock Lock(*SymbolsMutex); @@ -147,17 +165,24 @@ #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \ if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO; + #ifdef _M_IX86 + #define INLINE_DEF_SYMBOL1(TYP, SYM) \ + if (!strcmp(symbolName, #SYM)) return (void*)&inline_##SYM; + #define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM) + #endif + { #include "explicit_symbols.inc" } #undef EXPLICIT_SYMBOL #undef EXPLICIT_SYMBOL2 + #undef INLINE_DEF_SYMBOL1 + #undef INLINE_DEF_SYMBOL2 return 0; } - void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { if (!isValid()) return NULL; @@ -166,5 +191,4 @@ return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName); } - } Index: lib/Support/Windows/explicit_symbols.inc =================================================================== --- lib/Support/Windows/explicit_symbols.inc +++ lib/Support/Windows/explicit_symbols.inc @@ -63,4 +63,32 @@ /* msvcrt */ #if defined(_MSC_VER) EXPLICIT_SYMBOL2(alloca, _alloca_probe) + +#ifdef _M_IX86 +#define INLINE_DEF_FLOAT_SYMBOL(SYM, ARGC) INLINE_DEF_SYMBOL##ARGC(float, SYM) + INLINE_DEF_FLOAT_SYMBOL(acosf, 1) + INLINE_DEF_FLOAT_SYMBOL(asinf, 1) + INLINE_DEF_FLOAT_SYMBOL(atanf, 1) + INLINE_DEF_FLOAT_SYMBOL(atan2f, 2) + INLINE_DEF_FLOAT_SYMBOL(ceilf, 1) +#if (_MSC_VER==1800) + INLINE_DEF_FLOAT_SYMBOL(copysignf, 2) +#endif + INLINE_DEF_FLOAT_SYMBOL(cosf, 1) + INLINE_DEF_FLOAT_SYMBOL(coshf, 1) + INLINE_DEF_FLOAT_SYMBOL(expf, 1) + INLINE_DEF_FLOAT_SYMBOL(floorf, 1) + INLINE_DEF_FLOAT_SYMBOL(fminf, 2) + INLINE_DEF_FLOAT_SYMBOL(fmaxf, 2) + INLINE_DEF_FLOAT_SYMBOL(fmodf, 2) + INLINE_DEF_FLOAT_SYMBOL(logf, 1) + INLINE_DEF_FLOAT_SYMBOL(powf, 2) + INLINE_DEF_FLOAT_SYMBOL(sinf, 1) + INLINE_DEF_FLOAT_SYMBOL(sinhf, 1) + INLINE_DEF_FLOAT_SYMBOL(sqrtf, 1) + INLINE_DEF_FLOAT_SYMBOL(tanf, 1) + INLINE_DEF_FLOAT_SYMBOL(tanhf, 1) +#undef INLINE_DEF_FLOAT_SYMBOL +#endif + #endif Index: test/ExecutionEngine/win-frem.ll =================================================================== --- /dev/null +++ test/ExecutionEngine/win-frem.ll @@ -0,0 +1,22 @@ +; LLI.exe used to crash on Windows\X86 when certain single precession +; floating point intrinsics (defined as macros) are used. +; This unit test guards against the failure. +; +; RUN: lli %s > /dev/null + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-win32" + +@flt = internal global float 12.0e+0 +@str = internal constant [18 x i8] c"Double value:%f \0A\00" + +declare i32 @printf(i8* nocapture, ...) nounwind + +define i16 @main() { + %flt = load float* @flt + %float2 = frem float %flt, 5.0 + %double1 = fpext float %float2 to double + %yo = call i32(i8*, ...)* @printf( i8* getelementptr ([18 x i8]* @str, i32 0, i64 0), double %double1 ) + + ret i16 0 +}