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, ALT) \ + extern "C" { \ + TYP inline_##SYM(TYP _X) { return (TYP)ALT(_X); } \ + } +#define INLINE_DEF_SYMBOL2(TYP, SYM, ALT) \ + extern "C" { \ + TYP inline_##SYM(TYP _X, TYP _Y) { return (TYP)ALT(_X, _Y); } \ + } +#endif + #include "explicit_symbols.inc" #undef EXPLICIT_SYMBOL #undef EXPLICIT_SYMBOL2 +#undef INLINE_DEF_SYMBOL +#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, ALT) \ + if (!strcmp(symbolName, #SYM)) return (void*)&inline_##SYM; + #define INLINE_DEF_SYMBOL2(TYP, SYM, ALT) INLINE_DEF_SYMBOL1(TYP, SYM, ALT) + #endif + { #include "explicit_symbols.inc" } #undef EXPLICIT_SYMBOL #undef EXPLICIT_SYMBOL2 + #undef INLINE_DEF_SYMBOL + #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,30 @@ /* msvcrt */ #if defined(_MSC_VER) EXPLICIT_SYMBOL2(alloca, _alloca_probe) + +#ifdef _M_IX86 +#define INLINE_DEF_FLOAT_VERSION(SYM, ARGC) INLINE_DEF_SYMBOL##ARGC(float, SYM##f, SYM) + INLINE_DEF_FLOAT_VERSION(acos, 1) + INLINE_DEF_FLOAT_VERSION(asin, 1) + INLINE_DEF_FLOAT_VERSION(atan, 1) + INLINE_DEF_FLOAT_VERSION(atan2, 2) + INLINE_DEF_FLOAT_VERSION(ceil, 1) + INLINE_DEF_FLOAT_VERSION(copysign, 2) + INLINE_DEF_FLOAT_VERSION(cos, 1) + INLINE_DEF_FLOAT_VERSION(cosh, 1) + INLINE_DEF_FLOAT_VERSION(exp, 1) + INLINE_DEF_FLOAT_VERSION(floor, 1) + INLINE_DEF_FLOAT_VERSION(fmin, 2) + INLINE_DEF_FLOAT_VERSION(fmax, 2) + INLINE_DEF_FLOAT_VERSION(fmod, 2) + INLINE_DEF_FLOAT_VERSION(log, 1) + INLINE_DEF_FLOAT_VERSION(pow, 2) + INLINE_DEF_FLOAT_VERSION(sin, 1) + INLINE_DEF_FLOAT_VERSION(sinh, 1) + INLINE_DEF_FLOAT_VERSION(sqrt, 1) + INLINE_DEF_FLOAT_VERSION(tan, 1) + INLINE_DEF_FLOAT_VERSION(tanh, 1) +#undef INLINE_DEF_FLOAT_VERSION +#endif + #endif Index: test/CodeGen/X86/win_frem.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/win_frem.ll @@ -0,0 +1,17 @@ +; This unit test tests LLI.exe crashes on Windows\X86 when certain single precession +; floating point intrinsics are used +; +; RUN: lli %s + +target triple = "i686-pc-win32" + +declare i16 @llvm.convert.to.fp16.f32(float %a) +@flt = internal global float 12.0e+0 + +define i16 @main() { + %flt = load float* @flt + %float2 = frem float 12.0, 6.0 + %i16 = call i16 @llvm.convert.to.fp16.f32(float %float2) + + ret i16 %i16 +}