[libc] Fix gmtime and mktime for years before zero (#236515)
yrs % 4 is negative for a year before zero, which moved the month out of
range and aborted on the assertion that follows. Mask the low two bits
instead, which is the non-negative remainder
Add the year before zero and year zero to the gmtime test
AI disclosure: this patch was written with Claude Code. I reviewed the
change and ran the new test; it fails without the fix and passes with it
Assisted-by: Claude
[libc][uefi] Encode the error bit in EFI_STATUS error codes (#235071)
Set the high bit on the EFI_STATUS error macros through new
EFI_ERROR_BIT, EFIERR and EFI_ERROR helpers, and use them
directly in the errno translation table, so that error codes match
the values returned by UEFI firmware while warnings remain
plain values. Add EFI_UNSUPPORTED and
EFI_BUFFER_TOO_SMALL to the table, map unrecognized error
statuses to EIO and unrecognized warnings to success, and
cover the conversions with a unit test.
Include the standard boolean header in the UEFI type definitions that
use bool, so that C translation units prior to C23 can include them.
[ValueTracking] Add constrained intrinsics variants to intrinsicPropagatesPoison (#239270)
Followup to #239135. Maybe we can make this tablegen-generated in the
future.
RuntimeLibcalls: Mark vector libcall out pointers dereferenceable
The whole vector width will be written, so mark the vector width. To
maintain the element width alignment for some functions, we need to
start explicitly tracking if the element alignment is used or not.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
RuntimeLibcalls: Declare vector libcall attributes in TableGen (#238227)
Replace the type-based heuristics for vector math libcall attributes
with attributes declared on the libcall definitions, emitted with the
same attribute table helpers as intrinsics.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Key register classes by member EnumValues in Key2RC
Key2RC is searched with Key::operator<, which compares member lists and
loads every register in both. Store the EnumValues of the non-artificial
members in the keys instead, so a lookup only loads the members of the
class being looked up.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 561 295 95
After 536 (-4.5%) 287 (-2.7%) 93 (-1.9%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Only collect sub-registers when there are candidate sub-classes
For each register class and sub-register index, inferMatchingSuperRegClass
looked up the sub-register of every member before checking for candidate
sub-classes, but most pairs have none: 73% for AMDGPU, with 62% of the
lookups. Collect the sub-registers when the first candidate is found.
The candidates are found by the TopoSigs of the sub-registers, which are
the same for registers with the same TopoSig. So find them once per class
from one member per TopoSig, which is usually a single member.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 564 311 100
After 561 (-0.5%) 295 (-5.2%) 95 (-4.9%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Only build the register bank in CallingConvEmitter when needed
CallingConvEmitter built the register bank to find registers named by
strings, which only CCAssignToRegTuple uses. No target does, but
building the register bank is most of the work for targets with many
registers. Build it when the first register name is looked up instead.
All 16 CallingConv tablegen runs in an LLVM build with all targets:
Gigainstructions Gigacycles CPU seconds
Before 73.5 43.4 15.1
After 47.1 (-35.9%) 27.7 (-36.2%) 10.2 (-32.2%)
For AMDGPU alone, the run executes 63% fewer cycles.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
RISCV: Use minimal tablegen inputs for TargetParser (#239104)
Generate RISCVTargetParserDef.inc from a reduced td file which
includes only the features, profiles and processors, instead of all of
RISCV.td. The processors reference scheduling models, which are
defined with the scheduling information for the instructions, so the
new file defines empty placeholder models instead, as was done for
AArch64 in #231954.
RISCV was the last TargetParser input that parsed the full target, and
took 1.74 of the 1.78 seconds spent in the TargetParser tablegen jobs.
llvm-min-tblgen -gen-riscv-target-def, mean of 5 runs
Gigainstructions Seconds Peak RSS .td deps
RISCV.td 7.47 1.74 407 MB 139
RISCVTargetParserDef.td 0.04 0.01 7 MB 9
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
RISCV: Define macro fusion features separately from predicates (#239103)
Move the fusion tuning features to RISCVFeatures.td with the other
tuning features, and attach the predicates with SimpleFusionFor and
FusionFor. The features no longer depend on the instruction definitions.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Allow macro fusion predicates for a separate subtarget feature (#239102)
Fusion defines a subtarget feature and its fusion predicates in a single
record. The predicates reference instructions, so the feature can't be
defined without the instruction definitions. Add FusionFor and
SimpleFusionFor to attach fusion predicates to a SubtargetFeature
defined elsewhere.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[flang] Fix references to a LOCAL variable of an enclosing DO CONCURRENT (#238647)
A `REDUCE` locality-spec on a nested `DO CONCURRENT` that names a
variable with `LOCAL` or `LOCAL_INIT` locality in the enclosing `DO
CONCURRENT` crashes lowering:
```fortran
subroutine s(n, nz, work)
integer :: n, nz, work(nz), j, k, tmp
do concurrent (k=1:nz) local(tmp)
tmp = 0
do concurrent (j=1:n) reduce(max:tmp)
tmp = max(tmp, j)
end do
work(k) = tmp
end do
end subroutine
```
[67 lines not shown]
[BOLT] Connect inlined e843419 veneer block to its return target (#238108)
When an lld Cortex-A53 erratum 843419 veneer is inlined, the branch
being replaced is a tail call, so its block has no successors in the
CFG. The block then ends in the veneer's load/store with no edge to
the veneer's branch-back target. Block reordering and splitting are
free to separate the two, and fixBranches adds no branch, because a
block with no successors has no fall-through to fix up: execution
runs into whatever was laid out next.
Record the edge when inlining, and only inline over a branch that is
the block's unconditional terminator, which is what lld writes in
place of the patched load/store.
[clang][DepScan] Support subdirectory seach in getModuleMapsForModules (#238860)
Respect resolving modulemaps with
`-fmodulemap-allow-subdirectory-search` in `getModuleMapsForModules` to
match the normal scan's lookup. Note this option is default disabled.
[BOLT] Handle relative vtable slots covered by WPD aliases (#238065)
A PC-relative relocation in read-only data will be treated as a relative
vtable slot and resolved against its function symbol if and only if the
innermost data symbol containing it is a vtable. Otherwise BOLT will
treat it as a reference to S+A.
With ThinLTO split LTO units, WPD could export a hidden alias symbol
`__typeid_<id>_<offset>_unique_member` at a vtable's address point. It
inherits the vtable's size, so it extends past the vtable, is not nested
under it, and is the innermost symbol for the slots. A slot's addend is
its offset from the address point, so S+A can land inside the target
function, which is then incorrectly interpreted as having an unclaimed
internal reference and marked as non-simple.
The fix is to keep an address-sorted index of vtables, filled when
symbols are registered, and look up the vtable containing a slot
directly. Vtables do not overlap, so only the last one starting at or
before the slot can contain it. This would also handle any new kind of
[2 lines not shown]
[CodeGen] Overwrite a 0 sized alloca to have same number of bytes as it's Frame Object (#232755)
Fix: instruction selection rounds a zero-sized `alloca`'s frame object
up to one byte without updating the `alloca`, leading to bad alias
information and wrong access conclusions in BasicAA.
---
#### Context
I ran into a bug where StackColoring (on a mix of C and Rust codebase)
would collapse 1 byte LLVM IR alloca into other 0 byte LLVM IR allocas
but their FrameObject would have a min-size of 1 byte. However, when
BasicAA runs it reads the LLVM IR `alloca` to get the size, and not the
Frame Object. The LLVM IR alloca would still show 0 bytes, and this can
break BasicAA's conclusions about whether two accesses can touch the
same memory and results in bad program behaviour (e.g. wrong values,
hangs, crashes, deadlocks, etc).
[29 lines not shown]
[AMDGPU] Move the bitcast cost comments, document the i1 mask test
Put the comment about the scalarized parts of a vector bitcast above
the size check, and the comment about the shared registers inside it.
Say in the test which case @i1_mask covers.
Assisted-by: Claude Opus
[AMDGPU] Treat a bitcast between legal types as free
The generic cost model treats a bitcast as free only when both types
are integer types or both are not. AMDGPU keeps integer and
floating-point values in the same registers, so a bitcast between two
legal types is a no-op. A scalar bitcast from i32 to float cost 1, but
the vector bitcast from <2 x i32> to <2 x float> cost 0. The SLP
vectorizer counted this difference as a saving.
A bitcast that involves a type the target legalizes, such as a vector
of i8, keeps its cost, because the lanes may need repacking.
Assisted-by: Claude Opus
[AMDGPU][NFC] Add bitcast cost tests for legalized types and pointers
Add bitcasts that involve types the target legalizes, such as vectors
of i8, i24 and <2 x i24>, and bitcasts of pointers. Add a gfx7 RUN
line, where i16 and <2 x i16> are not legal.
Assisted-by: Claude Opus
[AMDGPU][NFC] Add tests for bitcasts between integer and FP types
Add cost model tests for bitcasts between integer and floating-point
types of the same size, as scalars and as vectors. Add an SLP test that
stores a pair of values bitcast from i32 to float.
Assisted-by: Claude Opus
[PseudoProbe] Avoid OOB in pseudo probe search (#239082)
There's an OOB access if `GUIDProbeFunctionMap` tries to find an invalid
GUID that over the biggest GUID. `lower_bound` returns the end of
vector, which makes the dereference invalid.
Assisted by: Opus 5.5
[libc++] Rewrite some std::allocator verify tests (#238802)
They were written in a way that makes it look like they are executed,
when in reality they aren't.
The underlying motivation for rewriting is that some of the verify
checks were written inside `assert(...)`, which made them fail if the
`assert` macro expands to nothing or expands to something that evaluates
the expression twice (both of which are terrible implementations of
assert).
Assisted by Claude
[ELF] Parallelize symbol interning while parsing files. NFC (#238701)
Looking up global symbol names in the symbol table dominates the serial
doParseFiles loop, mostly through cache misses. Shard the global symbol
map and let helper threads run ahead of the loop, interning the names of
relocatable object files in input order. Before parsing a file, the loop
waits for the helper that claimed it, or claims the file and inserts its
symbols serially.
An interned symbol is invisible to find() until SymbolTable::insert
appends it to symVector, and resolution stays serial, so the output is
unchanged. The shards are locked only while the helpers run.
```
Chromium clang (release)
--threads link (ms) parse link (ms) parse
1 +30 (+0.8%) 659 -> 690 +3 (+0.7%) 49 -> 52
2 2724 -> 2502 (-8%) 663 -> 455 347 -> 337 (-3.5%) 50 -> 40
8 1767 -> 1412 (-20%) 667 -> 313 181 -> 151 (-17%) 56 -> 24
16 1692 -> 1315 (-21%) 688 -> 326 159 -> 136 (-14%) 50 -> 25
```
[Tooling] Resolve relative "directory" against the compilation database (#235400)
JSONCompilationDatabase does not resolve a relative "directory", e.g.
`{"directory": ".", "command": "cc ../src/a.c", "file": "../src/a.c"}`.
getCompileCommands finds nothing, so clang-check reports "Compile
command not found" and clangd uses a fallback command.
getAllCompileCommands returns the directory verbatim, so each consumer
resolves it against its own working directory.
Resolve it against the directory containing compile_commands.json,
without resolving symlinks, so that paths keep the spelling clangd
receives from the editor. A compile_commands.json symlinked into the
source root is therefore relative to the source root. Since
loadFromBuffer has no file path, it takes the base directory as a new
first parameter.
LLM-aided