LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 5053 - [windows JIT] incorrect 'frem' behaviour with floats
Summary: [windows JIT] incorrect 'frem' behaviour with floats
Status: RESOLVED FIXED
Alias: None
Product: new-bugs
Classification: Unclassified
Component: new bugs (show other bugs)
Version: trunk
Hardware: PC Windows NT
: P normal
Assignee: Swaroop Sridhar
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-09-25 14:10 PDT by Jack
Modified: 2014-11-13 18:39 PST (History)
4 users (show)

See Also:
Fixed By Commit(s):


Attachments
Fix for using floating point intrinsics defined as macros (3.53 KB, patch)
2014-09-17 16:22 PDT, Swaroop Sridhar
Details
Fix for using floating point intrinsics defined as macros (6.10 KB, patch)
2014-10-02 10:56 PDT, Swaroop Sridhar
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jack 2009-09-25 14:10:30 PDT
Use following test case:

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 void @main() {
  %flt = load float* @flt
  %float2 = frem float %flt, 5.0
  %double1 = fpext float %float2 to double
  %yo = call i32(i8* nocapture, ...)* @printf( i8* getelementptr ([18 x i8]* @str, i32 0, i64 0), double %double1 )

  ret void
}

Running with JIT:
Stack dump:
0.      Program arguments: lli test.bc
00000000 (0x41400000 0x40A00000 0x00FEFA40 0x0008D3B1) <unknown module>
00FF003B (0x01A1F6B4 0x01BFB4B0 0x01A1F784 0x5C1E1B36) <unknown module>
0033EA9C (0x01BFB4B0 0x00D81B5C 0x00FE1D20 0x5C1E15EA), llvm::ExecutionEngine::runFunctionAsMain()+0940 bytes(s), e:\external\llvm\lib\executionengine\executionengine.cpp, line 387+0030 byte(s)
00081894 (0x00000002 0x00FE7FD8 0x00FE1D20 0x5C1E155A), main()+2196 bytes(s), e:\external\llvm\tools\lli\lli.cpp, line 218+0064 byte(s)
00A6BFB8 (0x01A1F9D4 0x776F3677 0x7EFDE000 0x01A1FA14), __tmainCRTStartup()+0424 bytes(s), f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c, line 586+0025 byte(s)
00A6BDEF (0x7EFDE000 0x01A1FA14 0x77C99D72 0x7EFDE000), mainCRTStartup()+0015 bytes(s), f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c, line 403
776F3677 (0x7EFDE000 0x7623FA65 0x00000000 0x00000000), BaseThreadInitThunk()+0018 bytes(s)
77C99D72 (0x00A6BDE0 0x7EFDE000 0x00000000 0x00000000), RtlInitializeExceptionChain()+0099 bytes(s)
77C99D45 (0x00A6BDE0 0x7EFDE000 0x00000000 0x00000000), RtlInitializeExceptionChain()+0054 bytes(s)

Running with interpreter:
Double value:2.000000

But if I change floats to doubles - all is OK:

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 double 12.0e+0
@str = internal constant [18 x i8] c"Double value:%f \0A\00"

declare i32 @printf(i8* nocapture, ...) nounwind

define void @main() {
  %flt = load double* @flt
  %float2 = frem double %flt, 5.0
  %yo = call i32(i8* nocapture, ...)* @printf( i8* getelementptr ([18 x i8]* @str, i32 0, i64 0), double %float2 )

  ret void
}
Comment 1 Chris Lattner 2009-09-27 13:36:48 PDT
This also works fine for me on macos.  This must be a windows specific jit problem.
Comment 2 Jack 2009-09-27 14:00:02 PDT
I tested it on Windows 7 x64 and Server 2008 x64 ( using 32-bit versions of llvm tools )
Comment 3 Jack 2009-10-18 06:06:51 PDT
I also experienced same problems with floating point intrinsics - their 'float' versions perform incorrectly. For example:

this will crash runtime:
 %flt = load float* ...
 ... = call float @llvm.cos.f32(float %flt)

but with doubles all is OK:
 %flt = load double* ...
 ... = call double @llvm.cos.f64(double %flt)
Comment 4 Anton Korobeynikov 2009-11-03 01:16:53 PST
See PR5052 for some information
Comment 5 Swaroop Sridhar 2014-09-17 16:22:52 PDT
Created attachment 13048 [details]
Fix for using floating point intrinsics defined as macros

The here problem is that 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. The DLL does contain the definitions for the intrinsics, but the symbols are not exported (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 helper functions are exactly the same as the inline definitions in math.h. The address of these helper functions are used to patch up the CALL instruction at load time.
Comment 6 Swaroop Sridhar 2014-10-02 10:56:59 PDT
Created attachment 13115 [details]
Fix for using floating point intrinsics defined as macros

Added a Windows specific test case in Codegen\x86
Comment 7 Lang Hames 2014-10-13 14:46:53 PDT
Hi Swaroop,

The old JIT is deprecated in 3.5, and has been removed entirely on the development branch of LLVM. Could you try this with MCJIT and see if your problem reproduces there?

Just run 'lli -use-mcjit testcase.ll' on 3.5, or simply 'lli testcase.ll' on the development branch where MCJIT is the default.

Cheers,
Lang.
Comment 8 Swaroop Sridhar 2014-10-24 18:21:08 PDT
Hi Lang,

Is the MCJit supported on Windows? 

I tried the following using lli MCJIT (on the development branch of LLVM), but LLI failed with the following error:

Debug\bin\lli.exe  llvm\test\ExecutionEngine\hello.ll
LLVM ERROR: Incompatible object format!
Stack dump:
0.      Program arguments: Debug\bin\lli.exe D:\enlist\JIT\llvm\test\ExecutionEngine\hello.ll


Thanks,
Swaroop.
Comment 9 Swaroop Sridhar 2014-11-13 18:39:52 PST
 r221947 - Fix symbol resolution of floating point libc builtins in MCJIT