diff --git a/src/driver.jl b/src/driver.jl index 116e0691..f1f0d539 100644 --- a/src/driver.jl +++ b/src/driver.jl @@ -138,15 +138,9 @@ function codegen(output::Symbol, job::CompilerJob; fn = LLVM.name(f) LLVM.name!(f, "") f′ = LLVM.Function(ir, fn, eltype(llvmtype(f))) - for attr in collect(function_attributes(f)) - push!(function_attributes(f′), attr) - end - for attr in collect(return_attributes(f)) - push!(return_attributes(f′), attr) - end - for i in 1:length(parameters(f)), attr in collect(parameter_attributes(f, i)) - push!(parameter_attributes(f′, i), attr) - end + # copying attributes is broken due to maleadt/LLVM.jl#186, + # but that doesn't matter because `only_entry` is only used for reflection, + # and the emitted code has already been optimized at this point. replace_uses!(f, f′) end end diff --git a/src/gcn.jl b/src/gcn.jl index dcc007a6..c4cbb085 100644 --- a/src/gcn.jl +++ b/src/gcn.jl @@ -43,6 +43,7 @@ end function add_lowering_passes!(job::CompilerJob{GCNCompilerTarget}, pm::LLVM.PassManager) add!(pm, ModulePass("LowerThrowExtra", lower_throw_extra!)) + add!(pm, FunctionPass("FixAllocaAddrspace", fix_alloca_addrspace!)) end function lower_throw_extra!(mod::LLVM.Module) @@ -103,6 +104,33 @@ function lower_throw_extra!(mod::LLVM.Module) end return changed end +function fix_alloca_addrspace!(fn::LLVM.Function) + changed = false + alloca_as = 5 + ctx = context(fn) + + for bb in blocks(fn) + for insn in instructions(bb) + if isa(insn, LLVM.AllocaInst) + ty = llvmtype(insn) + ety = eltype(ty) + addrspace(ty) == alloca_as && continue + + new_insn = nothing + Builder(ctx) do builder + position!(builder, insn) + _alloca = alloca!(builder, ety, name(insn)) + new_insn = addrspacecast!(builder, _alloca, ty) + end + replace_uses!(insn, new_insn) + unsafe_delete!(LLVM.parent(insn), insn) + end + end + end + + return changed +end + function emit_trap!(job::CompilerJob{GCNCompilerTarget}, builder, mod, inst) ctx = context(mod) diff --git a/test/gcn.jl b/test/gcn.jl index 23304fda..d304ff48 100644 --- a/test/gcn.jl +++ b/test/gcn.jl @@ -17,6 +17,17 @@ include("definitions/gcn.jl") @test occursin("amdgpu_kernel", ir) end +@testset "alloca addrspace" begin + function kernel(i) + sink(i) # sink provides an alloca in addrspace 0 + return + end + + ir = sprint(io->gcn_code_llvm(io, kernel, Tuple{Int64}; dump_module=true)) + @test occursin("alloca i64, addrspace(5)", ir) + @test !occursin("alloca i64\n", ir) +end + end ############################################################################################