diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 90091cc1f38db..a60396cfca5df 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1897,7 +1897,17 @@ void optimizeDLSyms(Module &M) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER { void fixupTM(TargetMachine &TM) { auto TheTriple = TM.getTargetTriple(); if (jl_options.opt_level < 2) { - if (!TheTriple.isARM() && !TheTriple.isPPC64() && !TheTriple.isAArch64()) + // Try GlobalISel on AArch64 - it's the default in LLVM at -O0 and + // is apparently generally faster than SelectionDAG while producing good code. + // Use fallback mode so unsupported patterns fall back to SelectionDAG. + // Note: Requires RemoveJuliaAddrspacesPass to run before codegen + // because GlobalISel doesn't handle Julia's custom address spaces. + if (TheTriple.isAArch64()) { + TM.setGlobalISel(true); + TM.setGlobalISelAbort(GlobalISelAbortMode::Disable); + TM.setFastISel(false); + } + else if (!TheTriple.isARM() && !TheTriple.isPPC64()) TM.setFastISel(true); else // FastISel seems to be buggy Ref #13321 TM.setFastISel(false); diff --git a/test/atomics.jl b/test/atomics.jl index 369a63f7d5fbf..b212bd118becb 100644 --- a/test/atomics.jl +++ b/test/atomics.jl @@ -1115,3 +1115,15 @@ function add_one57190!() end @test add_one57190!() == 1 + +# Test atomic Float16 operations at all optimization levels (GlobalISel miscompile on AArch64) +# See https://github.com/JuliaLang/julia/pull/54140#issuecomment-2855794363 +for opt in 0:3 + @test success(run(```$(Base.julia_cmd()) --startup-file=no -O$opt -e ' + a = Threads.Atomic{Float16}(Float16(0)) + a[] = Float16(1.5) + @assert a[] === Float16(1.5) "atomic Float16 store failed: got \$(a[]) expected 1.5 (opt level = -O$(Base.JLOptions().opt_level))" + a[] = Float16(3.25) + @assert a[] === Float16(3.25) "atomic Float16 store failed: got \$(a[]) expected 3.25 (opt level = -O$(Base.JLOptions().opt_level))" + '```)) +end