declare half @air.sincos.f16(half, half* nocapture writeonly)
vs
declare half @air.sincos.f16(half, i64)
So the problem is we aren't passing a pointer, but an i64. This can be fixed by using @typed_ccall from LLVM.jl instead of plain ccall.
It's also probably useful to add those annotations to
|
function annotate_air_intrinsics!(@nospecialize(job::CompilerJob), mod::LLVM.Module) |
|
changed = false |
|
|
|
for f in functions(mod) |
|
isdeclaration(f) || continue |
|
fn = LLVM.name(f) |
|
|
|
attrs = function_attributes(f) |
|
function add_attributes(names...) |
|
for name in names |
|
if LLVM.version() >= v"16" && name in ["argmemonly", "inaccessiblememonly", |
|
"inaccessiblemem_or_argmemonly", |
|
"readnone", "readonly", "writeonly"] |
|
# XXX: workaround for changes from https://reviews.llvm.org/D135780 |
|
continue |
|
end |
|
push!(attrs, EnumAttribute(name, 0)) |
|
end |
|
changed = true |
|
end |
|
|
|
# synchronization |
|
if fn == "air.wg.barrier" || fn == "air.simdgroup.barrier" |
|
add_attributes("nounwind", "convergent") |
|
|
|
# atomics |
|
elseif match(r"air.atomic.(local|global).load", fn) !== nothing |
|
# TODO: "memory(argmem: read)" on LLVM 16+ |
|
add_attributes("argmemonly", "readonly", "nounwind") |
|
elseif match(r"air.atomic.(local|global).store", fn) !== nothing |
|
# TODO: "memory(argmem: write)" on LLVM 16+ |
|
add_attributes("argmemonly", "writeonly", "nounwind") |
|
elseif match(r"air.atomic.(local|global).(xchg|cmpxchg)", fn) !== nothing |
|
# TODO: "memory(argmem: readwrite)" on LLVM 16+ |
|
add_attributes("argmemonly", "nounwind") |
|
elseif match(r"^air.atomic.(local|global).(add|sub|min|max|and|or|xor)", fn) !== nothing |
|
# TODO: "memory(argmem: readwrite)" on LLVM 16+ |
|
add_attributes("argmemonly", "nounwind") |
|
end |
|
end |
|
|
|
return changed |
|
end |
Originally posted by @maleadt in #530
Originally posted by @maleadt in #530