[test][Clang][CFI] Precommit tests for cfi-vcall checked loads (#241638)
Record current `cfi-vcall` codegen before emitting
`llvm.type.checked.load` for non-trapping modes. Cover cross-DSO CFI,
VFE, relative vtables, speculative devirtualization, MS ABI secondary
vfptrs, virtual object deletion, ignorelists, debug info, sanitizer
stats, and `EmitVTablePtrCheck` in trap and minimal-runtime modes.
Add compiler-rt tests for two false traps, marked XFAIL:
- deleting a base object through a same-layout derived pointer with
`-fwhole-program-vtables`;
- `-fdevirtualize-speculatively` with a public class whose vtable comes
from a non-LTO object.
Needed by #241639, #241640, #241643, #241644, #241646, and #241647.
Assisted-by: Gemini
[compiler-rt][RISCV] Terminate the save/restore #error strings (NFC) (#241799)
The `#error` directives in riscv/save.S and riscv/restore.S were missing
their closing quote. The assembler preprocessor tolerates that, but a C
preprocessor warns about the unterminated string literal even when the
directive is in a group that is skipped, for instance when the files are
included in C translation units.
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Mintsuki <mintsuki at protonmail.com>
Signed-off-by: Mintsuki <mintsuki at protonmail.com>
[NFC][LowerTypeTests] Make export summary tests self-contained without split-file (#221090)
Follow-up to https://github.com/llvm/llvm-project/pull/220776.
LLVM assembly parsing natively supports co-locating module IR and
ThinLTO
module summary entries in a single `.ll` file (LLParser skips summary
records when parsing module IR, and skips module IR when parsing summary
assembly via parseSummaryIndexAssembly).
Migrate all 13 LowerTypeTests tests that used split-file and temporary
summary files to directly reference %s with
-lowertypetests-read-summary=%s.
This eliminates unnecessary temporary directory creation, split-file
overhead, and disk I/O, keeping each test completely self-contained.
Also convert promoted-internal.ll from a split-file YAML import summary
to
a `cfiFunctionDefs` summary entry in the same file.
Assisted-by: Gemini
[SPIRV] Backend service functions must handle callees with aligned returns (#240910)
We use service functions to pipe undefined but declared (potentially
indirect) callees through IRTranslator. The generated service function
is not translated, but rather emitted as a trap. This is mostly fine
except for cases where the callee provides alignment guarantees on the
return value. In this latter situation, IRTranslator defaults to
inserting an assertion on the alignment value, but we never
allocate/create the vreg it asserts on, which leads to broken MIR. The
workaround here is to signal that we "lowered" a tail call (which is not
a lie), case in which the assertion is not inserted. For a more robust
future solution, we could opt for properly lowering the service function
to MIR, and dealing with it afterwards.
---------
Co-authored-by: Dmitry Sidorov <dsidorov at amd.com>
[libc][signal] fix the ordering issue of abort guard (#242025)
Current abort guard's locking lifetime encloses blocking lifetime.
Hence,
inside locking-blocking gap, reentrant signal handler can deadlock. As
demonstrated in the following cases:
With a handler that calls `sigaction(SIGABRT, ...)` interrupting `fork`:
```
thread (in fork) signal handler on the same thread
---------------- ---------------------------------
SigAbortGuard(exclusive=false)
abort_lock.read_lock()
<------- signal delivered ------->
sigaction(SIGABRT, ...)
SigAbortGuard(exclusive=true)
abort_lock.write_lock()
waits for the reader, which is
[29 lines not shown]
IR: Add getOrInsertFunction with a constructor callback
This fixes an annoying asymmetry in the Module APIs. We already have
getOrInsertGlobal with a constructor callback, but did not have the
same for Functions. This allows inserting a declaration with a single
symbol table probe.
Inserting a missing function did a getNamedValue lookup, then a second
hash table probe when Function::Create added the name. Add
ValueSymbolTable::lookupOrInsert to do both with one try_emplace to
implement this. Intrinsic and unnamed functions keep the old path since
intrinsics are set up from their name on construction. A microbenchmark
inserting all of the runtime libcalls shows this is about 28% faster in
the miss / insertion case.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
ZTS: find a straddling block in raidz_expand_boundary_repair
raidz_expand_boundary_repair sometimes reports SKIP "no block of the
file straddles the reflow offset" (fedora43 in fork CI).
The test pauses the reflow, looks for a file block that straddles the
reflow offset, and if none qualifies moves the pause point on and looks
again, up to 20 times. With the default 16 metaslabs of 64M the file
is written to eight metaslabs with free ones between them. The reflow
pauses at the first txg boundary after the pause point, so it stops
inside the file's data in only about eight of the tries: three in the
first metaslab, a few after it has skipped the free metaslabs in one
step, and the rest at metaslab ends, which are never inside a block.
Each stop inside the data qualifies with a probability of about 0.4
(the reflow may stop in a block's first or last rows, or in a block
whose column on the zeroed disk is its parity), so now and then no try
qualifies before the reflow completes. In ten runs of a version of the
test that kept going to the end of the reflow, 1 to 6 of 12 or 13 tries
qualified.
[14 lines not shown]
ztest: Discard the checkpoint before freeing space after ENOSPC
When a pass records ENOSPC, the next one starts with ztest_run()
destroying a random dataset to free space, and ztest_generic_run()
then creates it again with VERIFY0(ztest_dataset_open(i)). The
creation is a sync task checked against ZFS_SPACE_CHECK_NORMAL.
ztest_spa_checkpoint_create_discard() often leaves a pool checkpoint
in place. Under it, the destroy gives back only the space of the
blocks born after the checkpoint; the others stay allocated for it.
The pool can then stay full for several passes, until the dataset to
create again holds too little to make room, and ztest aborts:
ASSERT at cmd/ztest.c:8817:ztest_generic_run()
VERIFY0(ztest_dataset_open(i)) failed (28)
Discard the checkpoint, and wait for the discard to finish, before
the destroy.
[6 lines not shown]
Kick the autotrim threads when autotrim is off
spa_sync() kicks the autotrim threads only while autotrim is on, but a
thread waiting in vdev_autotrim_wait_kick() learns that autotrim was
turned off only once it has been kicked: it checks the property in
vdev_autotrim_should_stop() after the wait. So after "zpool set
autotrim=off" the thread keeps waiting until autotrim is turned back
on or something stops it explicitly: an export, or the next vdev
configuration change through spa_vdev_enter().
When the property changes while the thread waits for the
TXG_CONCURRENT_STATES + TXG_DEFER_SIZE kicks that follow the TRIM of a
metaslab, that metaslab stays disabled all that time: nothing is
allocated from it, and it takes one of the max_disabled_ms slots of
its group. Two manual TRIMs limited to a low rate can hold the other
two (#19448), and every initialize, TRIM or rebuild of that top-level
vdev then waits in metaslab_disable() for as long as they do. A ztest
run (on a tree carrying #17567, none of whose code is involved)
stalled that way at pool close for more than 18 minutes, spa_unload()
[20 lines not shown]
ZTS: inject zinject_args read errors on every mirror child
zinject_args creates a mirror of every disk in $DISKS (three by
default), and its last pass injects read errors on the first disk
only, then reads one 128K block once with primarycache=none. A mirror
reads a block from a single child: vdev_mirror_child_select() picks
the least loaded one, and among children with equal load it picks by
the I/O offset. When it picks another child, the handler on the first
disk never matches and the test fails with "device-fault injection
did not execute (inject=0)".
Register the read fault on every child and check the sum of the
inject counts, so that whichever child serves the read, its handler
fires. The read now fails outright instead of being repaired from
another child; the test already ignores its status. Offlining the
other children would also force the read onto the first disk, but it
degrades the pool and starts a resilver while the remaining checks
run.
[5 lines not shown]
zfs allow: list receive:append in the help output
receive:append was added to the permission table in the kernel and
to zfs-allow.8 by 201d26294, but not to the list that `zfs allow`
prints when run without arguments, so users could not discover it.
Add the missing zfs_deleg_note_t value and table entry, with a
description matching the manual page, the same way send:raw and
send:encrypted were wired up.
Also move the receive:append row of the manual page to the group of
subcommand permissions, next to receive, which is where the help
output lists it. It was left under "other", after a stray blank line.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Tigerblue77 <37409593+tigerblue77 at users.noreply.github.com>
Closes #19682
[clang] Flush the PCM stream before querying the file status (#242050)
The `writeImpl()` function queries the status of the written file
through its file descriptor while the `raw_fd_ostream` may still hold
buffered contents. This can report a size smaller than the actual file.
This PR flushes the stream first.
Nothing observed this bug. The file did get flushed right at the end of
the scope before being moved into the final destination, so no other
processes ever saw a partially-written file. The current Clang instance
never reads back the written buffer, it keeps using its in-memory
version. The only observable thing is the out-parameter `Size` being
wrong, but implicit modules never use it and instead hash contents of
the file for consistency checks.
ZTS: use consistent host identities in concurrent imports
Define the MMP fixture's hostids as hexadecimal so zgenhostid and
ZFS_HOSTID select the same identities. Strip the prefix in
mmp_set_hostid when checking the written value. After a successful zhack
export, use a different identity for the activity check and restore the
pool identity for the next phase.
Both concurrent imports may fail after the initial hard-force export,
leaving the pool marked active under its previous hostid. Use -f for
the first recovery import so that this allowed outcome does not fail
the test. The activity check is still required and verified.
Assisted-by: OpenAI Codex
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: ooonea <ooonea at noreply.codeberg.org>
Closes #19585
[lld-macho] Parallel input section priorities for -order_file (#241470)
buildInputSectionPriorities() used to look up every symbol in
`priorities`, which does a bunch of work (hash a symbol, do some string
manipulation).
Instead, call getSymbolPriority in parallel over object files, and then
serially merge the results.
(This works because std::min() is associative.)
Takes a Chromium Framework link on my machine from 4.191 s ± 0.020 s to
3.970 s ± 0.045 s.
Chromium uses an order file with just a few entries. I also checked with
a synthetic order file that lists all symbols. There, this phase goes
from 781 ms to 357 ms, so it's still faster (the relative speedup is
just smaller).
[2 lines not shown]
[AMDGPU] Restore SADDR add sharing in GlobalISel
Before GFX12, the scalar add expands into an s_add_u32/s_addc_u32 pair
linked through SCC, which MachineCSE cannot merge. Without the per-block
cache, each access in GlobalISel built its own pair, so code for those
targets grew, in some functions beyond what upstream generates. Restore
the cache and add a MIR test that checks two loads share one add.
[HLSL][NFC] Move common defines to the main header (hlsl.h) (#241626)
Move common `#define`s from included headers to the main header
(`hlsl.h`). Includes `_HLSL_BUILTIN_ALIAS`, `HLSL_AVAILABILITY` and
`_HLSL_AVAILABILITY_STAGE`.
[compiler-rt][RISCV] Fix the LP64E __riscv_save_* routines (#241798)
On RV64 with the LP64E ABI, `__riscv_save_0`, `__riscv_save_1` and
`__riscv_save_2` stored ra, s0 and s1 with sw, but the matching
`__riscv_restore_*` routines reload them with ld. The upper 32 bits of
every restored register therefore came from stale stack memory, so code
built with -mabi=lp64e -msave-restore could return to a wrong address or
see corrupted callee-saved values. The sw stores came with the LP64E
versions of these routines in #95398.
Store the registers with sd, like the LP64 routines do, and make the
`END_COMPILERRT_FUNCTION` directives name the functions they end instead
of `__riscv_save_3`, which this configuration does not define.
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Mintsuki <mintsuki at protonmail.com>
[JITLink] Move lookup result into applyLookupResult (#242067)
applyLookupResult takes its AsyncLookupResult by value, but linkPhase3
passed it a copy of LR, even though LR is not used again afterwards.
Moving the result in instead avoids copying the map, along with a
reference-count increment and decrement for every name in it.
The copy also left LR holding the result's SymbolStringPtrs for the rest
of the link. If finalization (or abandonment, on failure) completes
synchronously, the linker and LinkGraph are destroyed before linkPhase3
returns. When the graph holds the only reference to its
SymbolStringPool, that destroys the pool while LR still holds references
into it, tripping the "Dangling references at pool destruction time"
assertion. With the move, the names are released as soon as they have
been applied to the graph.
The new JITLinkGenericTest.SuccessfulLookupWithGraphOwnedPool test
covers a successful synchronous link of a graph that is the only owner
of its pool. The graph construction shared with
FailedLookupWithGraphOwnedPool is moved into a helper.
ARM: Use inline register class syntax in MIR tests
Delete the registers section when unnecessary.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>