Skip to content

Conversation

@IanButterworth
Copy link
Member

@IanButterworth IanButterworth commented Dec 7, 2025

On-top of/alternative to #60338
Just exploring whether this works, given below:


GlobalISel is LLVM's modern instruction selector that is designed to replace
both FastISel and SelectionDAG. On AArch64, it is mature and enabled by default
at -O0 in upstream LLVM.

This enables GlobalISel with fallback mode on AArch64, which provides faster
instruction selection than SelectionDAG while maintaining correctness by
falling back to SelectionDAG for unsupported patterns.

Note: This requires RemoveJuliaAddrspacesPass to run before codegen, which is
already the case in the current pipeline (see pipeline.cpp comment about
GlobalISel not liking Julia's address spaces).

Co-authored-by: Claude

FastISel was disabled on AArch64 in 2015 (PR JuliaLang#13393) to fix issue JuliaLang#13321, but
that issue was specifically about 32-bit ARM (ARMv7) segfaults during bootstrap.
The AArch64 exclusion was added conservatively alongside the ARM fix.

AArch64 FastISel has been actively maintained upstream with recent bug fixes:
- llvm/llvm-project#75993 (Jan 2024)
- llvm/llvm-project#133987 (May 2025)

This enables faster instruction selection for JIT compilation on AArch64 at
lower optimization levels, reducing compilation latency.
@IanButterworth IanButterworth changed the title jitlayers: Enable FastISel on AArch64 at -O0/-O1 jitlayers: Use GlobalISel on AArch64 at -O0/-O1 Dec 7, 2025
@IanButterworth IanButterworth added the compiler:codegen Generation of LLVM IR and native code label Dec 7, 2025
GlobalISel is LLVM's modern instruction selector that is designed to replace
both FastISel and SelectionDAG. On AArch64, it is mature and enabled by default
at -O0 in upstream LLVM.

This enables GlobalISel with fallback mode on AArch64, which provides faster
instruction selection than SelectionDAG while maintaining correctness by
falling back to SelectionDAG for unsupported patterns.

Note: This requires RemoveJuliaAddrspacesPass to run before codegen, which is
already the case in the current pipeline (see pipeline.cpp comment about
GlobalISel not liking Julia's address spaces).

Co-Authored-By: Claude <[email protected]>
@gbaraldi
Copy link
Member

gbaraldi commented Dec 8, 2025

I'm more comfortable with this than fastisel

@giordano
Copy link
Member

giordano commented Dec 8, 2025

Does this need a pkgeval?

@IanButterworth IanButterworth added the needs pkgeval Tests for all registered packages should be run with this change label Dec 8, 2025
@IanButterworth
Copy link
Member Author

Yeah a pkgeval on aarch64 would be good. @maleadt is that still possible?

@xal-0
Copy link
Member

xal-0 commented Dec 8, 2025

I believe this was enabled at one point for ahead-of-time compilation but disabled because of miscompiles? I should probably report/fix the easy ones upstream...
#54140 (comment)

The atomic Float16 miscompile still happens on this version:

$ ./usr/bin/julia --banner=short -O1
  o  | Version 1.14.0-DEV.1348 (2025-12-07)
 o o | HEAD/dc0539badaa* (fork: 26 commits, 7 days)
julia> code_native(setindex!, (Threads.Atomic{Float16}, Float16); debuginfo=:none)
[...]
"_julia_setindex!_600":                 ; @"julia_setindex!_600"
	stp	x29, x30, [sp, #-16]!           ; 16-byte Folded Spill
	mov	x29, sp
	mrs	w8, NZCV
	;DEBUG_VALUE: setindex!:v <- $w8
	stlrh	w8, [x0]
	ldp	x29, x30, [sp], #16             ; 16-byte Folded Reload
	ret

Compare with -O1 on master:

"_julia_setindex!_615":                 ; @"julia_setindex!_615"
	;DEBUG_VALUE: setindex!:x <- [$x0+0]
	;DEBUG_VALUE: setindex!:v <- $h0
	stp	x29, x30, [sp, #-16]!           ; 16-byte Folded Spill
	mov	x29, sp
	;DEBUG_VALUE: setindex!:x <- [$x0+0]
	;DEBUG_VALUE: setindex!:v <- $h0
	fmov	w8, s0
	stlrh	w8, [x0]
	ldp	x29, x30, [sp], #16             ; 16-byte Folded Reload
	ret

IIRC you can get this to trigger during bootstrapping with -O1.

@oscardssmith
Copy link
Member

yeah. we should definitely be reporting any bugs in global isel we're finding. IIUC Global Isel is intended to be the isel future (completely replacing SelectionDAG) so we want it to be as solid as possible.

@maleadt
Copy link
Member

maleadt commented Dec 9, 2025

Yeah a pkgeval on aarch64 would be good. @maleadt is that still possible?

Not easily, no; it's a very manual process.
The ARM machine in question is now also used for Base CI, so I can't take it over for a full-scale PkgEval run without compromising CI resources.

@oscardssmith
Copy link
Member

should we also use it at O2/O3? iiuc, for aarch64 it's generally expected to produce equally good code

@IanButterworth IanButterworth removed the needs pkgeval Tests for all registered packages should be run with this change label Dec 9, 2025
@IanButterworth
Copy link
Member Author

IanButterworth commented Dec 9, 2025

@xal-0 I added a test based on your example. It fails locally.

@gbaraldi
Copy link
Member

gbaraldi commented Dec 9, 2025

You can probably ask Claude to turn this into an llc test case for an LLVM issue.

@IanButterworth
Copy link
Member Author

llvm/llvm-project#171494

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler:codegen Generation of LLVM IR and native code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants