# Julia references at LLVM IR level

**URL:** <https://discourse.julialang.org/t/julia-references-at-llvm-ir-level/78870>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 1, 2022, 2:18pm UTC](https://discourse.julialang.org/t/julia-references-at-llvm-ir-level/78870 "2022-04-01T14:18:50Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![knlv.ok](https://avatars.discourse-cdn.com/v4/letter/k/b77776/32.png) [@knlv.ok](https://discourse.julialang.org/u/knlv.ok)\
**Post date:** [April 1, 2022, 2:18pm UTC](https://discourse.julialang.org/t/julia-references-at-llvm-ir-level/78870/1 "2022-04-01T14:18:50Z")

</div>

Hello  
I’m coming to ask for your help today, because I have the following problem:  
As a toy example, I have implemented a multiplication function below:

```julia
function mult!(res::Ref{Int16},a::Int16,b::Int16)
    res[]=a*b
    return nothing
end

```

In which, I am using an Int16 reference pass as a parameter to my function to store the result (this is required for my example).  
Unfortunately at LLVM IR level in the function signature the reference is typed as ({}\* nonnull align 2 dereferenceable(2) %0):

```julia
define void @julia_mult_276({}* nonnull align 2 dereferenceable(2) %0, i16 signext %1, i16 signext %2) #0 {
top:

   %3 = mul i16 %1, %2
   %4 = bitcast {}* %0 to i16*
   store i16 %3, i16* %4, align 2
  ret void
}

```

But I need to be able to generate an LLVM IR by using Julia where references are typed as pointers to the type of the reference in the functions signature. I will inject this IR later in another application.  
So based on the example of my multiplication function above, I would like to have the following LLVM IR level result:

```julia
define void @julia_mult_276(i16* %0, i16 signext %1, i16 signext %2) #0 {
top:

   %3 = mul i16 %1, %2
   store i16 %3, i16* %0, align 2
  ret void
}

```

With the reference Int16 typed how this i16\* %0 in the signature.  
Is there any solution to force the typing in the signature at LLVM IR level by using flags or others at Julia code level ?

Thanks in advance for your help.

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [April 5, 2022, 12:05pm UTC](https://discourse.julialang.org/t/julia-references-at-llvm-ir-level/78870/2 "2022-04-05T12:05:31Z")

</div>

`Ref` is a Julia object. Use regular `Ptr`s if you want pointers:

```julia
julia> mult!(res,a,b) = unsafe_store!(res, a*b)
mult! (generic function with 1 method)

julia> code_llvm(mult!, Tuple{Ptr{Int16},Int16,Int16})
; @ REPL[1]:1 within `mult!`
define i64 @"julia_mult!_143"(i64 zeroext %0, i16 signext %1, i16 signext %2) #0 {
top:
; ┌ @ int.jl:88 within `*`
   %3 = mul i16 %2, %1
; └
; ┌ @ pointer.jl:118 within `unsafe_store!` @ pointer.jl:118
   %4 = inttoptr i64 %0 to i16*
   store i16 %3, i16* %4, align 1
; └
  ret i64 %0
}

```

The pointers are passed as integers. If you want actual pointers, use `Core.LLVMPtr{T,AS}` (but note that `unsafe_store!` etc doesn’t work on those by default, use LLVM.jl if you need that kind of functionality). Also note that those pointers will still be untyped, but LLVM is moving towards opaque pointers anyway.

```julia
julia> using LLVM

julia> mult!(res,a,b) = unsafe_store!(res, a*b)
mult! (generic function with 1 method)

julia> code_llvm(mult!, Tuple{Core.LLVMPtr{Int16,0},Int16,Int16})
; @ REPL[2]:1 within `mult!`
define void @"julia_mult!_452"(i8* %0, i16 signext %1, i16 signext %2) #0 {
top:
; ┌ @ int.jl:88 within `*`
   %3 = mul i16 %2, %1
; └
; ┌ @ /Users/tim/Julia/pkg/LLVM/src/interop/pointer.jl:84 within `unsafe_store!` @ /Users/tim/Julia/pkg/LLVM/src/interop/pointer.jl:84 @ /Users/tim/Julia/pkg/LLVM/src/interop/pointer.jl:84
; │┌ @ /Users/tim/Julia/pkg/LLVM/src/interop/pointer.jl:44 within `pointerset`
; ││┌ @ /Users/tim/Julia/pkg/LLVM/src/interop/pointer.jl:44 within `macro expansion` @ /Users/tim/Julia/pkg/LLVM/src/interop/base.jl:40
     %4 = bitcast i8* %0 to i16*
     store i16 %3, i16* %4, align 1
; └└└
  ret void
}

```
