[CIR] Report side effects of volatile loads and memory asm operands
cir.load, cir.get_bitfield and cir.matrix.column_major_load declared only
a read of their address, so dead code elimination erased them when the
result was unused, even when the load was volatile or atomic. A cir.asm
with a memory operand such as "=*m" and no result was erased the same
way. A volatile or atomic load now also reports unknown read and write
effects, as the LLVM dialect does, and an inline asm reports a read and
a write of each memory operand.
Assisted-by: Claude Code (claude-opus-5-5).
Support: Only use aligned allocation in allocate_buffer when needed (#242674)
allocate_buffer always used aligned operator new, which is much slower
than plain operator new. Plain operator new already guarantees
__STDCPP_DEFAULT_NEW_ALIGNMENT__, which covers most callers, such as
DenseMap. Only use the aligned form for larger alignments.
CTMark instructions:u: O3 -0.13%, ThinLTO -0.12%.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[CIR] Make cir-canonicalize a full canonicalizer
cir-canonicalize applied the CIR canonicalization patterns and folders
only to a hand-written list of operations. It now builds the pattern set
once in initialize() and runs the greedy driver over every operation, so
every pattern and folder applies everywhere. Dead code elimination is
disabled: CIR stays close to the source, so unused locals and ignored
expressions are kept as in classic codegen, and only the inputs of a
folded operation can be left unused. Empty scopes and switches were
removed only because they were dead, so they get explicit
canonicalization patterns.
The pass uses the multi-op driver because the region driver always
erases blocks without a CFG predecessor, and a block that starts with
cir.label is reached only through cir.goto until the goto solver runs.
Region simplification stays off for the same reason. The new
test-convergence option fails the pass when the driver does not reach a
fixpoint, as in the upstream canonicalizer.
Assisted-by: Claude Code (claude-opus-5-5).
[flang][OpenMP] Move OmpAttributeVisitor members out of line, NFC (#242658)
The function body was getting difficult to read with many long functions
defined inline.
Co-Authored-By: Claude Opus 5 (1M context) <noreply at anthropic.com>
[llvm-objdump] Parse -mllvm options into a context (#242688)
Parse -M att/intel and -mllvm into a cl::LibraryOptionsContext instead
of the global option values, otherwise --x86-asm-syntax=att will become
unrecognized when we reject library options in the legacy
cl::ParseCommandLineOptions.
AMDGPU: Copy 16-bit arguments in 32-bit registers as i32 and truncate
A 16-bit argument passed in an SGPR, or in a VGPR without real true16,
lives in the low half of a full 32-bit register. Copy the argument as
i32 and truncate it rather than reading it with a 16-bit CopyFromReg of
the 32-bit live-in register. With real true16 a 16-bit VGPR value has its
own register class, so it is still copied directly.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[MachineLICM] Track peak register pressure when hoisting
The pressure check in MachineLICM only looks at the estimates saved in
BackTrace. These record pressure at block boundaries, so they can miss an
earlier peak in the current BB or an ancestor BB. If pressure falls before the
candidate, the check can allow it to move even though its def then needs to stay
live across that earlier peak. This can push pressure beyond the limit and cause
spills.
This PR adds PeakPressure alongside RegPressure and saves the previous peak with
the existing boundary estimate in BackTrace. The pressure check considers the
current BB's peak and both saved estimates. Normal hoists adjust the current and
saved peaks, and scope exit restores the previous peak. Preheader scanning skips
peak updates and seeds the starting pressure from its final estimate.
Fixes LCOMPILER-3233.
This PR was assisted by AI but I reviewed all the changes.
[CodeGen] Honor -stress-regalloc in register pressure limits
computePSetLimit falls back to the target pressure limit when the reserved
register weight is at least that limit. This avoids underflow, but loses
allocation restrictions such as -stress-regalloc.
Bound this fallback by the remaining allocatable register weight. The
allocatable count already includes the stress limit. Keep the existing
subtraction when it leaves a positive limit and the zero-allocation
fallback.
Add an AMDGPU MIR test for stress limits that block or allow hoisting.
Add an X86 MIR test to check that a stress value which clips no allocation
order preserves the normal pressure adjustment and hoisting result.
Update the affected AMDGPU stress test.
Validation: all 51 stress-regalloc tests pass with MachineLICM unchanged.
With the stacked MachineLICM change, the full LLVM suite has 80,791 passes
and no unexpected failures.
[2 lines not shown]
[LFI][AArch64] Do not save or restore LFI reserved registers (#241545)
Marks LFI's reserved registers using `ReserveXRegister` so that they are
omitted by calling conventions and builtins like
`__builtin_unwind_init`. Also uses `ReserveLRForRA` to mark `x30` as
reserved.
[llubi] Return poison for OOB base ptr for GEP inbounds (#242603)
Before this patch, llubi would not return poison for a getelementptr
inbounds instruction that ended up back inside the original allocation
because we never checked whether the base pointer was in bounds.
Fixes #235438
Assisted-By: LLM
Support: Only use aligned allocation in allocate_buffer when needed
allocate_buffer always used aligned operator new, which is much slower
than plain operator new. Plain operator new already guarantees
__STDCPP_DEFAULT_NEW_ALIGNMENT__, which covers most callers, such as
DenseMap. Only use the aligned form for larger alignments.
CTMark instructions:u: O3 -0.13%, ThinLTO -0.12%.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
Verifier: Check each string function attribute once
verifyFunctionAttrs looked up about 35 string attributes by name for
every function and call site. Iterate over the string attributes that
are present instead, and only look up the attributes they depend on.
Whole O3 instructions in opt:
kimwitu++ k.bc -1.03%, SPASS cnf.bc -0.34%, sqlite3 -0.12%.
CTMark instructions:u: ThinLTO -0.05%.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[RISCV] Mark that the register spill libcall clobbers X6. (#238079)
I've added a test, but it was already fixed by clobbering x6-x7
on tail calls for the restore.
Fixes #235697
[llc,llvm-mc] Remove redundant MCOptions.LibraryOptions assignments. NFC (#242672)
mc::getMCTargetOptions and codegen::getTargetOptions (#242671) now set
MCOptions.LibraryOptions to the context they read.
[MC] Set MCTargetOptions::LibraryOptions in getMCTargetOptions (#242671)
Set the `LibraryOptions` pointer in getMCTargetOptions, so that tools
like llc/llvm-mc can stop setting it by hand. With this change,
`lli -jit-kind=mcjit -x86-indirect-branch-tracking` emits no endbr64.
[InstCombine] Handle nuw in foldCmpLoadFromIndexedGlobal (#242665)
nuw is safe to handle with any stride and without masking as it means
`Offset + (Index * Stride)` can't wrap.
[IR] Remove unused private type aliases (NFC) (#242614)
AtomicCmpXchgInst::AtomicOrderingBitfieldElement and
AtomicRMWInst::AtomicOrderingBitfieldElement: The last uses were removed
on July 7, 2020 in commit abdd367b200a0bf4176dbdaf200b23f750a35cb0.
TimePassesHandler::PassInvocationID: The last uses were removed on
March 27, 2020 in commit 0125db9ab21de29191e04fe021bb675b146f2645.
Assisted-by: Antigravity
[IPO] Remove unused SampleProfileProber::CurModuleUniqueId (NFC) (#242613)
The last use was removed on April 14, 2025 in commit
8e8d04870dbc3248301534796b4370f75e33f7c0.
Assisted-by: Antigravity
DAG: Allow narrowing uint_to_fp source to the zext source type
The narrowing fold skipped uint_to_fp (zext x) when the narrow type
matched x, to avoid undoing a target combine that widened the source.
AMDGPU was the target doing this, and stopped in 50d1a75d978c. This
prevented the fold in the most direct case, so uitofp (zext i32 to i64)
was expanded as a 64-bit conversion. This also hit with topological
DAG combine ordering, where zext i16 -> i64 is first rewritten to a
zext from i32.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
AMDGPU: Add more uitofp of zext from i32 tests
These currently get the full i64 conversion expansion.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
DAG: Look through fp_extend/fp_round when folding bitcast of fcopysign (#242587)
visitFCOPYSIGN strips these from the sign operand, but the bitcast may
be visited first, leaving the conversion live in the integer form. Strip it in
the fold too, so the result does not depend on visitation order.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
RuntimeLibcalls: Mark noreturn and pure helper libcalls
Mark the functions which never return as noreturn. Add some nounwind
and cold, mostly following inferLibFuncAttributes. Mark
misc. functions as pure.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>