[SPIR-V] Add -spirv-nonsemantic-debug-info-version to select the NSDI set
The backend hardcoded NonSemantic.Shader.DebugInfo.100 as its debug-info
ext-inst set. Add a flag selecting .100 (the default) or .200.
[OpenMP] Remove the LocationDescription constructor that dropped the location. (#221949)
LocationDescription had an implicit conversion from a bare insertion
point, so `ompBuilder->emitSomething(someInsertPoint, ...)` compiled
happily and silently produced an empty debug location. Because
updateToLocation() installs the location unconditionally, this was worse
than a missing assignment: it cleared whatever the builder was carrying,
and the emitted runtime call ended up with no !dbg. On the device those
calls are inlinable, so the verifier rejects them once the runtime
carries debug info -- which is how this kept turning up as bug reports
rather than as anything visible at the callsite.
With the callers in OMPIRBuilder, OpenMPOpt, the MLIR translation and
clang all converted, the constructor can go, and the compiler will now
refuse the shape that caused the problem. Callers have to say which
location they mean: pass the IRBuilder to take its current one, or spell
out the insertion point and location as a pair.
Co-authored-by: Cursor <cursoragent at cursor.com>
[AMDGPU] Update no-modifier operand tests for the dropped align diagnostic
The no-modifier reg-or-inline operands routed through the HwMode
predicate now report a misaligned tuple as a plain invalid operand,
matching the diagnostic dropped earlier in the stack.
[AMDGPU] Route no-modifier reg-or-inline AsmParser operands through HwMode predicate
Convert the reg-or-inline operands with no modifiers (MFMA VGPR/AGPR
sources, VCSrc, v_pk_mov_b32, VOP scalar f64) from the fixed-class
isRegOrInlineNoMods to the HwMode-aware isRegOrInlineNoModsByHwMode, so an
odd-aligned tuple is rejected at the offending operand column instead of by
the validateVGPRAlign catch-all.
Co-Authored-By: Claude <noreply at anthropic.com>
[mlir][NFC] Prune unused copyArrayRefInto template (#222365)
`copyArrayRefInto` has internal linkage, so it is only reachable from
MLIRContext.cpp, and it has no callers there. It is the only mention of
the name in the MLIR tree.
An unused internal-linkage template fires -Wunused-template. That
warning is not in -Wall on main today, having been reverted by
8710728e0418, but it did ship enabled in clang 23.1.0, so building MLIR
with that released compiler under -Werror fails here:
mlir/lib/IR/MLIRContext.cpp:379:20: error: unused function template
'copyArrayRefInto' [-Werror,-Wunused-template]
This is the same deletion as one hunk of #221480, which cleans up the
same warning across 21 MLIR files and is still open. Landing that PR is
the better outcome; this is split out only because the file blocks a
release/23.x build today.
[2 lines not shown]
[InferAddressSpaces] Safely delete duplicate dead instructions (#222115)
Track deletion candidates with WeakTrackingVH so recursive deletion
cannot leave dangling pointers in later duplicate or overlapping
worklist entries.
[AMDGPU] Make custom AsmParser matchers alignment aware (#221988)
Currently custom matchers accept registers belonging to unaligned classes, leaving the alignment check and its diagnostic to validateVGPRAlign. The problem is that validateVGPRAlign does not account for the operand register class, which may have a different alignment requirement on mixed-alignment targets.
The fix is to add a custom matcher that resolves the operand's `_AlignTarget` class via HwMode and uses that resolved class to accept a register. The drawback is that this changes the diagnostic from the more specific "error: invalid register class: vgpr tuples must be 64 bit aligned" to the generic "error: invalid operand for instruction" — but keeping the specific one doesn't seem worth the effort.
This commit converts the input-mods and DP-ALU DPP matchers. The no-modifier reg-or-inline operands come next. validateVGPRAlign stays as a catch-all until every operand is converted.
Co-Authored-By: Claude [noreply at anthropic.com](mailto:noreply at anthropic.com)
[CIR] Accept a union covered only by a bit-field's declared type (#222108)
The size of a union is calculated by its largest member. When that
member is a bit-field, the unit storing it can be narrower than the type
it was declared with, and it is the declared type that accounts for the
union's bytes. BitFieldType gains a query for that declared type, and
the x86_64 union rule reads it rather than the stored size, so `union {
int x : 3; }` and `union { int x : 3; char c; }` now both pass as i32.
A union larger than one eightbyte still needs a member covering it
outright, since the coerce basis skips the entry carrying the
declaration.
Assisted-by: Cursor / claude-opus-5
[AMDGPU][MC] Diagnose bf16 inline constants without op_sel in the ass… (#223035)
…embler
GFX1250 generates a bf16 inline constant in the high half of the
corresponding fp32 inline constant. The VOP1 bf16 opcodes therefore only
read it correctly in the VOP3 encoding with op_sel[0] set:
v_cvt_f32_bf16, v_rcp_bf16, v_sqrt_bf16, v_rsq_bf16, v_log_bf16,
v_exp_bf16, v_sin_bf16, v_cos_bf16 and v_tanh_bf16.
Codegen has applied this workaround since 57a9c4f939e5, but hand-written
assembly and inline asm had no protection at all and silently assembled
to instructions that read the wrong half. Reject those forms in the
assembler.
Only single-source bf16 opcodes are affected. Multi-source and packed
bf16 instructions such as v_fma_mix*_bf16, which also have a scalar bf16
src0, are explicitly excluded.
[3 lines not shown]
[mlir][ROCDL] Carry `arch`'s xnack/sramecc onto the module
`rocdl-attach-target` rejected a target ID that pinned xnack or sramecc,
because `#rocdl.target` feeds a TargetMachine and the backend no longer
accepts those two as subtarget features. Now that the module attributes
exist, migrate them instead of refusing: `TargetInfo` gains
`migrateArchFeaturesToModuleFlags`, which records the settings the target
ID pinned as `rocdl.xnack` / `rocdl.sramecc` on a module, and
`rocdl-attach-target` calls it on each module it attaches to.
A setting the target ID leaves open, or that the GPU does not support, is
left alone rather than written as false: an absent flag means "either",
so writing false would be a different request. That also means an
attribute already on the module survives an `arch` that says nothing
about the feature, while an `arch` that does pin it wins as the more
specific request.
[mlir][AMDGPU] Keep `chipset` as a deprecated alias for `arch`
Renaming the option meant every existing invocation of these passes had
to be updated in lockstep. Accept the old spelling instead: `chipset` on
`convert-amdgpu-to-rocdl`, `convert-gpu-to-rocdl`, `convert-arith-to-amdgpu`,
`convert-math-to-rocdl` and `amdgpu-emulate-atomics`, and `chip` on
`gpu-lower-to-rocdl-pipeline`, which is what each of them was called
before the rename.
`arch` wins whenever it names a target; the alias is consulted only when
`arch` is still at the sentinel that means "no target given", so with
neither given the error still names the unusable default rather than an
empty string, and a stale alias value is reported as itself.
[mlir][AMDGPU] Take an `arch` target ID instead of triple/chip/features
`features` was a general `-mattr` string, which needed a general feature
parser and let callers ask for arbitrary combinations we have no interest
in supporting. In practice the only things anyone sets are the wavefront
size and the xnack/sramecc settings that come off a device query.
Replace `triple`, `chip` and `features` with a single `arch` option that
names the target the way Clang does, parsed by `llvm::AMDGPU::TargetID`
rather than by hand. It accepts
- a processor, with optional target-ID modifiers: `gfx942`,
`gfx942:xnack+`, `gfx9-4-generic`;
- a triple: `amdgpu9.42-amd-amdhsa`;
- a full target ID: `amdcgn-amd-amdhsa--gfx90a:sramecc+:xnack-`, which
is what `rocminfo` prints for a device's ISA, so that output can be
pasted straight in.
Since `chipset=gfx942` becomes `arch=gfx942`, migration is a rename.
[22 lines not shown]
[mlir] Migrate AMDGPU/ROCDL to targets, not chipset versions
**migration tl;dr:** `chipset=` becomes `triple=`, migrate off of
`amdgpu::Chipset` to `ROCDL::TargetInfo`, and eventually change
`gfxXYZ` to `amdgpuX.YZ-amd-amdhsa` in that `triple` argument.
`amdgpu::Chipset` was an awkward hack that was hard to keep up to date
with changes in the compiler/new architectures, and didn't properly
support generic targets (and has been strongly disfavored by the
compiler team).
This PR replaces `amdgpu::Chipset` with `ROCDL::TargetInfo`, a
structure that uses LLVM's TargetParser and the underlying LLVM
features tables to get the real nature of the target being compiled
for.
This also helps MLIR move to
new-style (`-mtriple=amdgpuX.YZ-amd-amdhsa`) over "old
style" (`-mtriple=amdgcn-amd-amdhsa -mcpu=gfxXYZ`) triples.
[40 lines not shown]
[mlir][AMDGPU][NFC] Pre-commit tests for incorrect version checks
There'll be a refactoring from `amdgpu::Chipset` to
`ROCDL::TargetInfo`, thus also moving from chip version checks to
features checks. This commit adds tests for incorrect lowerings that
were allowed by the current code.
- gfx90c is >= gfx90a but stil needs atomic emulation (it doesn't
have buffer fmax and so on).
- gfx90c is also >= gfx90a but has no barrier back-off, so it needs
the inline asm workaround around `s_barrier` that it isn't getting
- gfx908 doesn't have a packed fp16 atomic add but we thought it did
- gfx950 is mistakenly allowing xf32 MFMAs
- gfx1200 is allowing permlane_swap instructions that it doesn't have
- gfx11.7 should be allowing OCP FP8 conversions but isn't on the list
This also cleans up some redundant tests with a --check-prefixes
AI disclosure: Claude found these and wrote the tests.
[2 lines not shown]
[mlir][ROCDL] Add `rocdl.xnack` and `rocdl.sramecc` module attributes
Since 27eeb7370281, the AMDGPU backend takes the xnack
and sramecc target-ID settings from the `amdgpu.xnack` and
`amdgpu.sramecc` module flags instead subtarget features, making the
old usage a hard error.
This commit adds `rocdl.xnack` and `rocdl.sramecc` module attributes
to the discardable attribute list the ROCDL dialect defines in order
to represent these flags and adds translations for them.
Omitting them means to leave these modifiers at
their default "either" state, which isn't the same as setting them to
false.
AI disclosure: Claude wrote this code and I reviewed it and tried to
reword the comments to something better.
[AMDGPU] Form VOPD3 pairs with pair-local literal moves
VOPD3 cannot encode literal operands, but its src0 can read scalar registers.
In this PR, we try to allow to form a pair with one distinct non-inline constant
value by moving that value to a free SGPR. If both components use the same value,
one move serves both, but we reject pairs that need two different values, since
that doesn't buy us anything. Ffunctions without tracked liveness, and functions
optimized for size are also rejected.
With this change, `GCNCreateVOPD` checks every adjacent pair before it selects a
greedy non-overlapping pair. This lets an infeasible pair fall through to the
overlapping next one. We use one reverse liveness walk to find an SGPR that is
free over each pair-local range. Disjoint selected pairs can reuse the same SGPR.
Each accepted pair adds at most one `S_MOV_B32` for the one instruction removed
by fusion.
The post-RA scheduler uses the same matcher policy, so it will not cluster a
two-value pair that the create pass cannot build.
[SystemZ][z/OS] Handle constants with initializers with relocations (#223055)
When the initializer of a constant needs relocations, the constant
cannot be placed into the code section, because the loader needs a
writable section to fixup the relocation.
This change
- sets the relocation model for z/OS to `DynamicNoPIC`, which better
fits the relocation handling than `Static`, and
- treats section kind `ReadOnlyWithRel` like a variable.
Assisted by IBM Bob.
[X86] Fold FMSUBADD + FADD into VFCMADDC for fp16 (#222896)
Complex multiply by conjugate and accumulate fp16 (c += a * ~b) is
lowered into vfmsubadd + vaddph, failing to emit native vfcmaddcph in
avx512fp16. We can reuse the pattern for FSUBADD and extend
combineFaddCFmul to perform this fold.
Fixes #216290
[flang] Respect math flags during conversions (#214311)
We normally use saturating intrinsics when converting from fp to
integers, but when running with -ffast-math we can just use
fptosi/fptoui, which avoids generating expensive overflow/NAN checks.
Assisted-by: Claude Opus
[lldb] Fix library step-in when the binary is linked with MOLD (#178695)
The mold linker adds a function symbol to the symbol table (.symtab) for
every shared library exported function.
So if we try to step into a library, lldb will fail because the symbol
at the address is not a trampline function.
Example:
```cpp
// lib.c
int lib_add(int a, int b);
```
when we link the library to an executable, mold will create the normal
trampoline functions in the .plt section but add an extra symbol in
symbol table `lib_add$plt`.
[DAGCombiner] Require a 0/1 carry-in when rebuilding a borrow chain (#223396)
combineOrOfSetCCToUSUBOCarry (aae871ba1224) rewrites
carry_out = (A <u B) | ((A == B) & carry_in)
to USUBO_CARRY(A, B, carry_in), accepting any value as carry_in.
USUBO_CARRY's third operand is specified as "1 if and only if there is
an incoming carry/borrow", so 0 and 1 are its only meaningful values.
Unlike SADDO_CARRY/SSUBO_CARRY it does not fall back to
getBooleanContents for wider types. The matched `and` is bitwise against
a 0/1 setcc, so only bit 0 of carry_in reaches carry_out and nothing
else constrains it; a carry_in with any other bit set is outside the
operand's contract and miscompiles.
Require carry_in to be known 0/1. Check known bits rather than look for
an `and carry_in, 1`: only bit 0 is demanded inside the `and`, so such a
mask is usually folded away before this combine runs. An i1 carry_in,
[4 lines not shown]
[AMDGPU] Add `getLocalMemorySize` and `getAddressableLocalMemorySize` to TargetParser (#220718)
The number of SIMDs a work-group runs on is a per-kernel mode rather
than a property of the GPU, so it stays a parameter.