Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia llvm function signature when using arrays

When looking at the LLVM IR that the julia compiler generates (using code_llvm) I noticed something strange in the function signature when using arrays as arguments. Let me give an example:

function test(a,b,c)
    return nothing
end

(This is a useless example, but the results are the same with other functions, the resulting IR of this example is just less cluttered)

Using code_llvm(test, (Int,Int,Int)), I get the following output:

; Function Attrs: sspreq
define void @julia_test14855(i64, i64, i64) #2 {
top:
  ret void, !dbg !366
}

Using code_llvm(test, (Array{Int},Array{Int},Array{Int})), I get an (at least for me) unexpected result:

; Function Attrs: sspreq
define %jl_value_t* @julia_test14856(%jl_value_t*, %jl_value_t**, i32) #2 {
top:
  %3 = icmp eq i32 %2, 3, !dbg !369
  br i1 %3, label %ifcont, label %else, !dbg !369

else:                                             ; preds = %top
  call void @jl_error(i8* getelementptr inbounds ([26 x i8]* @_j_str0, i64 0, i64 0)), !dbg !369
  unreachable, !dbg !369

ifcont:                                           ; preds = %top
  %4 = load %jl_value_t** inttoptr (i64 36005472 to %jl_value_t**), align 32, !dbg !370
  ret %jl_value_t* %4, !dbg !370
}

Why is the signature of the llvm function not just listing the 3 variables as i64* or something like that? And why doesn't the function return void anymore?

like image 814
PieterV Avatar asked May 31 '26 20:05

PieterV


1 Answers

Why is the signature of the llvm function not just listing the 3 variables as i64*

This signature is the generic Julia calling convention (because, as @ivarne mentioned, the types are incomplete).

@julia_test14856(%jl_value_t*, %jl_value_t**, i32) arguments are:

  1. pointer to the function closure
  2. pointers to boxed arguments (jl_value_t is basic box type)
  3. number of arguments

The signature @ivarne shows is the specialized calling convention. Arguments are still passed boxed, but argument type and count are known already (and the function closure is unnecessary because it is already specialized).

About the output of your example function, this section checks the number of arguments (if not 3 -> goto label else:):

top:
  %3 = icmp eq i32 %2, 3, !dbg !369
  br i1 %3, label %ifcont, label %else, !dbg !369

This section returns the error:

else:                                             ; preds = %top
  call void @jl_error(i8* getelementptr inbounds ([26 x i8]* @_j_str0, i64 0, i64 0)), !dbg !369
  unreachable, !dbg !369

Finally, the default case goes to this line which pulls the value for nothing stored in address 36005472 (in @ivarne version, this is guaranteed, so can return void directly).

%4 = load %jl_value_t** inttoptr (i64 36005472 to %jl_value_t**), align 32, !dbg !370

like image 68
Isaiah Norton Avatar answered Jun 02 '26 20:06

Isaiah Norton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!