Skip to content

Instruction does not dominate all uses! error after the bump to LLVM 18 #56909

@nsajko

Description

@nsajko

The bump to LLVM 18 (#54848) is causing crashes for the InlineStrings test suite.

MWE, run an assert build with --check-bounds=yes:

module InlineStrings
    abstract type InlineString <: AbstractString end
    for sz in 256
        nm = Symbol(:String, sz-1)
        nma = Symbol(:InlineString, sz-1)
        macro_nm = Symbol(:inline, sz-1, :_str)
        at_macro_nm = Symbol("@", macro_nm)
        @eval begin
            primitive type $nm <: InlineString $(sz * 8) end
            const $nma = $nm
            macro $macro_nm(ex)
                T = InlineStringType($(sz - 1))
                T(unescape_string(ex))
            end
        end
    end
    Base.promote_rule(::Type{T}, ::Type{String}) where {T <: InlineString} = String
    function addcodeunit(x::T, b::UInt8) where {T <: InlineString}
        len = Base.trunc_int(UInt8, x)
        sz = Base.trunc_int(UInt8, sizeof(T))
        shf = Base.zext_int(Int16, max(0x01, sz - len - 0x01)) << 3
        x = Base.or_int(x, Base.shl_int(Base.zext_int(T, b), shf))
        return Base.add_int(x, Base.zext_int(T, 0x01)), (len + 0x01) >= sz
    end
    for T in (:InlineString255,)
        @eval $T() = Base.zext_int($T, 0x00)
        @eval function $T(x::AbstractString)
            len = ncodeunits(x)
            len < sizeof($T) || stringtoolong($T, len)
            y = $T()
            for i = 1:len
                @inbounds y, _ = addcodeunit(y, codeunit(x, i))
            end
            return y
        end
    end
    @noinline stringtoolong(T, n) = throw(ArgumentError("string too large ($n) to convert to $T"))
    function InlineStringType(n::Integer)
        InlineString255
    end
    InlineString(x::AbstractString)::InlineString255 = (InlineStringType(ncodeunits(x)))(x)
    macro inline_str(ex)
        InlineString(unescape_string(ex))
    end
    function inlinestrings(itr::T) where {T}
        IS = Base.IteratorSize(T)
        state = iterate(itr)
        state === nothing && return []
        y, st = state
        x = y === missing ? missing : sizeof(y) < 256 ? InlineString(y) : String(y)
        eT = typeof(x)
        res = allocate(eT, IS, itr)
        i = 1
        set!(IS, res, x, i)
        i += 1
        return _inlinestrings(itr, st, eT, IS, res, i)
    end
    const HasLength = Union{Base.HasShape, Base.HasLength}
    allocate(::Type{T}, ::HasLength, itr) where {T} = Vector{T}(undef, length(itr))
    set!(::HasLength, res, x, i) = setindex!(res, x, i)
    function _inlinestrings(itr, st, ::Type{eT}, IS, res, i) where {eT}
        while true
            state = iterate(itr, st)
            state === nothing && break
            y, st = state
            if y === missing && eT >: Missing
                set!(IS, res, missing, i)
            elseif y !== missing && eT !== Missing && (sizeof(y) < sizeof(eT) || sizeof(y) == 1)
                set!(IS, res, Base.nonmissingtype(eT)(y), i)
            else
                x = y === missing ? missing : sizeof(y) < 256 ? InlineString(y) : String(y)
                new_eT = promote_type(typeof(x), eT)
                newres = allocate(new_eT, Base.HasLength(), res)
                copyto!(newres, 1, res, 1, i - 1)
                set!(IS, newres, x, i)
                return _inlinestrings(itr, st, new_eT, IS, newres, i + 1)
            end
            i += 1
        end
        return res
    end
end
InlineStrings.inlinestrings(["a"^128])

This is the beginning of the error message:

Instruction does not dominate all uses!
  %141 = call token (...) @llvm.julia.gc_preserve_begin(ptr addrspace(10) nonnull %138), !dbg !211
  call void @llvm.julia.gc_preserve_end(token %141), !dbg !211
Failed to verify function 'julia_unsafe_copyto!_164', dumping entire module!

; ModuleID = 'unsafe_copyto!'
source_filename = "unsafe_copyto!"

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviorcompiler:llvmFor issues that relate to LLVMregressionRegression in behavior compared to a previous versionregression 1.12Regression in the 1.12 release

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions