Skip to content

1.8 regression: isbitstype does not resolve at compile-time #309

Closed
@maleadt

Description

@maleadt

MWE:

using GPUCompiler

module TestRuntime
    # dummy methods
    signal_exception() = return
    malloc(sz) = C_NULL
    report_oom(sz) = return
    report_exception(ex) = return
    report_exception_name(ex) = return
    report_exception_frame(idx, func, file, line) = return
end

struct TestCompilerParams <: AbstractCompilerParams end
GPUCompiler.runtime_module(::CompilerJob{<:Any,TestCompilerParams}) = TestRuntime

function kernel(ptr::Ptr{T}, val) where {T}
    if isbitstype(T)
        unsafe_store!(ptr, val, 1)
    end
    return
end

function main()
    source = FunctionSpec(kernel, Tuple{Ptr{Float32}, Float32})
    target = NativeCompilerTarget()
    params = TestCompilerParams()
    job = CompilerJob(target, source, params)

    JuliaContext() do ctx
        println(GPUCompiler.compile(:llvm, job; ctx)[1])
    end
end

isinteractive() || main()

On 1.9:

define void @_Z16julia_kernel_6353PtrI7Float32ES0_(i64 zeroext %0, float %1) local_unnamed_addr #0 !dbg !5 {
top:
  %2 = load i8, i8* inttoptr (i64 4914551176 to i8*), align 8, !dbg !7, !tbaa !14
  %3 = and i8 %2, 8, !dbg !18
  %.not = icmp eq i8 %3, 0, !dbg !21
  br i1 %.not, label %L7, label %L6, !dbg !13

L6:                                               ; preds = %top
  %4 = inttoptr i64 %0 to float*, !dbg !24
  store float %1, float* %4, align 1, !dbg !24, !tbaa !28
  br label %L7, !dbg !24

L7:                                               ; preds = %L6, %top
  ret void, !dbg !30
}

... which is Really Bad, since it's leaking CPU values into the GPU IR.

For reference, on 1.8:

define void @_Z16julia_kernel_4963PtrI7Float32ES0_(i64 zeroext %0, float %1) local_unnamed_addr #0 !dbg !5 {
top:
  %2 = inttoptr i64 %0 to float*, !dbg !7
  store float %1, float* %2, align 1, !dbg !7, !tbaa !11
  ret void, !dbg !15
}

Enabling inference remarks gives:

┌ Debug: Inference remark during GPU compilation of MethodInstance for isbitstype(::Type{Float32}): [constprop] Disabled by function heuristic
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35
┌ Debug: Inference remark during GPU compilation of MethodInstance for kernel(::Ptr{Float32}, ::Float32): [constprop] Disabled by argument and rettype heuristics
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35
┌ Debug: Inference remark during GPU compilation of MethodInstance for unsafe_store!(::Ptr{Float32}, ::Float32, ::Int64): [constprop] Disabled by argument and rettype heuristics
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35
┌ Debug: Inference remark during GPU compilation of MethodInstance for Int64(::Int64): [constprop] Disabled by argument and rettype heuristics
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35
┌ Debug: Inference remark during GPU compilation of MethodInstance for unsafe_store!(::Ptr{Float32}, ::Float32, ::Int64): [constprop] Disabled by argument and rettype heuristics
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35
┌ Debug: Inference remark during GPU compilation of MethodInstance for unsafe_store!(::Ptr{Float32}, ::Float32, ::Int64): [constprop] Disabled by argument and rettype heuristics
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35
┌ Debug: Inference remark during GPU compilation of MethodInstance for kernel(::Ptr{Float32}, ::Float32): Call result type was widened because the return value is unused
└ @ GPUCompiler ~/Julia/pkg/GPUCompiler/src/utils.jl:35

Const-prop of isbitstype being disabled seems crucial here. I wonder if this has anything to do with the fix to JuliaLang/julia@4846fbb (cc @aviatesk).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions