From 5230d27de950165475892acfabded59713c8cd3e Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Fri, 16 Aug 2024 03:33:22 -0400 Subject: [PATCH 1/8] Fix push! for OffsetVectors, add tests for push! and append! on AbstractVector (#55480) Per https://github.com/JuliaLang/julia/pull/55470#discussion_r1714000529, the `push!(::AbstractArray, ...)` array implementation assumed one-based indexing and did not account for an `OffsetVector` scenario. Here we add tests for `push!(::AbstractArray, ...)` and `append(::AbstractArray, ...)` including using `@invoke` to test the effect on `OffsetVector`. cc: @fredrikekre --- base/abstractarray.jl | 7 ++++--- test/abstractarray.jl | 18 +++++++++++++++++- test/offsetarray.jl | 29 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 3f8886e14940c1..754ab20660ab88 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -3532,7 +3532,7 @@ function push!(a::AbstractVector{T}, item) where T itemT = item isa T ? item : convert(T, item)::T new_length = length(a) + 1 resize!(a, new_length) - a[new_length] = itemT + a[end] = itemT return a end @@ -3540,7 +3540,7 @@ end function push!(a::AbstractVector{Any}, @nospecialize x) new_length = length(a) + 1 resize!(a, new_length) - a[new_length] = x + a[end] = x return a end function push!(a::AbstractVector{Any}, @nospecialize x...) @@ -3548,8 +3548,9 @@ function push!(a::AbstractVector{Any}, @nospecialize x...) na = length(a) nx = length(x) resize!(a, na + nx) + e = lastindex(a) - nx for i = 1:nx - a[na+i] = x[i] + a[e+i] = x[i] end return a end diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 8b4a1d91139402..f655d9abe423f3 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1437,14 +1437,30 @@ using .Main.OffsetArrays end @testset "Check push!($a, $args...)" for - a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)), + a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), SimpleArray{Any}(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)), args in (("eenie",), ("eenie", "minie"), ("eenie", "minie", "mo")) orig = copy(a) push!(a, args...) @test length(a) == length(orig) + length(args) + @test a[axes(orig,1)] == orig @test all(a[end-length(args)+1:end] .== args) end +@testset "Check append!($a, $args)" for + a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), SimpleArray{Any}(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)), + args in (("eenie",), ("eenie", "minie"), ("eenie", "minie", "mo")) + orig = copy(a) + append!(a, args) + @test length(a) == length(orig) + length(args) + @test a[axes(orig,1)] == orig + @test all(a[end-length(args)+1:end] .== args) +end + +@testset "Check sizehint!($a)" for + a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), SimpleArray{Any}(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)) + @test sizehint!(a, 10) === a +end + @testset "splatting into hvcat" begin t = (1, 2) @test [t...; 3 4] == [1 2; 3 4] diff --git a/test/offsetarray.jl b/test/offsetarray.jl index c50f38c382385d..5ee918e85faf7f 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -383,6 +383,18 @@ v2 = copy(v) @test v2[end-1] == 2 @test v2[end] == 1 +# push!(v::AbstractVector, x...) +v2 = copy(v) +@test @invoke(push!(v2::AbstractVector, 3)) === v2 +@test v2[axes(v,1)] == v +@test v2[end] == 3 +@test v2[begin] == v[begin] == v[-2] +v2 = copy(v) +@test @invoke(push!(v2::AbstractVector, 5, 6)) == v2 +@test v2[axes(v,1)] == v +@test v2[end-1] == 5 +@test v2[end] == 6 + # append! from array v2 = copy(v) @test append!(v2, [2, 1]) === v2 @@ -399,6 +411,23 @@ v2 = copy(v) @test v2[axes(v, 1)] == v @test v2[lastindex(v)+1:end] == [2, 1] +# append!(::AbstractVector, ...) +# append! from array +v2 = copy(v) +@test @invoke(append!(v2::AbstractVector, [2, 1]::Any)) === v2 +@test v2[axes(v, 1)] == v +@test v2[lastindex(v)+1:end] == [2, 1] +# append! from HasLength iterator +v2 = copy(v) +@test @invoke(append!(v2::AbstractVector, (v for v in [2, 1])::Any)) === v2 +@test v2[axes(v, 1)] == v +@test v2[lastindex(v)+1:end] == [2, 1] +# append! from SizeUnknown iterator +v2 = copy(v) +@test @invoke(append!(v2::AbstractVector, (v for v in [2, 1] if true)::Any)) === v2 +@test v2[axes(v, 1)] == v +@test v2[lastindex(v)+1:end] == [2, 1] + # other functions v = OffsetArray(v0, (-3,)) @test lastindex(v) == 1 From ddecfe74ffdfbbdfe0c2e78cee059470982e0ab9 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 16 Aug 2024 14:14:36 -0400 Subject: [PATCH 2/8] fix overlapping definitions of `Base.active_module` and `REPL.active_module` (#55316) also avoid calling `active_module` from low-level printing functions fix #54888 --- base/Enums.jl | 2 +- base/show.jl | 44 +++++++++++++++++------------------------ stdlib/REPL/src/REPL.jl | 21 ++++++++------------ 3 files changed, 27 insertions(+), 40 deletions(-) diff --git a/base/Enums.jl b/base/Enums.jl index 6e9efd8ccde382..d4094945853ec2 100644 --- a/base/Enums.jl +++ b/base/Enums.jl @@ -44,7 +44,7 @@ Base.print(io::IO, x::Enum) = print(io, _symbol(x)) function Base.show(io::IO, x::Enum) sym = _symbol(x) if !(get(io, :compact, false)::Bool) - from = get(io, :module, Base.active_module()) + from = get(io, :module, Main) def = parentmodule(typeof(x)) if from === nothing || !Base.isvisible(sym, def, from) show(io, def) diff --git a/base/show.jl b/base/show.jl index fa66a198aef4d0..0a2976e7ebe42e 100644 --- a/base/show.jl +++ b/base/show.jl @@ -514,24 +514,16 @@ function _show_default(io::IO, @nospecialize(x)) end function active_module() - REPL = REPL_MODULE_REF[] - REPL === Base && return Main - return invokelatest(REPL.active_module)::Module + if ccall(:jl_is_in_pure_context, Bool, ()) + error("active_module() should not be called from a pure context") + end + if !@isdefined(active_repl) || active_repl === nothing + return Main + end + return invokelatest(active_module, active_repl)::Module end -# Check if a particular symbol is exported from a standard library module -function is_exported_from_stdlib(name::Symbol, mod::Module) - !isdefined(mod, name) && return false - orig = getfield(mod, name) - while !(mod === Base || mod === Core) - activemod = active_module() - parent = parentmodule(mod) - if mod === activemod || mod === parent || parent === activemod - return false - end - mod = parent - end - return isexported(mod, name) && isdefined(mod, name) && !isdeprecated(mod, name) && getfield(mod, name) === orig +module UsesCoreAndBaseOnly end function show_function(io::IO, f::Function, compact::Bool, fallback::Function) @@ -544,13 +536,13 @@ function show_function(io::IO, f::Function, compact::Bool, fallback::Function) print(io, mt.name) elseif isdefined(mt, :module) && isdefined(mt.module, mt.name) && getfield(mt.module, mt.name) === f - mod = active_module() - if is_exported_from_stdlib(mt.name, mt.module) || mt.module === mod - show_sym(io, mt.name) - else + # this used to call the removed internal function `is_exported_from_stdlib`, which effectively + # just checked for exports from Core and Base. + mod = get(io, :module, UsesCoreAndBaseOnly) + if !(isvisible(mt.name, mt.module, mod) || mt.module === mod) print(io, mt.module, ".") - show_sym(io, mt.name) end + show_sym(io, mt.name) else fallback(io, f) end @@ -737,9 +729,9 @@ end function show_typealias(io::IO, name::GlobalRef, x::Type, env::SimpleVector, wheres::Vector) if !(get(io, :compact, false)::Bool) # Print module prefix unless alias is visible from module passed to - # IOContext. If :module is not set, default to Main (or current active module). + # IOContext. If :module is not set, default to Main. # nothing can be used to force printing prefix. - from = get(io, :module, active_module()) + from = get(io, :module, Main) if (from === nothing || !isvisible(name.name, name.mod, from)) show(io, name.mod) print(io, ".") @@ -1053,9 +1045,9 @@ function show_type_name(io::IO, tn::Core.TypeName) quo = false if !(get(io, :compact, false)::Bool) # Print module prefix unless type is visible from module passed to - # IOContext If :module is not set, default to Main (or current active module). + # IOContext If :module is not set, default to Main. # nothing can be used to force printing prefix - from = get(io, :module, active_module()) + from = get(io, :module, Main) if isdefined(tn, :module) && (from === nothing || !isvisible(sym, tn.module, from::Module)) show(io, tn.module) print(io, ".") @@ -2535,7 +2527,7 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg uw = unwrap_unionall(ft) if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) && _isself(uw) uwmod = parentmodule(uw) - if qualified && !is_exported_from_stdlib(uw.name.mt.name, uwmod) && uwmod !== Main + if qualified && !isexported(uwmod, uw.name.mt.name) && uwmod !== Main print_within_stacktrace(io, uwmod, '.', bold=true) end s = sprint(show_sym, (demangle ? demangle_function_name : identity)(uw.name.mt.name), context=io) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 67f5860082c8ad..585ff1aa775b74 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -329,7 +329,7 @@ function warn_on_non_owning_accesses(current_mod, ast) end return ast end -warn_on_non_owning_accesses(ast) = warn_on_non_owning_accesses(REPL.active_module(), ast) +warn_on_non_owning_accesses(ast) = warn_on_non_owning_accesses(Base.active_module(), ast) const repl_ast_transforms = Any[softscope, warn_on_non_owning_accesses] # defaults for new REPL backends @@ -497,7 +497,7 @@ end function display(d::REPLDisplay, mime::MIME"text/plain", x) x = Ref{Any}(x) with_repl_linfo(d.repl) do io - io = IOContext(io, :limit => true, :module => active_module(d)::Module) + io = IOContext(io, :limit => true, :module => Base.active_module(d)::Module) if d.repl isa LineEditREPL mistate = d.repl.mistate mode = LineEdit.mode(mistate) @@ -527,7 +527,7 @@ show_repl(io::IO, ::MIME"text/plain", ex::Expr) = function print_response(repl::AbstractREPL, response, show_value::Bool, have_color::Bool) repl.waserror = response[2] with_repl_linfo(repl) do io - io = IOContext(io, :module => active_module(repl)::Module) + io = IOContext(io, :module => Base.active_module(repl)::Module) print_response(io, response, show_value, have_color, specialdisplay(repl)) end return nothing @@ -628,7 +628,7 @@ function run_repl(repl::AbstractREPL, @nospecialize(consumer = x -> nothing); ba Core.println(Core.stderr, e) Core.println(Core.stderr, catch_backtrace()) end - get_module = () -> active_module(repl) + get_module = () -> Base.active_module(repl) if backend_on_current_task t = @async run_frontend(repl, backend_ref) errormonitor(t) @@ -760,14 +760,9 @@ REPLCompletionProvider() = REPLCompletionProvider(LineEdit.Modifiers()) mutable struct ShellCompletionProvider <: CompletionProvider end struct LatexCompletions <: CompletionProvider end -function active_module() # this method is also called from Base - isdefined(Base, :active_repl) || return Main - Base.active_repl === nothing && return Main - return active_module(Base.active_repl::AbstractREPL) -end -active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate.active_module -active_module(::AbstractREPL) = Main -active_module(d::REPLDisplay) = active_module(d.repl) +Base.active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate.active_module +Base.active_module(::AbstractREPL) = Main +Base.active_module(d::REPLDisplay) = Base.active_module(d.repl) setmodifiers!(c::CompletionProvider, m::LineEdit.Modifiers) = nothing @@ -1206,7 +1201,7 @@ enable_promptpaste(v::Bool) = JL_PROMPT_PASTE[] = v function contextual_prompt(repl::LineEditREPL, prompt::Union{String,Function}) function () - mod = active_module(repl) + mod = Base.active_module(repl) prefix = mod == Main ? "" : string('(', mod, ") ") pr = prompt isa String ? prompt : prompt() prefix * pr From 5a633b7c8400cf3ae36cfebab62c5a316fc46649 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Fri, 16 Aug 2024 15:30:48 -0300 Subject: [PATCH 3/8] Fix fast getptls ccall lowering. (#55507) --- src/ccall.cpp | 3 +-- src/julia_threads.h | 3 --- test/compiler/codegen.jl | 3 +++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 97315d46b6ead8..36808e13fdbf93 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1671,9 +1671,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) emit_gc_safepoint(ctx.builder, ctx.types().T_size, get_current_ptls(ctx), ctx.tbaa().tbaa_const); return ghostValue(ctx, jl_nothing_type); } - else if (is_libjulia_func("jl_get_ptls_states")) { + else if (is_libjulia_func(jl_get_ptls_states)) { ++CCALL_STAT(jl_get_ptls_states); - assert(lrt == ctx.types().T_size); assert(!isVa && !llvmcall && nccallargs == 0); JL_GC_POP(); return mark_or_box_ccall_result(ctx, get_current_ptls(ctx), retboxed, rt, unionall, static_rt); diff --git a/src/julia_threads.h b/src/julia_threads.h index 3486c5b969383f..9a2a8cec375f5c 100644 --- a/src/julia_threads.h +++ b/src/julia_threads.h @@ -206,10 +206,7 @@ typedef struct _jl_tls_states_t { #endif } jl_tls_states_t; -#ifndef JL_LIBRARY_EXPORTS -// deprecated (only for external consumers) JL_DLLEXPORT void *jl_get_ptls_states(void); -#endif // Update codegen version in `ccall.cpp` after changing either `pause` or `wake` #ifdef __MIC__ diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index c74dfbb29d3dd8..cb983d7ab515e5 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -966,3 +966,6 @@ end let x = Incomplete55396(55396) @test x.x === (55396,) end + +# Core.getptls() special handling +@test !occursin("call ptr @jlplt", get_llvm(Core.getptls, Tuple{})) #It should lower to a direct load of the ptls and not a ccall From f2fc2d903558fecee55d7aebf3536692ff278fed Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 16 Aug 2024 15:58:08 -0400 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20Pkg?= =?UTF-8?q?=20stdlib=20from=207aef1f044=20to=20d1d2fc986=20(#55511)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 | 1 - .../Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 | 1 - .../Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/md5 | 1 + .../Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/md5 create mode 100644 deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/sha512 diff --git a/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 b/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 deleted file mode 100644 index 218260c77ea072..00000000000000 --- a/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -832f88c404516179ece213581cd227f8 diff --git a/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 b/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 deleted file mode 100644 index fc763c8d86f40a..00000000000000 --- a/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -4355bb51a7f83bde489e587527e1e3a9c70799a5c0d27cd7f42b4227a5fbca2a1200a83db0317a75c582ee997bec72e9e8afafb059c395bd46e2aa015f481dca diff --git a/deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/md5 b/deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/md5 new file mode 100644 index 00000000000000..097013569ceaed --- /dev/null +++ b/deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/md5 @@ -0,0 +1 @@ +725181b382adb22ad4f1f5e78db526ed diff --git a/deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/sha512 b/deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/sha512 new file mode 100644 index 00000000000000..d6d81554310230 --- /dev/null +++ b/deps/checksums/Pkg-d1d2fc986e7249909b450979acc4d359aacfc88e.tar.gz/sha512 @@ -0,0 +1 @@ +9ab56f368d5075a6f514ab8d2169239b439610c9bc9aca67a45a8a834b4d4ae7988910de3c78a687e40623fcd8bc9ba4aeee64ae7edf2cc84f1945b7e543a559 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 964c43dfcc786a..cc38c670212243 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = 7aef1f044f3483e8b07d33fb4cfe918be554de69 +PKG_SHA1 = d1d2fc986e7249909b450979acc4d359aacfc88e PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 0a26e908e77f147a5a964735ad02f74d047fe47b Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 16 Aug 2024 20:58:30 +0100 Subject: [PATCH 5/8] update precompile progress bar to match Pkg (#55512) --- base/precompilation.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/base/precompilation.jl b/base/precompilation.jl index aa70718eab9bc0..6997ce12c8d013 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -304,9 +304,10 @@ function show_progress(io::IO, p::MiniProgressBar; termwidth=nothing, carriagere to_print = sprint(; context=io) do io print(io, " "^p.indent) printstyled(io, p.header, color=p.color, bold=true) - print(io, " [") - print(io, "="^n_filled, ">") - print(io, " "^n_left, "] ", ) + print(io, " ") + printstyled(io, "━"^n_filled; color=p.color) + printstyled(io, perc >= 95 ? "━" : "╸"; color=p.color) + printstyled(io, "━"^n_left, " "; color=:light_black) print(io, progress_text) carriagereturn && print(io, "\r") end From 8a19b74b5f849f6832a0bfcb689f6407300e9a80 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sat, 17 Aug 2024 19:15:58 +0530 Subject: [PATCH 6/8] Update symmetric docstring to reflect the type of uplo (#55504) This brings the docstring closer to the actual implementation. In particular, following the current docstring and defining ```julia symmetric(::MyMatrix, uplo=:U) ``` leads to a method ambiguity, as `LinearAlgebra` defines `symmetric(::AbstractMatrix, uplo::Symbol=:U)`. --- stdlib/LinearAlgebra/src/symmetric.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stdlib/LinearAlgebra/src/symmetric.jl b/stdlib/LinearAlgebra/src/symmetric.jl index d8011582326730..55630595f6fb2f 100644 --- a/stdlib/LinearAlgebra/src/symmetric.jl +++ b/stdlib/LinearAlgebra/src/symmetric.jl @@ -12,7 +12,7 @@ struct Symmetric{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T} end end """ - Symmetric(A, uplo=:U) + Symmetric(A::AbstractMatrix, uplo::Symbol=:U) Construct a `Symmetric` view of the upper (if `uplo = :U`) or lower (if `uplo = :L`) triangle of the matrix `A`. @@ -63,7 +63,7 @@ function Symmetric(A::AbstractMatrix, uplo::Symbol=:U) end """ - symmetric(A, uplo=:U) + symmetric(A, uplo::Symbol=:U) Construct a symmetric view of `A`. If `A` is a matrix, `uplo` controls whether the upper (if `uplo = :U`) or lower (if `uplo = :L`) triangle of `A` is used to implicitly fill the @@ -105,7 +105,7 @@ struct Hermitian{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T} end end """ - Hermitian(A, uplo=:U) + Hermitian(A::AbstractMatrix, uplo::Symbol=:U) Construct a `Hermitian` view of the upper (if `uplo = :U`) or lower (if `uplo = :L`) triangle of the matrix `A`. @@ -153,7 +153,7 @@ function Hermitian(A::AbstractMatrix, uplo::Symbol=:U) end """ - hermitian(A, uplo=:U) + hermitian(A, uplo::Symbol=:U) Construct a hermitian view of `A`. If `A` is a matrix, `uplo` controls whether the upper (if `uplo = :U`) or lower (if `uplo = :L`) triangle of `A` is used to implicitly fill the @@ -998,7 +998,7 @@ function cbrt(A::HermOrSym{<:Real}) end """ - hermitianpart(A, uplo=:U) -> Hermitian + hermitianpart(A::AbstractMatrix, uplo::Symbol=:U) -> Hermitian Return the Hermitian part of the square matrix `A`, defined as `(A + A') / 2`, as a [`Hermitian`](@ref) matrix. For real matrices `A`, this is also known as the symmetric part @@ -1014,7 +1014,7 @@ See also [`hermitianpart!`](@ref) for the corresponding in-place operation. hermitianpart(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart(A), uplo) """ - hermitianpart!(A, uplo=:U) -> Hermitian + hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) -> Hermitian Overwrite the square matrix `A` in-place with its Hermitian part `(A + A') / 2`, and return [`Hermitian(A, uplo)`](@ref). For real matrices `A`, this is also known as the symmetric From faa6095e983fed777007274f4efb9911154b1f3d Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Sat, 17 Aug 2024 17:00:26 +0200 Subject: [PATCH 7/8] Demote(B)Float16 pass: only keep enabled for PPC. (#55486) LLVM should handle this properly now for everything but PPC (where BFoat16 isn't supported anyway). --- src/llvm-demote-float16.cpp | 47 ++++++++++-------------- test/llvmpasses/fastmath.jl | 26 -------------- test/llvmpasses/float16.ll | 71 +++++++++++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 57 deletions(-) diff --git a/src/llvm-demote-float16.cpp b/src/llvm-demote-float16.cpp index 5d0d9f5d37c406..7f1b076897fc84 100644 --- a/src/llvm-demote-float16.cpp +++ b/src/llvm-demote-float16.cpp @@ -49,37 +49,28 @@ extern JuliaOJIT *jl_ExecutionEngine; namespace { -static bool have_fp16(Function &caller, const Triple &TT) { - Attribute FSAttr = caller.getFnAttribute("target-features"); - StringRef FS = ""; - if (FSAttr.isValid()) - FS = FSAttr.getValueAsString(); - else if (jl_ExecutionEngine) - FS = jl_ExecutionEngine->getTargetFeatureString(); - // else probably called from opt, just do nothing - if (TT.isAArch64()) { - if (FS.find("+fp16fml") != llvm::StringRef::npos || FS.find("+fullfp16") != llvm::StringRef::npos){ - return true; - } - } else if (TT.getArch() == Triple::x86_64) { - if (FS.find("+avx512fp16") != llvm::StringRef::npos){ - return true; - } - } - if (caller.hasFnAttribute("julia.hasfp16")) { - return true; - } - return false; +static bool have_fp16(Function &F, const Triple &TT) { + // for testing purposes + Attribute Attr = F.getFnAttribute("julia.hasfp16"); + if (Attr.isValid()) + return Attr.getValueAsBool(); + + // llvm/llvm-project#97975: on some platforms, `half` uses excessive precision + if (TT.isPPC()) + return false; + + return true; } -static bool have_bf16(Function &caller, const Triple &TT) { - if (caller.hasFnAttribute("julia.hasbf16")) { - return true; - } +static bool have_bf16(Function &F, const Triple &TT) { + // for testing purposes + Attribute Attr = F.getFnAttribute("julia.hasbf16"); + if (Attr.isValid()) + return Attr.getValueAsBool(); - // there's no targets that fully support bfloat yet;, - // AVX512BF16 only provides conversion and dot product instructions. - return false; + // https://github.com/llvm/llvm-project/issues/97975#issuecomment-2218770199: + // on current versions of LLVM, bf16 always uses TypeSoftPromoteHalf + return true; } static bool demoteFloat16(Function &F) diff --git a/test/llvmpasses/fastmath.jl b/test/llvmpasses/fastmath.jl index dd0892be56a0b4..3c4c1d491ec28d 100644 --- a/test/llvmpasses/fastmath.jl +++ b/test/llvmpasses/fastmath.jl @@ -16,29 +16,3 @@ import Base.FastMath # CHECK: call fast float @llvm.sqrt.f32(float %"x::Float32") emit(FastMath.sqrt_fast, Float32) - - -# Float16 operations should be performed as Float32, unless @fastmath is specified -# TODO: this is not true for platforms that natively support Float16 - -foo(x::T,y::T) where T = x-y == zero(T) -# CHECK: define {{(swiftcc )?}}i8 @julia_foo_{{[0-9]+}}({{.*}}half %[[X:"x::Float16"]], half %[[Y:"y::Float16"]]) {{.*}}{ -# CHECK-DAG: %[[XEXT:[0-9]+]] = fpext half %[[X]] to float -# CHECK-DAG: %[[YEXT:[0-9]+]] = fpext half %[[Y]] to float -# CHECK: %[[DIFF:[0-9]+]] = fsub float %[[XEXT]], %[[YEXT]] -# CHECK: %[[TRUNC:[0-9]+]] = fptrunc float %[[DIFF]] to half -# CHECK: %[[DIFFEXT:[0-9]+]] = fpext half %[[TRUNC]] to float -# CHECK: %[[CMP:[0-9]+]] = fcmp oeq float %[[DIFFEXT]], 0.000000e+00 -# CHECK: %[[ZEXT:[0-9]+]] = zext i1 %[[CMP]] to i8 -# CHECK: ret i8 %[[ZEXT]] -# CHECK: } -emit(foo, Float16, Float16) - -@fastmath foo(x::T,y::T) where T = x-y == zero(T) -# CHECK: define {{(swiftcc )?}}i8 @julia_foo_{{[0-9]+}}({{.*}}half %[[X:"x::Float16"]], half %[[Y:"y::Float16"]]) {{.*}}{ -# CHECK: %[[DIFF:[0-9]+]] = fsub fast half %[[X]], %[[Y]] -# CHECK: %[[CMP:[0-9]+]] = fcmp fast oeq half %[[DIFF]], 0xH0000 -# CHECK: %[[ZEXT:[0-9]+]] = zext i1 %[[CMP]] to i8 -# CHECK: ret i8 %[[ZEXT]] -# CHECK: } -emit(foo, Float16, Float16) diff --git a/test/llvmpasses/float16.ll b/test/llvmpasses/float16.ll index 33069c71179ed4..d1dfb6aca11ddd 100644 --- a/test/llvmpasses/float16.ll +++ b/test/llvmpasses/float16.ll @@ -99,7 +99,7 @@ top: ret half %13 } -define bfloat @demote_bfloat_test(bfloat %a, bfloat %b) { +define bfloat @demote_bfloat_test(bfloat %a, bfloat %b) #2 { top: ; CHECK-LABEL: @demote_bfloat_test( ; CHECK-NEXT: top: @@ -160,5 +160,70 @@ top: ret bfloat %13 } -attributes #0 = { "target-features"="-avx512fp16" } -attributes #1 = { "target-features"="+avx512fp16" } +define bfloat @native_bfloat_test(bfloat %a, bfloat %b) #3 { +top: +; CHECK-LABEL: @native_bfloat_test( +; CHECK-NEXT: top: +; CHECK-NEXT: %0 = fadd bfloat %a, %b +; CHECK-NEXT: %1 = fadd bfloat %0, %b +; CHECK-NEXT: %2 = fadd bfloat %1, %b +; CHECK-NEXT: %3 = fmul bfloat %2, %b +; CHECK-NEXT: %4 = fdiv bfloat %3, %b +; CHECK-NEXT: %5 = insertelement <2 x bfloat> undef, bfloat %a, i32 0 +; CHECK-NEXT: %6 = insertelement <2 x bfloat> %5, bfloat %b, i32 1 +; CHECK-NEXT: %7 = insertelement <2 x bfloat> undef, bfloat %b, i32 0 +; CHECK-NEXT: %8 = insertelement <2 x bfloat> %7, bfloat %b, i32 1 +; CHECK-NEXT: %9 = fadd <2 x bfloat> %6, %8 +; CHECK-NEXT: %10 = extractelement <2 x bfloat> %9, i32 0 +; CHECK-NEXT: %11 = extractelement <2 x bfloat> %9, i32 1 +; CHECK-NEXT: %12 = fadd bfloat %10, %11 +; CHECK-NEXT: %13 = fadd bfloat %12, %4 +; CHECK-NEXT: ret bfloat %13 +; + %0 = fadd bfloat %a, %b + %1 = fadd bfloat %0, %b + %2 = fadd bfloat %1, %b + %3 = fmul bfloat %2, %b + %4 = fdiv bfloat %3, %b + %5 = insertelement <2 x bfloat> undef, bfloat %a, i32 0 + %6 = insertelement <2 x bfloat> %5, bfloat %b, i32 1 + %7 = insertelement <2 x bfloat> undef, bfloat %b, i32 0 + %8 = insertelement <2 x bfloat> %7, bfloat %b, i32 1 + %9 = fadd <2 x bfloat> %6, %8 + %10 = extractelement <2 x bfloat> %9, i32 0 + %11 = extractelement <2 x bfloat> %9, i32 1 + %12 = fadd bfloat %10, %11 + %13 = fadd bfloat %12, %4 + ret bfloat %13 +} + +define i1 @fast_half_test(half %0, half %1) #0 { +top: +; CHECK-LABEL: @fast_half_test( +; CHECK-NEXT: top: +; CHECK-NEXT: %2 = fsub fast half %0, %1 +; CHECK-NEXT: %3 = fcmp fast oeq half %2, 0xH0000 +; CHECK-NEXT: ret i1 %3 +; + %2 = fsub fast half %0, %1 + %3 = fcmp fast oeq half %2, 0xH0000 + ret i1 %3 +} + +define i1 @fast_bfloat_test(bfloat %0, bfloat %1) #2 { +top: +; CHECK-LABEL: @fast_bfloat_test( +; CHECK-NEXT: top: +; CHECK-NEXT: %2 = fsub fast bfloat %0, %1 +; CHECK-NEXT: %3 = fcmp fast oeq bfloat %2, 0xR0000 +; CHECK-NEXT: ret i1 %3 +; + %2 = fsub fast bfloat %0, %1 + %3 = fcmp fast oeq bfloat %2, 0xR0000 + ret i1 %3 +} + +attributes #0 = { "julia.hasfp16"="false" } +attributes #1 = { "julia.hasfp16"="true" } +attributes #2 = { "julia.hasbf16"="false" } +attributes #3 = { "julia.hasbf16"="true" } From 4aa9dfa25bde12be7daae2680445eb477eab5da9 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Sat, 17 Aug 2024 17:25:11 -0400 Subject: [PATCH 8/8] Some small tests for transcode (#55436) This logic appears to be [uncovered](https://app.codecov.io/gh/JuliaLang/julia/blob/master/base%2Fstrings%2Fcstring.jl#L232) although it does have a doctest! Running the tests locally managed to trigger these functions. --- test/strings/basic.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/strings/basic.jl b/test/strings/basic.jl index 87d812c5bf2019..d8ca4d204b6f4a 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -1388,3 +1388,10 @@ end end end end + +@testset "transcode" begin + str = "αβγ" + @test transcode(String, transcode(UInt16, str)) == str + @test transcode(String, transcode(UInt16, transcode(UInt8, str))) == str + @test transcode(String, transcode(UInt8, transcode(UInt16, str))) == str +end