[TargetInstrInfo] Address review: autogenerate greedy-inline-asm-fold.mir checks
Generate the checks with update_mir_test_checks.py so that the spills and
reloads around each folded inline asm are verified, not just the INLINEASM
itself. Fix the "=r" comment to describe the C "+r" operand, note that which
"+rm" pair greedy folds is its own choice, and add a "+&rm" case on an
uninitialized value showing that folding a pair whose tied use is undef
stores to the slot without loading from it.
Assisted-by: Claude Opus 5.5
[APFloat][NFCI] Move x87DoubleExtended next to the other native IEEE types (#223193)
Reordered the `APFloatBase::Semantics` so that `S_x87DoubleExtended` is
placed after the IEEE types and before the DoubleDouble types.
Previously, `S_x87DoubleExtended` was the very last `enum` value,
meaning that `SemanticsToEnum`/`bitcastToAPInt`/`initFromAPInt` would
test if `Sem` is one of the 13 GPU floating point types before testing
if `Sem` is `x87DoubleExtended`. Given that `x87DoubleExtended` is more
commonly used and a native LLVM IR type, I thought a better heuristic
would be to test if `Sem` is a `x87DoubleExtended` type before testing
if it is one of the 13 GPU floating point types.
I also made the order of other functions/fields more consistent across
`APFloat`.
photoc helps you review, organize, and prepare photos from the
terminal: summarize a shoot, read metadata, find blurry shots and
exact duplicates, rename and sort into folders, make contact sheets
and smaller copies, or remove GPS before sharing. Most commands
work in shell scripts; `review` needs a terminal. Inspection commands
can print JSON. Large JPEGs may use temporary in-memory previews,
which do not change the originals. photoc reads JPEG files and
metadata from Sony ARW RAW files as of now.
[TargetLowering][X86] Prefer 'r' over 'm' for foldable "rm" inline asm operands
An "rm" (register-or-memory) inline asm operand has always resolved to
'm', because getConstraintPreferences() picks the most general
constraint present, and 'm' is more general than 'r'. That's safe, since
memory can't run out, but it forces a value that could stay in a
register through a stack slot even when there's no register pressure
(https://github.com/llvm/llvm-project/issues/20571).
Prefer 'r' instead where the register allocator can fold the register
back to a stack slot when it runs out of registers, and mark the
register operand foldable (InlineAsm::Flag::setRegMayBeFolded()) so it
does. Both allocators can: the greedy allocator folds an operand when it
spills its value, and the fast allocator folds operands up front when
the asm's register operands wouldn't fit.
ParseConstraints() sets AsmOperandInfo::MayFoldRegister for an operand
whose constraint codes include 'r' and 'm' and are otherwise only
immediate codes, above -O0, on a target that opts in through the new
[26 lines not shown]
[RegAllocFast] Fold foldable inline asm operands under register pressure
An inline asm register operand marked foldable (from an "rm" constraint)
may be replaced with a stack slot when the register allocator runs out
of registers. The greedy allocator does that when it spills the value.
The fast allocator can't: it assigns the operands of an instruction one
at a time, and folding replaces the instruction. So it reported
"inline assembly requires more registers than available" instead.
Before allocating a block, estimate from each inline asm's own operands
whether they fit in registers, and fold as many foldable registers as
needed to make them fit, so the common case without pressure still gets
a register. Values that only live across the asm don't count, since the
allocator spills them when it needs their registers. The estimate
follows allocateInstruction():
- First all defs get distinct registers, avoiding physreg defs; then all
uses, along with the defs still occupied while the uses are read
(early-clobber and tied defs, see isLiveThroughDef()), get distinct
[26 lines not shown]
[CodeGen] Report an error for a direct inline asm output in memory
An inline asm output returned by value has no memory to write to, yet a
constraint such as "=rm" picks memory, the most general constraint, as
does "=m". SelectionDAG asserted on that ("Can only indirectify direct
input operands!"), and GlobalISel dereferenced a null pointer. Clang
never emits such an output, since it passes the address of a memory
output, but other IR can. Report "cannot handle direct memory outputs
yet for constraint 'm'" instead, like the other inline asm errors there.
Assisted-by: Claude Opus 5.5
[TargetInstrInfo] Fix folding inline asm operands next to tied operands
foldInlineAsmMemOperand() swapped a register operand for the target's
memory operands with MachineInstr::removeOperand(), which asserts when a
later operand is tied, because moving it would break the tie. Inline asm
lists every input after every output, so folding any operand that comes
before another tied pair asserted, e.g. an "rm" input followed by the
input of a "+r" operand, or one of two "+rm" operands. Without
assertions, the moved operands kept stale tie indices. Untie the
operands, rebuild the operand list, and re-tie the remaining pairs at
their new positions.
It also gave up when the register appears in more than one operand, e.g.
one value passed to two "rm" operands, which left the greedy allocator
unable to spill that value at all. Fold every such operand into the
stack slot.
Finally, take MayLoad from the folded operands rather than from every
read of the register: a folded def whose tied use is another virtual
[9 lines not shown]
[DebugInfo] Bound the probe loop in DWARFUnitIndex::getFromHash (#232375)
A CU/TU index with no empty slot and no matching signature made the
lookup iterate forever. Stop after NumBuckets probes, which visit every
slot of a well-formed table.
rdar://186841022
[MIR] Serialize the "foldable" inline asm register operand flag (#229626)
The symbolic MIR syntax for inline asm operand flags dropped
InlineAsm::Flag's RegMayBeFolded bit, which marks a register operand
(from an "rm" constraint) that the register allocator may fold to a
stack slot. Printing MIR and parsing it back therefore silently changed
what the allocator was allowed to do, e.g. with -stop-before and
-run-pass, and a test could only set the bit through a raw numeric flag.
Print the bit as a trailing "foldable", as MachineInstr::print() already
does, and parse it back. A tied use stores its matched operand number in
the same bits, so it never prints the marker.
Co-authored-by: Nick Desaulniers <ndesaulniers at google.com>
Co-authored-by: Bill Wendling <morbo at google.com>
[CIR] Emit references to constant-initialized const variables as const. (#231689)
This ports classic codegen's tryEmitAsConstant, so CIR folds references
to const variables with constant initializers instead of only enum
constants. That includes lambda captures, references, and static
members accessed through MemberExpr.
It fixes cir.const lowering for the constant forms.
NOTE: The changes on the classic codegen are NFC and we move code
around so that we can reuse on CIR side.
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply at anthropic.com>
[CIR] Refresh the ClangIR landing docs page (#232501)
Rewrite clang/docs/CIR/index.md as the project's front page: drop the
stale upstreaming warning, keep the design-documents toctree, and add
Using ClangIR, RFC, talks/posts, and History sections with some content
ported from the (now archived) incubator site.
[Flang] Diagnose invalid SIGNAL handler arguments (#229092)
SIGNAL accepts a procedure or scalar INTEGER as its handler argument,
but the current intrinsic matching may also accept other scalar types.
Add a SIGNAL-specific semantic check for the handler argument. This also
rejects UNSIGNED handlers when -funsigned is enabled; SIGNAL accepts
only a procedure or a scalar INTEGER handler.
Add regression tests for valid procedure/integer handlers and invalid
non-integer data arguments.
AI was used to assist with code analysis, debugging, and drafting the PR
description. I personally debugged, reviewed and verified the changes,
tested the code, and fully understand the submitted contribution.
Fixes 221193
[lldb] Replace const char * in TypeFilterImpl's interface (#232072)
Expression paths could be added either via const char * or std::string.
I'm centralizing on llvm::StringRef so it can accept any kind of string
object that we can produce.
Similarly, GetExpressionPathAtIndex will return a StringRef instead of a
const char *.