Skip to content

Commit 84021a2

Browse files
vchuravymaleadt
andauthored
Pass actually pointer typed things to printf (#302)
Co-authored-by: Tim Besard <tim.besard@gmail.com>
1 parent 8fa9bd9 commit 84021a2

File tree

1 file changed

+39
-2
lines changed

1 file changed

+39
-2
lines changed

lib/intrinsics/src/printf.jl

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,55 @@ end
3838
llvm_f, _ = create_function(T_int32, param_types)
3939
mod = LLVM.parent(llvm_f)
4040

41-
# generate IR
4241
IRBuilder() do builder
4342
entry = BasicBlock(llvm_f, "entry")
4443
position!(builder, entry)
4544

45+
# `printf` needs to be invoked very specifically, e.g., the format string needs
46+
# to be a pointer to a string, and arguments need to match exactly what is
47+
# expected by the format string, so we cannot rely on how the arguments to this
48+
# function have been passed in (by `llvmcall`).
49+
T_actual_args = LLVMType[]
50+
actual_args = LLVM.Value[]
51+
for (_, (arg, argtyp)) in enumerate(zip(parameters(llvm_f), arg_types))
52+
if argtyp <: LLVMPtr
53+
# passed as i8*
54+
T,AS = argtyp.parameters
55+
actual_typ = LLVM.PointerType(convert(LLVMType, T), AS)
56+
actual_arg = bitcast!(builder, arg, actual_typ)
57+
elseif argtyp <: Ptr
58+
T = eltype(argtyp)
59+
if T === Nothing
60+
T = Int8
61+
end
62+
actual_typ = LLVM.PointerType(convert(LLVMType, T))
63+
actual_arg = if value_type(arg) isa LLVM.PointerType
64+
# passed as i8* or ptr
65+
bitcast!(builder, arg, actual_typ)
66+
else
67+
# passed as i64
68+
inttoptr!(builder, arg, actual_typ)
69+
end
70+
elseif argtyp <: Bool
71+
# passed as i8
72+
T = eltype(argtyp)
73+
actual_typ = LLVM.Int1Type()
74+
actual_arg = trunc!(builder, arg, actual_typ)
75+
else
76+
actual_typ = convert(LLVMType, argtyp)
77+
actual_arg = arg
78+
end
79+
push!(T_actual_args, actual_typ)
80+
push!(actual_args, actual_arg)
81+
end
82+
4683
str = globalstring_ptr!(builder, String(fmt); addrspace=AS.Constant)
4784

4885
# invoke printf and return
4986
printf_typ = LLVM.FunctionType(T_int32, [T_pint8]; vararg=true)
5087
printf = LLVM.Function(mod, "printf", printf_typ)
5188
push!(function_attributes(printf), EnumAttribute("nobuiltin"))
52-
chars = call!(builder, printf_typ, printf, [str, parameters(llvm_f)...])
89+
chars = call!(builder, printf_typ, printf, [str, actual_args...])
5390

5491
ret!(builder, chars)
5592
end

0 commit comments

Comments
 (0)