[AMDGPU] Canonicalize num_records to its actual width in InstCombine
llvm.amdgcn.make.buffer.rsrc is overloaded on the type of its
num_records argument, but the hardware field it ends up in has a fixed
width (32 bits, or 45 bits on gfx1250 and up). Rewrite the intrinsic to
use that width, zero-extending or truncating num_records as needed, so
that IR-level optimizations can see that the extra bits of, for example,
the i64 that Clang emits are not demanded.
Targets that aren't concrete enough for the buffer resource layout to be
known are left alone.
AI disclosure: This was my idea but Claude wrote the code (and I've
tried to tighten up the comments)
[AMDGPU] Pre-commit tests for num_records canonicalization
Add tests for having InstCombine canonicalize the num_records argument
of llvm.amdgcn.make.buffer.rsrc to the width it will ultimately have,
which lets later passes see that, for example, the high bits of the i64
that Clang emits aren't used.
AI disclosure: Claude generated these and I've looked at them
[mlir][AMDGPU] Emit num_records at the buffer resource's actual width
makeBufferRsrc() zero-extended num_records to i64 on targets whose
buffer resource has a 45-bit num_records field, leaving 19 bits that the
hardware will never look at. Emit an i45 instead, which is what
rocdl.make.buffer.rsrc will end up putting in the descriptor anyway, so
that downstream consumers can see that those bits aren't demanded.
While here, factor the i32 and i64 conversion helpers into a shared
convertUnsignedToInt() that takes the target width.
AI disclosure: Claude made this, I looked at and poked the design into
shape.
[AMDGPU] Use real num_records width in LowerBufferFatPointers
Fix the following edge cases in reasoning about whether a value can be
The out-of-bounds analysis in LowerBufferFatPointers took the
num_records operand of llvm.amdgcn.make.buffer.rsrc at face value, which
went wrong in three ways.
1. The pass would crash if num_records was narrower than the
underlying hardware width.
2. A 45-bit num_records with its high bit set made all offsets look
negative, which, among other things, broke the `(1 << 45) - 1` "no
bounds checking" value.
3. The test for all-1 num_records wasn't accounting for hardware
width, leading to false positives if the num_records field was
narrower tan the underlying field.
4. Don't try to do reasoning about num_records when its width isn't
known.
AI disclosure: Claude found and took a try at fixing these, I've
reviewed
[AMDGPU] Pre-commit num_records of arbitrary width tests for LowerBufferFatPointers
Add tests to ensure that the reasoning for whether an access can be
partially out of bounds and needs to be scalarized work correctly when
num_records has a width different from the hardware width.
AI disclosure: Claude generated these and I've looked at them
[AMDGPU] Track buffer resource num_records width in a subtarget field
Replace the boolean 45-bit-num-records-buffer-resource subtarget
feature's `Has45BitNumRecordsBufferResource` flag with a numeric
`BufferResourceNumRecordsWidth` field.
AI disclosure: Code by Claude, comments and wordings by me
[Clang] Improve concept diagnostics (#218618)
We used to drop SFINAE errors that occurred during parameter mapping
instantiation
on the floor, making our diagnostics worse for some cases.
This patch corrects that behavior. Moreover it fixes some clients where
the errors were not properly handled for invalid expressions.
Fixes https://github.com/llvm/llvm-project/issues/144053
math/scilab: chase the upgrade of math/matio to 1.6.0
The recent upgrade of matio broke Scilab, because Scilab only test
the minor version MATIO_RELEASE_LEVEL and not the full string.
Reported by: pkg-fallout
arm: Quote diagnostic message
The C standard does not require diagnostic messages to be quoted, but
some tools get confused by unbalanced quotes such as the apostrophe in
“don't”. Wrap this message in double quotes to resolve the confusion.
Sponsored by: Klara, Inc.
Sponsored by: NetApp, Inc.
[AMDGPU] Canonicalize num_records to its actual width in InstCombine
llvm.amdgcn.make.buffer.rsrc is overloaded on the type of its
num_records argument, but the hardware field it ends up in has a fixed
width (32 bits, or 45 bits on gfx1250 and up). Rewrite the intrinsic to
use that width, zero-extending or truncating num_records as needed, so
that IR-level optimizations can see that the extra bits of, for example,
the i64 that Clang emits are not demanded.
Targets that aren't concrete enough for the buffer resource layout to be
known are left alone.
AI disclosure: This was my idea but Claude wrote the code (and I've
tried to tighten up the comments)
[AMDGPU] Pre-commit tests for num_records canonicalization
Add tests for having InstCombine canonicalize the num_records argument
of llvm.amdgcn.make.buffer.rsrc to the width it will ultimately have,
which lets later passes see that, for example, the high bits of the i64
that Clang emits aren't used.
AI disclosure: Claude generated these and I've looked at them
[AMDGPU] Use real num_records width in LowerBufferFatPointers
Fix the following edge cases in reasoning about whether a value can be
The out-of-bounds analysis in LowerBufferFatPointers took the
num_records operand of llvm.amdgcn.make.buffer.rsrc at face value, which
went wrong in three ways.
1. The pass would crash if num_records was narrower than the
underlying hardware width.
2. A 45-bit num_records with its high bit set made all offsets look
negative, which, among other things, broke the `(1 << 45) - 1` "no
bounds checking" value.
3. The test for all-1 num_records wasn't accounting for hardware
width, leading to false positives if the num_records field was
narrower tan the underlying field.
4. Don't try to do reasoning about num_records when its width isn't
known.
AI disclosure: Claude found and took a try at fixing these, I've
reviewed
[mlir][AMDGPU] Emit num_records at the buffer resource's actual width
makeBufferRsrc() zero-extended num_records to i64 on targets whose
buffer resource has a 45-bit num_records field, leaving 19 bits that the
hardware will never look at. Emit an i45 instead, which is what
rocdl.make.buffer.rsrc will end up putting in the descriptor anyway, so
that downstream consumers can see that those bits aren't demanded.
While here, factor the i32 and i64 conversion helpers into a shared
convertUnsignedToInt() that takes the target width.
AI disclosure: Claude made this, I looked at and poked the design into
shape.
[AMDGPU] Pre-commit num_records of arbitrary width tests for LowerBufferFatPointers
Add tests to ensure that the reasoning for whether an access can be
partially out of bounds and needs to be scalarized work correctly when
num_records has a width different from the hardware width.
AI disclosure: Claude generated these and I've looked at them
[AMDGPU] Track buffer resource num_records width in a subtarget field
Replace the boolean 45-bit-num-records-buffer-resource subtarget
feature's `Has45BitNumRecordsBufferResource` flag with a numeric
`BufferResourceNumRecordsWidth` field.
AI disclosure: Code by Claude, comments and wordings by me
[SelectionDAG] Preserve CTTZ_ELTS lane count during expansion (#217982)
Fixes #216649
`expandCttzElts` derives `VL` from its legalized auxiliary step vector.
When that helper vector is widened for target legality, its lane count
may differ from the logical lane count of the `CTTZ_ELTS` operand.
On X86 with AVX512F, the step vector for a semantic `<4 x i1>` mask is
widened from `v4i8` to `v16i8`. As a result, an all-zero
`llvm.experimental.cttz.elts` input returns 16 instead of the required
result of 4.
Preserve the `ElementCount` from the `CTTZ_ELTS` operand and use it when
materializing `VL`. Auxiliary step-vector legalization can still widen
its representation without changing the logical lane domain of the
operation.
Add AVX512F regression coverage for the affected `v4i1` and `v8i1`
cases.
[LLVMABI] Skip data-free members when reducing a union (#218532)
While implementing union support for ClangIR, I found that
`reduceUnionForX8664` can choose a member holding no data as the type
representing the union. It chooses by alignment and then by size, and an
over-aligned empty class or an array of empty records wins either
comparison, so the coercion comes out wider than Clang's.
Clang does not need this skip because it compares lowered types, where
an empty class is a byte array it can narrow the coercion through. A
record reaching this library has no fields, so there is nothing to
narrow through.
This change skips members holding no data, using `bitsContainNoUserData`
to identify them.
Assisted-by: Cursor / claude-opus-5
[CIR] Update CHECK lines for the nofreeobj rename
#218404 renamed classic's indirect-argument attribute from nofree to
nofreeobj. Five OGCG lines across two tests still pinned the
old spelling.
Assisted-by: Cursor / claude-opus-5