[llvm] r221947 - Fix symbol resolution of floating point libc builtins in MCJIT

Lang Hames lhames at gmail.com
Thu Nov 13 16:04:05 PST 2014


Thanks very much Swaroop! And thanks Reid for the review.

If this fixes  http://llvm.org/PR5053, please go ahead and mark it resolved.

Cheers,
Lang.

On Thu, Nov 13, 2014 at 3:32 PM, Reid Kleckner <reid at kleckner.net> wrote:

> Author: rnk
> Date: Thu Nov 13 17:32:52 2014
> New Revision: 221947
>
> URL: http://llvm.org/viewvc/llvm-project?rev=221947&view=rev
> Log:
> Fix symbol resolution of floating point libc builtins in MCJIT
>
> Fix for LLI failure on Windows\X86: http://llvm.org/PR5053
>
> LLI.exe crashes on Windows\X86 when single precession floating point
> intrinsics like the following are used: acos, asin, atan, atan2, ceil,
> copysign, cos, cosh, exp, floor, fmin, fmax, fmod, log, pow, sin, sinh,
> sqrt, tan, tanh
>
> The above intrinsics are defined as inline-expansions in math.h, and are
> not exported by msvcr120.dll (Win32 API GetProcAddress returns null).
>
> For an FREM instruction, the JIT compiler generates a call to a stub for
> the fmodf() intrinsic, and adds a relocation to fixup at load time. The
> loader searches the libraries for the function, but fails because the
> symbol is not exported. So, the call target remains NULL and the
> execution crashes.
>
> Since the math functions are loaded at JIT/runtime, the JIT can patch
> CALL instruction directly instead of the searching the libraries'
> exported symbols.  However, this fix caused build failures due to
> unresolved symbols like _fmodf at link time.
>
> Therefore, the current fix defines helper functions in the Runtime
> link/load library to perform the above operations.  The address of these
> helper functions are used to patch up the CALL instruction at load time.
>
> Reviewers: lhames, rnk
>
> Reviewed By: rnk
>
> Differential Revision: http://reviews.llvm.org/D5387
>
> Patch by Swaroop Sridhar!
>
> Added:
>     llvm/trunk/test/ExecutionEngine/frem.ll
> Modified:
>     llvm/trunk/lib/Support/Windows/DynamicLibrary.inc
>     llvm/trunk/lib/Support/Windows/explicit_symbols.inc
>
> Modified: llvm/trunk/lib/Support/Windows/DynamicLibrary.inc
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/DynamicLibrary.inc?rev=221947&r1=221946&r2=221947&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Support/Windows/DynamicLibrary.inc (original)
> +++ llvm/trunk/lib/Support/Windows/DynamicLibrary.inc Thu Nov 13 17:32:52
> 2014
> @@ -94,10 +94,24 @@ DynamicLibrary DynamicLibrary::getPerman
>    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<true> Lock(*SymbolsMutex);
> @@ -121,22 +135,32 @@ void* DynamicLibrary::SearchForAddressOf
>      }
>    }
>
> -  #define EXPLICIT_SYMBOL(SYM)                    \
> -    if (!strcmp(symbolName, #SYM)) return (void*)&SYM;
> -  #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO)        \
> -    if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO;
> +#define EXPLICIT_SYMBOL(SYM)
>      \
> +  if (!strcmp(symbolName, #SYM))
>      \
> +    return (void *)&SYM;
> +#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"
> +#include "explicit_symbols.inc"
>    }
>
> -  #undef EXPLICIT_SYMBOL
> -  #undef EXPLICIT_SYMBOL2
> +#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;
> @@ -145,5 +169,4 @@ void *DynamicLibrary::getAddressOfSymbol
>    return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
>  }
>
> -
>  }
>
> Modified: llvm/trunk/lib/Support/Windows/explicit_symbols.inc
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/explicit_symbols.inc?rev=221947&r1=221946&r2=221947&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Support/Windows/explicit_symbols.inc (original)
> +++ llvm/trunk/lib/Support/Windows/explicit_symbols.inc Thu Nov 13
> 17:32:52 2014
> @@ -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
>
> Added: llvm/trunk/test/ExecutionEngine/frem.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/frem.ll?rev=221947&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/frem.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/frem.ll Thu Nov 13 17:32:52 2014
> @@ -0,0 +1,20 @@
> +; 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 | FileCheck %s
> +
> + at flt = internal global float 12.0e+0
> + at str = internal constant [18 x i8] c"Double value: %f\0A\00"
> +
> +declare i32 @printf(i8* nocapture, ...) nounwind
> +
> +define i32 @main() {
> +  %flt = load float* @flt
> +  %float2 = frem float %flt, 5.0
> +  %double1 = fpext float %float2 to double
> +  call i32 (i8*, ...)* @printf(i8* getelementptr ([18 x i8]* @str, i32 0,
> i64 0), double %double1)
> +  ret i32 0
> +}
> +
> +; CHECK: Double value: 2.0
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141113/99800d01/attachment.html>


More information about the llvm-commits mailing list