#4992: LLVM trashes registers for primitive calls
-------------------------------+--------------------------------------------
Reporter: scpmw | Owner: davidterei@…
Type: bug | Status: new
Priority: normal | Component: Compiler (LLVM)
Version: 7.1 | Keywords:
Testcase: | Blockedby:
Os: Linux | Blocking:
Architecture: x86_64 (amd64) | Failure: Runtime crash
-------------------------------+--------------------------------------------
When calling, the LLVM backend will generate code that sets a number
of global registers to "undefined" to prevent LLVM from saving them. I
suppose that's a good idea for C calls, but for primitive calls it is
unnecessary, even dangerous. "tan 0.5" will have the backend generate code
like follows:
{{{
...
store i64 %ln1zX, i64* %ln1zZ
store i64 undef, i64* %R3_Var
store i64 undef, i64* %R4_Var
store i64 undef, i64* %R5_Var
store i64 undef, i64* %R6_Var
store float undef, float* %F1_Var
store float undef, float* %F2_Var
store float undef, float* %F3_Var
store float undef, float* %F4_Var
store double undef, double* %D1_Var
store double undef, double* %D2_Var
%ln1A0 = call ccc double (double)* @tan( double 0x3FE0000000000000 )
nounwind
...
}}}
A few lines later, these registers are then read again, with LLVM
probably assuming that the read results don't matter, as it can deduce
that "tan" can't have written them.
I discovered this when investigating why my programs using additional
primitive operations kept crashing. Removing the trashing for
primitive calls seems to fix the problem nicely, patch attached.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4992>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs