Skip to content

Instantly share code, notes, and snippets.

@tshort
Last active October 12, 2019 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tshort/96bbf6cdd52459130b6a02a586455a26 to your computer and use it in GitHub Desktop.
Save tshort/96bbf6cdd52459130b6a02a586455a26 to your computer and use it in GitHub Desktop.
Attempt to replace `inttoptr` with a direct call

I'm trying to replace inttoptr uses that happen when ccalls are generated. I've gotten as far as drilling down to the operand with inttoptr, but I can't figure out the next step.

using LLVM
ctx = Context()

mod = parse(LLVM.Module,  """
    define double @fun() {
    top:
      %0 = call double inttoptr (i32 -137186077 to double ()*)()
      ret double %0
    }
    """, ctx)

inst = first(instructions(first(blocks(functions(mod)["fun"]))))
ops = operands(inst)
op = first(ops)

There are not many methods that can operate on the operand, and I don't see any way to check that it is an inttoptr.

julia> inst = first(instructions(first(blocks(functions(mod)["fun"]))))
  %0 = call double inttoptr (i32 -137186077 to double ()*)()

julia> ops = operands(inst)
LLVM.UserOperandSet(  %0 = call double inttoptr (i32 -137186077 to double ()*)())

julia> op = first(ops)
double ()* inttoptr (i32 -137186077 to double ()*)

julia> filter!(s->!occursin("builder", s), string.(methodswith(typeof(op),supertypes=true)))
14-element Array{String,1}:
 "condition!(br::Instruction, cond::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/instructions.jl:153"
 "context(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:54"
 "initializer!(gv::GlobalVariable, val::LLVM.Constant) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/constant.jl:223"
 "isconstant(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:50"
 "isnull(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/constant.jl:7"
 "isundef(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:52"
 "llvmtype(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:36"
 "name(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:38"
 "name!(val::Value, name::String) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:39"
 "operands(user::LLVM.User) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/user.jl:13"
 "replace_uses!(old::Value, new::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:46"
 "show(io::IO, val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:42"
 "uses(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:87"
 "setindex!(iter::LLVM.UserOperandSet, val::Value, i) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/user.jl:20"

I can get the address of the pointer with, but I can't tell how to check whether it's an inttoptr.

julia> first(operands(op))
i32 -137186077

There is LLVM.IntToPtrInst, but that is an instruction, and what I'm trying to detect is part of an operand.

@tshort
Copy link
Author

tshort commented Aug 29, 2019

@tshort
Copy link
Author

tshort commented Oct 12, 2019

Another way is with opcode(x) == LLVM.API.LLVMIntToPtr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment