TheDan64 / inkwell

It's a New Kind of Wrapper for Exposing LLVM (Safely)
https://thedan64.github.io/inkwell/
Apache License 2.0
2.22k stars 217 forks source link

Can't create declaration for intrinsic with a pointer parameter #496

Open kotakotik22 opened 1 month ago

kotakotik22 commented 1 month ago

Describe the Bug Intrinsic::get_declaration (or some other part of inkwell) seems to convert PointerType to a i64 when creating the intrinsic declaration, which doesn't pass llvm's verify, at least when there's a nocapture attribute.

To Reproduce This example tries to get a declaration of the llvm.lifetime.start intrinsic (but doesn't even call it):

let ctx = Context::create();
let module = ctx.create_module("module");
let intrinsic = Intrinsic::find("llvm.lifetime.start").unwrap()
    // create the declaration
    .get_declaration(&module, &[
        ctx.i64_type().as_basic_type_enum(),
        ctx.ptr_type(AddressSpace::default()).as_basic_type_enum()
    ]);

// print the LLVM IR to stderr
module.print_to_stderr();
// attempt to verify (will panic)
module.verify().unwrap()

This generates the following LLVM IR:

; ModuleID = 'module'
source_filename = "module"

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.i64.p0(i64 immarg %0, i64 nocapture %1) #0

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }

Which then throws the following error when verifying: Attribute 'nocapture' applied to incompatible type! ptr @llvm.lifetime.start.i64.p0

Expected Behavior I expected that code to generate a declaration which accepts a i64 and a ptr, and of course that it wouldn't throw a verification error.

LLVM Version:

Desktop: