I’m running Julia 0.6.3 (downloaded from the website) on macOS 10.13.5. In the REPL, I can use code_llvm
to see how Julia lowers the +
operator for integers:
julia> code_llvm(+, (Int, Int))
define i64 @"jlsys_+_60775"(i64, i64) #0 !dbg !5 {
top:
%2 = add i64 %1, %0
ret i64 %2
}
All good: it’s generating an LLVM function that adds two unboxed 64-bit integers, and returns an unboxed 64-bit integer as the result. Let’s see what the machine code for that looks like:
julia> code_native(+, (Int, Int), :intel)
.section __TEXT,__text,regular,pure_instructions
Filename: int.jl
push ebp
dec eax
mov ebp, esp
Source line: 32
dec eax
lea eax, [edi + esi]
pop ebp
ret
Source line: 32
nop
nop
nop
nop
nop
nop
What in the world is going on here? First off, eax
gets decremented twice, needlessly. Second, since we’re doing 64-bit addition, shouldn’t it be lea rax, [rdi + rsi]
?
This is just limited to the assembly dump, though. Actual 64-bit addition works fine, which means that weirdly, the results of code_native
are not representative of the code Julia is actually executing. So what gives? Am I using code_native
incorrectly? Is this a bug? Should I just pretend every exx
is an rxx
? And even if I did that substitution, what’s with the clearly needless dec
instructions? Are they some kind of padding for alignment?
I should note that this issue applies to every code_native
dump I’ve looked at; I isolated the +
example because it was so simple.