[SPARC] Accept rN register names in getRegisterByName (#237528)
Accept r0-r31 as names for the integer registers in llvm.read_register
and llvm.write_register, matching the %rN syntax of the assembler.
This completes #212838, which was reverted because reading %r31/%i7 in
a leaf procedure produced a use of an undefined physical register once
leaf remapping turned it into %o7. That is fixed by #236654, which adds
live-ins for reserved registers remapped in leaf procedures. The %
prefix
and the sp/fp aliases from #212838 have since been added by #234875.
Also run the test with -verify-machineinstrs, which catches that failure
without an expensive checks build.
Co-authored-by: Kirill A. Korinsky <kirill at korins.ky>
[SelectionDAG] Don't crash after an error in a callbr's asm
When a callbr's asm has an error, such as a constraint it can't satisfy,
visitInlineAsm() reports it and returns before creating the INLINEASM_BR.
But the callbr's block still got edges to the indirect targets, which
BranchFolding rejects since nothing branches there, and a landing pad in
an indirect target looked for the registers that the INLINEASM_BR would
have defined.
Don't add the edges to the indirect targets, and make a landing pad's
value poison, since nothing reaches it.
Fixes #98379 and #172657. Part of #173609, whose asm is still rejected,
since LLVM picks the "k" alternative of "+kr", which needs AVX-512.
Assisted-by: Claude Opus 5.5
[SelectionDAG] Report an error for a callbr's indirect register output
An indirect output with a register constraint, e.g. "=*r", is stored to its
pointer after the asm. But a callbr's asm can branch to an indirect target
before then, so the store was silently skipped on the indirect paths. Clang
emits such an output for a _Complex lvalue with a register constraint:
_Complex float c;
asm goto("" : "=r"(c) : : : l);
Report an error instead. A callbr without indirect targets has no such
path, so it's still allowed.
Assisted-by: Claude Opus 5.5
Replay each output's read in the indirect targets
The indirect targets re-parsed the constraints, recomputed each output's
registers and types, and paired them with the recorded registers in order,
so they were right only if both computations agreed. Record each output's
operand info and registers when lowering the callbr instead, and read them
in the indirect targets with the same code as visitInlineAsm().
This also marks a flag output's register (NZCV on AArch64, CC on SystemZ)
live into the indirect targets, as a register output's already was. And the
indirect targets no longer create virtual registers they don't use, which
renumbers some in the AArch64 test.
Assisted-by: Claude Opus 5.5
Move the asm error handling to its own PR
This PR now fixes only valid asm whose outputs crash the indirect targets.
Lowering a callbr whose asm has an error, which crashes after reporting
it, moves to its own PR stacked on this one.
Assisted-by: Claude Opus 5.5
[SelectionDAG] Read callbr outputs from the INLINEASM_BR's registers
An indirect target of a callbr found the registers holding the asm's
outputs by walking back from the callbr's exported value through COPYs to
the INLINEASM_BR, and asserted that the chain held nothing else ("start of
copy chain MUST be COPY"). An output whose type differs from its register's,
such as a float in a general-purpose register, is converted, e.g. with
MOVDI2SSrr on x86, so the assertion fired. And the target didn't convert the
output to its result type, as visitInlineAsm() does.
After an error in the asm, nothing defines the exported value, so the walk
crashed, and the callbr block kept edges to the indirect targets with no
INLINEASM_BR to branch there, which later passes reject.
Record the registers that the INLINEASM_BR defines its outputs in when
lowering the callbr, and read the outputs from them in the indirect target,
converting each to its result type as visitInlineAsm() does. After an error,
give the indirect targets undefined outputs and no edges from the callbr.
Fixes #98379, #112914, #143795, #170100, #172657, and #173609.
Remove the stale FollowCopyChain comment and unrelated comment changes
The comment that explained FollowCopyChain's walk was left above
visitCallBrLandingPad() when the walk was removed. Also put the BTI comment
in visitCallBr() back as it was, and fix a double space.
Assisted-by: Claude Opus 5.5
Test more outputs that the indirect targets convert
Add the RISC-V shape of #143795, where an i32 output is sign-extended on
each path, a float in a specific physical register on x86, a double in a
pair of registers on i686, and a flag output on AArch64, whose NZCV is now
live into the indirect target. Also check that a callbr with direct and
indirect register outputs now only reports the error.
Assisted-by: Claude Opus 5.5
[MachineCSE] Don't reuse an instruction after an INLINEASM_BR elsewhere
An INLINEASM_BR can branch to its indirect targets before the instructions
after it in its block run, but MachineCSE let those instructions replace
ones in any block that their block dominates, including the indirect
targets. E.g., when both paths out of a callbr sign-extend its output, the
indirect target reused the extension on the path to the default target and
read a register that its own path never wrote.
Reuse an instruction after an INLINEASM_BR only in its own block. MachineSink
already refuses to sink into an indirect target for the same reason.
Assisted-by: Claude Opus 5.5
[InlineAsmPrepare] Rewrite callbr result uses that indirect dests reach
updateSSA() left a use of a callbr's result alone if the callbr's default
dest dominated it. But an indirect dest can reach the default dest too,
e.g. when they're the same block or when the indirect dest branches to it,
so such a use still read the callbr's result on the indirect path.
SelectionDAG copies that result to a virtual register after the
INLINEASM_BR, on the path to the default dest only, so the indirect path
read a register that it never defined.
Leave a use alone only if the edge to the default dest dominates it, and
don't make the result the value at the end of the default dest, so that
SSAUpdater merges it with the landing pad's value there.
Assisted-by: Claude Opus 5.5
[SelectionDAG] Use the Func kind for inline asm operands only on x86 (#237504)
The only platform that currently uses the "Func" kind is x86. The other
targets aren't able to handle it. For instance, SystemZ asserts "This is
not a register operand!" and Hexagon hits an llvm_unreachable.
Gate the use of the Func kind behind a new hook
TargetLowering::supportsInlineAsmFuncOperands(), which only x86
overrides.
Assisted-by: Claude Opus 5.5
[UpdateTestChecks] Fix Windows error when piping outputs (#237636)
On Windows, `update_cc_test_checks` fails to update tests that pipe
outputs since opening an already open `NamedTemporaryFile` errors when
it's set to automatically delete. This PR fixes this by closing the file
after initially writing to it and then manually removing it.
[InstSimplify] Only fold gep of a pointer difference when the division is exact (#237685)
The `ashr` and `sdiv` folds in simplifyGEPInst (`gep V, (ashr (sub P,
V), C) -> P` and its `sdiv` form) are only correct if the divisions are
exact.
Fixes #234269.
Assisted-by: Claude Opus 5.5
[mlir][scf] fix loop specialization crash when an scf.for result is used (#236046)
the replacement `scf.if` now has the original loop result types, if the
condition is satisfied (i.e bound equal to constant) the then branch
replaces the upper bound of the cloned loop with the constant, else the
original operation with bound is cloned as such.
the yield op is created inside both the branches if there is any
resullt, the original op's result users are redirected to the `scf.if`
results and the original loop is erased.
fixes #235552
assisted by: claude
[clang][bytecode][NFC] Remove useless IsOpaqueConstantCall function (#237689)
We're already including ExprConstShared.h, which has a copy of this
function, so just use that.
[SelectionDAG] Rework `nsz` handling (#232762)
Fixes #232307, #232320, and a few other unreported miscompiles.
Since #180906, `nsz` only allows instructions to non-deterministically
flip the sign of _input_ zeros. SelectionDAG (and many other things)
still has code that assumes output zero signs can also be flipped.
My hope is that these changes will make it a bit harder to gloss over
`nsz` without thinking more carefully about it.
The `frem` regressions here are inevitable if we want correctness. If we
want to see the old codegen, we could add `nsz` consumers to the tests.
---------
Assisted-by: Claude Opus 5.5 <noreply at anthropic.com>
[SPARC][NFC] Move Leon processor scheduling information to its own file (#234160)
The itineraries in SparcSchedule.td must be included before
SparcInstrInfo.td, and that prevents InstRW definitions from being added
to SparcSchedule.td.
Keep the itinerary class definitions in SparcSchedule.td and move the
Leon specific information to SparcSchedLeon.td instead.
Assisted-by: Claude
RuntimeLibcalls: Use element alignment for vector libcall out pointers
The pointer arguments of the vector modf, sincos and sincospi functions
are linear pointers to the scalar element type (e.g. the l4 in
_ZGVnN4vl4l4_sincosf), not pointers to the vector type. Only the element
alignment is guaranteed, so stop declaring them with the ABI alignment
of the vector.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
RuntimeLibcalls: Add signatures for more runtime functions
Add type missing signatures for assorted functions which were missing
type information.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
RuntimeLibcalls: Describe vector FuncArgTypes by element type and count
Define the vector libcall argument types from an element type and
count. Derive the matching integer and mask vector types from them
instead of spelling each one out.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>