id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
4992,LLVM trashes registers for primitive calls,scpmw,davidterei@gmail.com,"
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.
",bug,closed,normal,,Compiler (LLVM),7.1,invalid,,,Linux,x86_64 (amd64),Runtime crash,,,,,
