[AMDGPU] Fix scale_offset with wrapping offsets
On gfx1250, vector memory scales the sign-extended offset in 64 bits,
but SMEM scales the offset in 32 bits and then zero-extends it. Both
selectors set scale_offset either way, so global and flat accesses
miscompiled a 32-bit scaled index that wraps, and SMEM loads an index
whose 64-bit scaled value reaches 4 GiB.
Keep scale_offset only when nsw or known bits prove that the hardware
computes the same address. Fix the SMEM tests that expected the wrong
code.
Check arm64e ABI markers in static links too
Static links skipped the check, but ld64 takes only unversioned and
kernel objects there besides version 0, and ignores the other markers.
Assisted-by: Claude Code
[lld-macho] Reject incompatible arm64e object ABI markers
The CPU subtype of an arm64e object carries a pointer authentication ABI
marker. In a dynamic link, ld64 accepts only objects marked userland ABI
version 0, even on macOS and Mac Catalyst, whose executables are marked
version 1. It names any other marker as another architecture
(arm64e.old, arm64e.v1, arm64e.kernel, arm64e.kernel.v1 or unknown) and,
as with an arm64 object, ignores the file with a warning, or reports an
error with -arch_errors_fatal. This applies to archive members too.
lld linked these objects. Check the marker in the same way. ld64 accepts
unversioned and kernel-ABI objects in static links, so those links are
not checked.
Assisted-by: Claude Code
[lld-macho] Sign the arm64e TLV bootstrap pointer as ld64 does
The first word of a thread-local variable descriptor is bound to
__tlv_bootstrap, which dyld replaces with a pointer to tlv_get_addr that
TLV accesses call with blraaz. On arm64e, ld64 writes that bind as an
authenticated bind with the IA key and no diversity, although the object
asks for a plain pointer. Do the same.
Assisted-by: Claude Code
[lld-macho] List arm64e __auth_got entries in the map file
The map file printed the entries of __got but not those of arm64e's
__auth_got, which held the targets of the stubs and the personalities.
Print them in the same way.
Assisted-by: Claude Code
[lld-macho] Call through authenticated stubs on arm64e
ld64 calls dylib functions from arm64e code through __auth_stubs rather
than __stubs. Each stub is four instructions instead of three:
adrp x17, slot at page
add x17, x17, slot at pageoff
ldr x16, [x17]
braa x16, x17
where the slot is in __auth_got and holds a pointer that dyld signs with
the IA key, blended with the slot's address. The raw target is only ever
held in x16 and x17, so a stub never branches through an unauthenticated
pointer loaded from writable memory. Do the same: on arm64e, name the stubs
section __auth_stubs, make stubs 16 bytes, and put stub targets in
__auth_got. Fast ObjC stubs load _objc_msgSend from __auth_got and braa to
it in the same way, as ld64's do; small ones already branch to its stub.
__auth_stubs gets __stubs' place directly after __text. That is not just
[11 lines not shown]
Check which __auth_got slot each stub loads
The ObjC stub's slot was captured but never checked, so a stub loading
the wrong slot would have passed.
Assisted-by: Claude Code
Give __stubs and __auth_stubs distinct section priorities
The other code sections already had -5, so move the header, __text and
the code sections down by one to make room for __stubs. The order of the
sections is unchanged; only the ties are gone.
Assisted-by: Claude Code
Make skipping category merging on arm64e a FIXME
ld64 merges arm64e categories by default and keeps their signatures, so
this is a missing feature in lld, not ld64 behavior.
Assisted-by: Claude Code
Keep arm64e bind addends inline as ld64 does
arm64e binds have a 19-bit addend field, but only addends from 0 to 255
stayed inline, as in DYLD_CHAINED_PTR_64; the rest each took an import.
Keep addends below 256 KiB in magnitude inline, as ld64 does, except
negative ones in DYLD_CHAINED_PTR_ARM64E, which ld64 rejects and which
stay in the imports table.
Assisted-by: Claude Code
[lld-macho] Don't merge ObjC categories for arm64e
Category merging rewrites category data without regard to the signing
schemas of the authenticated pointers in it, which produces a binary that
crashes when the runtime authenticates them. Until merging preserves the
schemas, warn about -objc_category_merging on arm64e and leave the
categories as they are.
Assisted-by: Claude Code
Report both problems with a signing schema, and tidy two leftovers
An embedded signing schema can both lack bit 63 and set reserved bits, so
report both. Move the DYLD_CHAINED_PTR_64_OFFSET FIXME to where the
pointer format is chosen, and drop an ICF comparison that the type
comparison above it already makes.
Assisted-by: Claude Code
[lld-macho] Add an arm64e target
lld accepts -arch arm64e but links it with the arm64 target, so the output
claims to be arm64. Add an ARM64e target derived from ARM64, select it for
-arch arm64e, and mark the CPU subtype as ld64 does: CPU_SUBTYPE_ARM64E
with ptrauth ABI version 1 for macOS and Mac Catalyst executables, and
version 0 for everything else.
Assisted-by: Claude Code
Don't suggest -no_fixup_chains in any chained-fixup error on arm64e
The page-boundary and page-index errors still suggested the flag, which
arm64e ignores. Decide in one place whether the hint can help.
Assisted-by: Claude Code
[lld-macho] Don't mix arm64 and arm64e objects
arm64 and arm64e share a CPU type, but as in ld64, an arm64e link ignores
arm64 objects and an arm64 link ignores arm64e objects with a warning, and
-arch_errors_fatal makes both an error. Like ld64, both also ignore
arm64e.x1 objects, which have the arm64e ABI but need a newer CPU than
arm64e. The inputs of an -arch arm64e.x1 link are not checked.
Assisted-by: Claude Code
[lld-macho] Keep differently signed arm64e data apart in ICF
Sections that differ only in the signing schema of an authenticated pointer
are not identical. Compare the schemas in ICF. This matters even without
--icf, because __cfstring sections, whose isa pointers arm64e compilers
sign, are always deduplicated.
Assisted-by: Claude Code
[lld-macho] Link arm64e authenticated pointers
Parse ARM64_RELOC_AUTHENTICATED_POINTER, which keeps the pointer's signing
schema (key, diversity and address diversity) in its upper half, and write
it as an authenticated chained rebase or bind. Relocation stores the schema
next to a 32-bit addend, so its size stays 24 bytes.
As in ld64, accept only the extern form of the relocation and only a payload
with the authentication bit set and the reserved bits clear, store the
target of an authenticated rebase as an offset of at most 4 GiB from the
image base, put the addends of authenticated binds, which have no addend
field, in the imports table, and keep authenticated pointers in
__thread_vars signed pointers rather than offsets into the thread-local
data.
Assisted-by: Claude Code
[lld-macho] Sign arm64e personality pointers through __auth_got
The arm64e unwinder authenticates the personality pointers that it loads
through the GOT, from the personality array in __unwind_info and from a
CIE, against the address of their slot with the IA key. An image with an
unsigned slot crashes on its first throw. Like ld64, put these GOT entries
in __auth_got, whose pointers dyld signs that way. Other GOT references to
the same symbol keep their unsigned __got slot.
Assisted-by: Claude Code
[lld-macho] Use ld64's chained fixups for arm64e
Authenticated pointers can only be encoded as chained fixups, so like
ld64, use them for every arm64e output: also below the deployment targets
at which lld switches other architectures to chained fixups, and when
-no_fixup_chains is given, which ld64 ignores with a warning while keeping
__mod_init_func and DYLD_CHAINED_PTR_ARM64E.
Write rebases and binds in ld64's pointer formats, with an 8-byte stride:
DYLD_CHAINED_PTR_ARM64E_USERLAND24 from the deployment targets at which
ld64 switches to it, and DYLD_CHAINED_PTR_ARM64E below them. As ld64 does,
and with its messages, reject rebase targets that the format cannot hold,
including targets below the image base, and images with more than 65535
imports in DYLD_CHAINED_PTR_ARM64E, whose binds have 16-bit ordinals.
Assisted-by: Claude Code
[llvm-objdump] Decode arm64e chained fixups (#234001)
`llvm-objdump` and `llvm-otool` decoded only `DYLD_CHAINED_PTR_64` and
`DYLD_CHAINED_PTR_64_OFFSET` and stopped with "unsupported chained fixup
pointer_format" on arm64e.
Here we:
- Add the `dyld_chained_ptr_arm64e_*` structs of
`<mach-o/fixup-chains.h>` to `BinaryFormat`
- Decode `DYLD_CHAINED_PTR_ARM64E` and
`DYLD_CHAINED_PTR_ARM64E_USERLAND24` fixups in `MachOChainedFixupEntry`
- Authenticated rebases and binds expose their key, diversity and
address diversity, which `--dyld-info` prints in the div, addr and key
columns that cctools' `otool` uses for arm64e.
The test builds its images with `yaml2obj` from the `obj2yaml` output of
images that Xcode 27's ld linked from the sources in the test. The
lld-macho arm64e tests later in the stack check their output with this
decoder.
Assisted-by: Claude
[mlir][ODS] Add EnumInfo accessors for the bit enum separator (NFC)
The generators read the bit enum `separator` field through
getValueAsString in nine places, and EnumsGen and OpFormatGen each carry
a copy of the StringSwitch that maps it to the AsmParser method parsing
it. Add EnumInfo::getBitEnumSeparator, getBitEnumSeparatorKind and
getBitEnumSeparatorParser, and use them at every site; the comma checks
now compare the kind. A separator other than '|' or ',' used to produce
C++ that did not compile and is now a TableGen error instead.
Assisted-by: Claude Code (Claude Opus 5.5).
[mlir][ODS] Allow a space-only separator for bit enums
Bit enums required a separator containing '|' or ',', so a flag set
could not use the bare keyword syntax of LLVM IR, e.g. `nuw nsw`.
Dialects that want it, such as ClangIR's overflow flags, had to hand-write
a parser and printer for an EnumProp.
Allow `separator = " "` on new-style BitEnums. The generated
FieldParser then reads case keywords until the next token is not one,
symbolize splits on spaces, and the op-format `enum` directive parses
the same way. A literal right after such an enum or enum property that
is one of its cases, including an oilist clause keyword, is now rejected
as ambiguous. The separator must now be exactly '|' or ',', optionally
surrounded by spaces, or spaces only, so strings such as "||" are
rejected. Legacy BitEnumAttr keeps requiring '|' or ','.
Assisted-by: Claude Code (Claude Opus 5.5).
[AMDGPU][MLGO] Add regalloc scoring pass to the optimized pipeline (#229668)
Without it the last observation of each function in MLGO training logs
has no reward
[AArch64] Select same-input SVE EXT with EXT_ZZI_CONSTRUCTIVE (#227749)
When both operands of AArch64ISD::EXT are the same register, isel
selected destructive EXT_ZZI (or SVE2 EXT_ZZI_B). Two-address / RA then
inserted a COPY (mov) to satisfy dest == first source.
Match the same-input case to EXT_ZZI_CONSTRUCTIVE so expand-pseudos
emits MOVPRFX + EXT when dest differs from the source, and a bare EXT
when they already alias.
---------
Co-authored-by: Ricardo Jesus <rjj at nvidia.com>
[OpenMP][omptest] Run the ompTest unit tests on the AMDGPU clang-flang bot
ompTest ships unit tests that register as check-ompt-omptest, but
LIBOMPTEST_BUILD_UNITTESTS defaults to OFF, so no buildbot builds or runs
them. Its install rules are likewise never exercised.
Enable both on the openmp-offload-amdgpu-clang-flang bot, which already runs
check-openmp and installs.
Assisted-by: Claude Opus 5 <noreply at anthropic.com>
[OpenMP][omptest] Export the standalone build mode to library users
OmptTester.h picks its test-case implementation from
OPENMP_LIBOMPTEST_BUILD_STANDALONE, but the definition was PRIVATE and never
reached users of an installed ompTest: they pulled in the GoogleTest variant
against a standalone libomptest and failed to link.
Make it PUBLIC so the exported target carries it, and consumers select the
header matching the library without having to know how it was built.
Assisted-by: Claude Opus 5 <noreply at anthropic.com>
[OpenMP][omptest] Install the package config at a target-independent path
Make it predictable where the installed cmake config lands in presence
of LLVM_ENABLE_PER_TARGET_RUNTIME_DIR.
Install it under lib${LLVM_LIBDIR_SUFFIX}/cmake, which does not depend
on the target. The library itself stays next to libomp; the generated files
resolve their prefix relative to the config, so nothing else changes.
Assisted-by: Claude Opus 5 <noreply at anthropic.com>
[OpenMP][omptest] Fix target dependency on runtimes GTest (#237200)
Linking default_gtest PUBLIC puts it into omptest's link interface, so
install(EXPORT) fails with "requires target runtimes_gtest that is not
in any
export set".
Only GTest's include directories and compile definitions are needed, and
only
while building, so attach those behind BUILD_INTERFACE. Embedding the
GTest
objects is unchanged.
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
Co-authored-by: Michael Halkenhäuser <MichaelGerald.Halkenhauser at amd.com>