Commit Graph

17540 Commits

Author SHA1 Message Date
Ayokunle Amodu
38ad6b1983 [mlir][Affine] Fix crash in affine-loop-fusion pass by guarding against an empty op list (#144841)
Related: #139231

This patch fixes a crash in the affine-loop-fusion pass when
`getInnermostCommonLoop` is called with an empty list of operations.

The function expects at least one op to analyze, and passing an empty
array of ops causes an assertion failure. This change ensures the pass
checks for an empty op array before calling `getInnermostCommonLoop`.

@bondhugula @matthias-springer
2025-07-02 16:31:49 +02:00
Fabian Mora
bca79ec0d2 [mlir][linalg] Use ub.poison in linalg vectorizer instead of 0 for some transfer ops (#146544)
This patch is a follow up to https://github.com/llvm/llvm-project/pull/146088 and changes the padding value in the linalg vectorizer from `0` to `ub.poison` in `vector.transfer_read`s created for extracting slices or when vectorizing a generic.

Signed-off-by: Fabian Mora <fabian.mora-cordero@amd.com>
2025-07-02 10:10:03 -04:00
Mehdi Amini
6ec9b1b366 [MLIR] Remove spurious space when printing prop-dict (#145962)
When there is an elided properties, there use to be an extra space
insert in the prop-dict printing before the dictionnary.

Fix #145695
2025-07-02 14:07:17 +02:00
Matthias Springer
647aa6616f [mlir][SPIRVToLLVM] Set valid insertion point after op erasure (#146551)
Erasing/replacing an op, which is also the current insertion point,
invalidates the insertion point. Explicitly set the insertion point, so
that `copy` does not crash after the One-Shot Dialect Conversion
refactoring. (`ConversionPatternRewriter` will start behaving more like
a "normal" rewriter.)
2025-07-02 09:25:24 +02:00
Markus Böck
6c9be27b52 [mlir][tensor] Fold identity reshape of 0d-tensors (#146375)
Just like 1d-tensors, reshapes of 0d-tensors (aka scalars) are always
no-folds as they only have one possible layout. This PR adds logic to
the `fold` implementation to optimize these away as is currently
implemented for 1d tensors.
2025-07-02 09:09:03 +02:00
zbenzion
b68e8f1de7 [mlir][linalg] Allow promotion to use the original subview size (#144334)
linalg promotion attempts to compute a constant upper bound for the
allocated buffer size. Only when failed to compute an upperbound it
fallbacks to the original subview size, which may be dynamic.

Adding a promotion option to use the original subview size by default,
thus minimizing the allocation size.
Fixes #144268.
2025-07-02 08:47:51 +02:00
XiangZhang
aa1d9a4c31 [MLIR][Affine] Enhance simplifyAdd for AffineExpr mod (#146492)
Currently AffineExpr Add has ability to optimize `"s1 + (s1 // c * -c)"
to "s1 % c"`,
but can not optimize `"(s0 + s1) + (s1 // c * -c)"`. 
This patch provide an opportunity to do this simplification, let it can
be simplified to `"s0 + s1 % c"`.
2025-07-02 11:08:58 +08:00
Skrai Pardus
5ed852f7f7 [mlir][arith] Add arith::ConstantIntOp constructor (#144638)
This PR adds a `build()` constructor for `ConstantIntOp` that takes in
an `APInt`.


Creating an `arith` constant value with an `APInt` currently requires a
structure like the following:
```c
b.create<arith::ConstantOp>(IntegerAttr::get(apintValue, 5));
```
In comparison, the`ConstantFloatOp` already has an `APFloat` constructor
which allows for the following:
```c
b.create<arith::ConstantFloatOp>(floatType, apfloatValue);
```
Thus, intuitively, it makes sense that a similar `ConstantIntOp`
constructor is made for `APInts` like so:
```c
b.create<arith::ConstantIntOp>(intType, apintValue);
```

Depends on https://github.com/llvm/llvm-project/pull/144636
2025-07-01 23:50:39 +02:00
Han-Chung Wang
42578e8586 [mlir][linalg] Use hasPureTensorSemantics in TransposeMatmul methods. (#146438)
The issue is triggered by
ee070d0816
that checks `TensorLikeType` when downstream projects use the pattern
without registering bufferization::BufferizationDialect. The
registration is needed because the interface implementation for builtin
types locate at `BufferizationDialect::initialize()`. However, we do not
need to fix it by the registration. The proper fix is using the linalg
method, i.e., hasPureTensorSemantics.

No additional tests are added because the functionality is well tested
in
[transpose-matmul.mlir](https://github.com/llvm/llvm-project/blob/main/mlir/test/Dialect/Linalg/transpose-matmul.mlir).
To reproduce the issue, it requires a different setup, e.g., writing a
new C++ pass, which seems not worth it.

Signed-off-by: hanhanW <hanhan0912@gmail.com>
2025-07-01 14:15:27 -07:00
Chao Chen
5d849d3a90 [mlir][xegpu] Fix seg-fault caused by setting a null attribute (#146002) 2025-07-01 15:42:52 -05:00
Matthias Springer
d480359420 [mlir][sparse] Do not access operation after it was replaced (#146546)
Accessing an erased operation will no longer work during a One-Shot
Dialect Conversion.
2025-07-01 21:39:54 +02:00
Matthias Springer
569ca0f698 [mlir][async] Erase op later to preserve insertion point (#146516)
Delay the erasure of an op, so that the insertion point of the rewriter
remains valid.

This commit is in preparation of the One-Shot Dialect Conversion
refactoring. (The current implementation works with the current dialect
conversion driver because op erasure is delayed.)
2025-07-01 17:25:21 +02:00
Kazu Hirata
e99da2b7a9 [mlir] Remove unused includes (NFC) (#146467) 2025-07-01 07:32:44 -07:00
Ege Beysel
ace5108f37 feat(linalg): add a way to pass controlFn to foldIntoPackUnpackPatterns (#143685)
This PR adds a mechanism, so that downstream consumers can pass in
control functions for the application of these patterns. This change
shouldn't affect any consumers of this method that do not specify a
controlFn. The controlFn always gets the source operand of the consumer
in each of the patterns as a parameter.

In IREE, we (will) use it to control preventing folding patterns that
would inhibit fusion. See IREE issue
[#20896](https://github.com/iree-org/iree/issues/20896) for more
details.
2025-07-01 07:22:38 -07:00
Zhuoran Yin
8cfd9b8821 [MLIR] Make generic skip packing init operand when not used in DataLayoutPropagation (#146139)
In both `bubbleUpPackOpThroughGenericOp()` or
`pushDownUnPackOpThroughGenericOp()`, we can simplify the lowered IR by
removing the pack of an empty when the init tensor isn't used in generic
op. Instead of packing an empty tensor, the empty tensor can be
forwarded to the generic output. This allows cleaner result after data
layout propagation.
2025-07-01 09:39:30 -04:00
Nicolas Vasilache
08cf6ae537 [mlir][memref] Add a new ReifyResultShapes pass (#145927)
This pass reifies the shapes of a subset of
`ReifyRankedShapedTypeOpInterface` ops with `tensor` results.

The pass currently only supports result shape type reification for:
   - tensor::PadOp
   - tensor::ConcatOp

It addresses a representation gap where implicit op semantics are needed
to infer static result types from dynamic
operands. But it does so by using `ReifyRankedShapedTypeOpInterface` as
the source of truth rather than the op itself.
As a consequence, this cannot generalize today.

TODO: in the future, we should consider coupling this information with
op "transfer functions" (e.g.
`IndexingMapOpInterface`) to provide a source of truth that can work
across result shape inference, canonicalization and
op verifiers.

The pass replaces the operations with their reified versions, when more
static information can be derived, and inserts
casts when results shapes are updated.

Example:
```mlir
  #map = affine_map<(d0) -> (-d0 + 256)>
  func.func @func(%arg0: f32, %arg1: index, %arg2: tensor<64x?x64xf32>) -> tensor<1x?x64xf32> {
    %0 = affine.apply #map(%arg1)
    %extracted_slice = tensor.extract_slice %arg2[0, 0, 0] [1, %arg1, 64] [1, 1, 1] : tensor<64x?x64xf32> to tensor<1x?x64xf32>
    %padded = tensor.pad %extracted_slice low[0, 0, 0] high[0, %0, 0] {
    ^bb0(%arg3: index, %arg4: index, %arg5: index):
      tensor.yield %arg0 : f32
    } : tensor<1x?x64xf32> to tensor<1x?x64xf32>
    return %padded : tensor<1x?x64xf32>
  }

  // mlir-opt --reify-result-shapes
  #map = affine_map<()[s0] -> (-s0 + 256)>
  func.func @func(%arg0: f32, %arg1: index, %arg2: tensor<64x?x64xf32>) -> tensor<1x?x64xf32> {
    %0 = affine.apply #map()[%arg1]
    %extracted_slice = tensor.extract_slice %arg2[0, 0, 0] [1, %arg1, 64] [1, 1, 1] : tensor<64x?x64xf32> to tensor<1x?x64xf32>
    %padded = tensor.pad %extracted_slice low[0, 0, 0] high[0, %0, 0] {
    ^bb0(%arg3: index, %arg4: index, %arg5: index):
      tensor.yield %arg0 : f32
    } : tensor<1x?x64xf32> to tensor<1x256x64xf32>
    %cast = tensor.cast %padded : tensor<1x256x64xf32> to tensor<1x?x64xf32>
    return %cast : tensor<1x?x64xf32>
  }
  ```

---------

Co-authored-by: Fabian Mora <fabian.mora-cordero@amd.com>
2025-07-01 15:39:21 +02:00
Erich Keane
857815f3fa [OpenACC][CIR] Implement 'rest' of update clause lowering (#146414)
This implements the async, wait, if, and if_present (as well as
    device_type, but that is a detail of async/wait) lowering. All of
these are implemented the same way they are for the compute constructs,
      so this is a pretty mild amount of changes.
2025-07-01 06:05:08 -07:00
Denzel-Brian Budii
3702d64801 [mlir] Reapply 141423 mlir-query combinators plus fix (#146156)
An uninitialized variable that caused a crash
(https://lab.llvm.org/buildbot/#/builders/164/builds/11004) was
identified using the memory analyzer, leading to the reversion of
https://github.com/llvm/llvm-project/pull/141423. This pull request
reapplies the previously reverted changes and includes the fix, which
has been tested locally following the steps at
https://github.com/google/sanitizers/wiki/SanitizerBotReproduceBuild.

Note: the fix is included as part of the second commit
2025-07-01 15:03:17 +02:00
Hsiangkai Wang
f581ef5b66 [mlir][gpu] Add gpu.rotate operation (#142796)
Add gpu.rotate operation and a pattern to convert gpu.rotate to SPIR-V
OpGroupNonUniformRotateKHR.
2025-07-01 11:32:25 +01:00
Luke Hutton
698ec8c7ba [mlir][tosa] Require signless types in validation and add corresponding conversion pass (#144367)
Firstly, this commit requires that all types are signless in the strict
mode of the validation pass. This is because signless types on
operations are required by the TOSA specification. The "strict" mode in
the validation pass is the final check for TOSA conformance to the
specification, which can often be used for conversion to other formats.

In addition, a conversion pass `--tosa-convert-integer-type-to-signless`
is provided to allow a user to convert all integer types to signless.
The intention is that this pass can be run before the validation pass.
Following use of this pass, input/output information should be carried
independently by the user.
2025-07-01 10:29:53 +01:00
Yang Bai
393a75ebb7 [mlir][Vector] Add constant folding for vector.from_elements operation (#145849)
### Summary

This PR adds a new folding pattern for **vector.from_elements** that
canonicalizes it to **arith.constant** when all input operands are
constants.

### Implementation Details

**Leverages FoldAdaptor capabilities**: Uses adaptor.getElements() to
access **pre-computed** constant attributes, avoiding redundant pattern
matching on operands.

### Example Transformation
```
Before:
%c0_i32 = arith.constant 0 : i32
%c1_i32 = arith.constant 1 : i32
%c2_i32 = arith.constant 2 : i32
%c3_i32 = arith.constant 3 : i32
%v = vector.from_elements %c0_i32, %c1_i32, %c2_i32, %c3_i32 : vector<2x2xi32>

After:
%v = arith.constant dense<[[0, 1], [2, 3]]> : vector<2x2xi32>
```

---------

Co-authored-by: Yang Bai <yangb@nvidia.com>
2025-06-30 20:39:53 -07:00
Robert Konicar
163a7e1b4f [mlir][LLVMIR][NFC] Remove duplicate getUnnamedAddrAttrName uses in op printers (#146090)
Fix `UnnamedAddrAttrName` being inserted twice into the `elidedAttrs`
list for the attribute dictionary printer in `GlobalOp` and `AliasOp`
print functions.
2025-06-30 21:57:05 +02:00
Fabian Mora
878d3594ed [mlir][vector] Avoid setting padding by default to 0 in vector.transfer_read prefer ub.poison (#146088)
Context:
`vector.transfer_read` always requires a padding value. Most of its
builders take no `padding` value and assume the safe value of `0`.
However, this should be a conscious choice by the API user, as it makes
it easy to introduce bugs.
For example, I found several occasions while making this patch that the
padding value was not getting propagated (`vector.transfer_read` was
transformed into another `vector.transfer_read`). These bugs, were
always caused because of constructors that don't require specifying
padding.

Additionally, using `ub.poison` as a possible default value is better,
as it indicates the user "doesn't care" about the actual padding value,
forcing users to specify the actual padding semantics they want.

With that in mind, this patch changes the builders in
`vector.transfer_read` to always having a `std::optional<Value> padding`
argument. This argument is never optional, but for convenience users can
pass `std::nullopt`, padding the transfer read with `ub.poison`.

---------

Signed-off-by: Fabian Mora <fabian.mora-cordero@amd.com>
2025-06-30 15:20:42 -04:00
Erich Keane
a99fee6989 [OpenACC][CIR] Implement 'exit data' construct + clauses (#146167)
Similar to 'enter data', except the data clauses have a 'getdeviceptr'
operation before, so that they can properly use the 'exit' operation
correctly. While this is a touch awkward, it fits perfectly into the
existing infrastructure.

Same as with 'enter data', we had to add some add-functions for async
and wait.
2025-06-30 06:19:43 -07:00
Luke Hutton
2e7aa7ead6 [mlir][tosa] Add custom operand getters for select op (#145921)
The select op has 3 inputs: input1, input2, input3 to according to the
tosa specification. However, use of getInput1(), getInput2() and
getInput3() in the codebase can be confusing and hinder readability.
This commit adds custom getters to help improve readability:
  - input1 -> getPred()
  - input2 -> getOnTrue()
  - input3 -> getOnFalse()

They should be preferred as they are more descriptive, however, the ODS
generated getters (getInputX()) may still be used.

Unfortunately the custom getters don't propagate to Adaptors such as
`FoldAdaptor`, so the ODS generated getters must be used.
2025-06-30 10:11:09 +01:00
Jaden Angella
d4b5905a25 Addfinal specifier to the classop (#145977)
In some use cases of the `ClassOp`, eg MLGO, we would like to be able to declare the class as final. This specifier allows for that.
2025-06-29 19:00:59 -07:00
Kazu Hirata
b5cd49eff0 [mlir] Remove unused includes (NFC) (#146278)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-06-29 12:13:12 -07:00
Uday Bondhugula
80625c16f0 [MLIR][Affine] Fix memref replacement in affine-data-copy-generate (#139016)
Fixes: https://github.com/llvm/llvm-project/issues/130257

Fix affine-data-copy-generate in certain cases that involved users in
multiple blocks. Perform the memref replacement correctly during copy
generation.

Improve/clean up memref affine use replacement API. Instead of
supporting dominance and post dominance filters (which aren't adequate
in most cases) and computing dominance info expensively each time in
RAMUW, provide a user filter callback, i.e., force users to compute
dominance if needed.
2025-06-28 10:27:11 +05:30
Erich Keane
33d20828d1 [OpenACC][CIR] Implement enter-data + clause lowering (#146146)
'enter data' is a new construct type that requires one of the data
clauses, so we had to wait for all clauses to be ready before we could
commit this. Most of the clauses are simple, but there is a little bit
of work to get 'async' and 'wait' to have similar interfaces in the ACC
dialect, where helpers were added.
2025-06-27 13:47:42 -07:00
Kazu Hirata
9d6cbc3c20 [ADT] Deprecate MutableArrayRef(std::nullopt) (#146113)
ArrayRef(std::nullopt) just got deprecated.  This patch does the same
to MutableArrayRef(std::nullopt).  Since there are only a couple of
uses, this patch does migration and deprecation at the same time.
2025-06-27 11:31:11 -07:00
Momchil Velikov
3876e887d0 [MLIR][ArmSVE] Add an ArmSVE dialect operation mapping to bfmmla (#145064) 2025-06-27 15:37:13 +01:00
Erich Keane
3463aba45f [OpenACC][CIR] Implement copyin/copyout/create lowering for compute/c… (#145976)
…ombined

This patch does the lowering of copyin (represented as a
    acc.copyin/acc.delete), copyout (acc.create/acc.copyin), and create
(acc.create/acc.delete).

Additionally, it found a few problems with #144806, so it fixes those as
well.
2025-06-27 07:25:58 -07:00
Andrzej Warzyński
541f33e075 [mlir][linalg] Prevent hoisting of transfer pairs in the presence of aliases (#145235)
This patch adds additional checks to the hoisting logic to prevent hoisting of
`vector.transfer_read` / `vector.transfer_write` pairs when the underlying
memref has users that introduce aliases via operations implementing
`ViewLikeOpInterface`.

Note: This may conservatively block some valid hoisting opportunities and could
affect performance. However, as demonstrated by the included tests, the current
logic is too permissive and can lead to incorrect transformations.

If this change prevents hoisting in cases that are provably safe, please share
a minimal repro - I'm happy to explore ways to relax the check.

Special treatment is given to `memref.assume_alignment`, mainly to accommodate
recent updates in:

* https://github.com/llvm/llvm-project/pull/139521

Note that such special casing does not scale and should generally be avoided.
The current hoisting logic lacks robust alias analysis. While better support
would require more work, the broader semantics of `memref.assume_alignment`
remain somewhat unclear. It's possible this op may eventually be replaced with
the "alignment" attribute added in:

* https://github.com/llvm/llvm-project/pull/144344
2025-06-27 13:18:15 +01:00
long.chen
aed8f1992a [NFC][mlir][memref] refine debug message about memref::SubViewOp. (#145470) 2025-06-27 18:34:45 +08:00
Twice
c3e08c9b89 [MLIR] Replace getVoidPtrType with getPtrType in ConvertToLLVMPattern (#145657)
`ConversionPattern::getVoidPtrType` looks a little confusion since the
opaque pointer migration is already done. Also we cannot specify address
space in this method.

Maybe we can mark them as deprecated and add new method `getPtrType()`,
as this PR did : )
2025-06-27 12:31:53 +02:00
Christopher McGirr
96c1611163 [mlir][linalg] fix OuterUnitDims linalg.pack decomposition pattern (#141613)
Given the following example:
```
module {
  func.func @main(%arg0: tensor<1x1x1x4x1xf32>, %arg1: tensor<1x1x4xf32>) -> tensor<1x1x1x4x1xf32> {
    %pack = linalg.pack %arg1 outer_dims_perm = [1, 2, 0] inner_dims_pos = [2, 0] inner_tiles = [4, 1] into %arg0 : tensor<1x1x4xf32> -> tensor<1x1x1x4x1xf32>
    return %pack : tensor<1x1x1x4x1xf32>
  }
}
```

We would generate an invalid transpose operation because the calculated
permutation would be `[0, 2, 0]` which is semantically incorrect. As the
permutation must contain unique integers corresponding to the source
tensor dimensions.

The following change modifies how we calculate the permutation array and
ensures that the dimension indices given in the permutation array is
unique.

The above example would then translate to a transpose having a
permutation of `[1, 2, 0]`. Following the rule, that the `inner_dim_pos`
is appended to the permutation array and the preceding indices are
filled with the remaining dimensions.
2025-06-27 09:24:33 +02:00
Kazu Hirata
c7b34b0b44 [mlir] Use a new constructor of ArrayRef (NFC) (#146009)
ArrayRef now has a new constructor that takes a parameter whose type
has data() and size().  This patch migrates:

  ArrayRef<T>(X.data(), X.size()

to:

  ArrayRef<T>(X)
2025-06-26 23:38:20 -07:00
Jaden Angella
1dfdd1e6de [mlir][emitC] Add support to emitter for classop, fieldop and getfieldop (#145605)
Add support to the emitter for `ClassOp`, `FieldOp` and `GetFieldOp`.
These ops were introduced in #141158
2025-06-26 13:54:05 -07:00
Abid Qadeer
232c2921e1 Reland [mlir][OpenMP] Use correct debug location with link clause. (#145889)
https://github.com/llvm/llvm-project/pull/145026 was reverted because it
failed a sanitizer test. That issue has been fixed in
https://github.com/llvm/llvm-project/pull/145883.
2025-06-26 19:32:30 +01:00
Diego Caballero
7842e9eada [mlir][Vector] Lower vector.to_elements to LLVM (#145766)
Only elements with at least one use are lowered to `llvm.extractelement`
op.
2025-06-26 10:36:08 -07:00
Kazu Hirata
abc2c3a538 [mlir] Use llvm::is_contained instead of llvm::all_of (NFC) (#145845)
llvm::is_contained is shorter than llvm::all_of plus a lambda.
2025-06-26 08:41:26 -07:00
Kazu Hirata
70dce3d987 [mlir] Migrate away from std::nullopt (NFC) (#145842)
ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch replaces {} with std::nullopt.
2025-06-26 08:41:02 -07:00
Frank Schlimbach
2bece2194a [mlir][mesh] resubmitting #144079 (#145897)
#144079 introduced a test with an uninitialized access
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/164/builds/11140
and got reverted #145531

This PR is an exact copy of #144079 plus a trivial fix
(96c8525c82c5474d8522a973553e85a2033bee5b).
2025-06-26 16:36:17 +02:00
Nicolas Vasilache
5bf43634c4 [mlir][affine] NFC Rename SimplifyAffineMinMax -> SimplifyAffineMinMa… (#145905)
…xPass

This is more consistent re. auto-generated names like `createSimplifyAffineMinMaxPass`.
2025-06-26 16:34:47 +02:00
Nicolas Vasilache
a1d5b9d1cd [mlir][affine] Wrap SimplifyAffineMinMax in a pass (#145741)
This revision adds a pass working on FunctionOpInterface to connect recently introduced AffineMin/Max simplification patterns.

Additionally fixes some minor issues that have surfaced upon larger scale testing.
2025-06-26 15:32:51 +02:00
Benjamin Kramer
6a5469bb81 [bazel] Fixes for e5a8c51c9d 2025-06-26 15:06:18 +02:00
Nicolas Vasilache
e5a8c51c9d [mlir][tensor] Make tensor::PadOp a ReifyRankedShapedTypeOpInterface (#145867)
Co-authored-by: Fabian Mora <fmora.dev@gmail.com>
2025-06-26 14:40:57 +02:00
Benjamin Kramer
3287c1c176 [XeGPU] Move targetinfo constants to their own header file
This breaks the dependency from Dialect to Utils, which would be cyclic.
2025-06-26 13:53:00 +02:00
Andrzej Warzyński
e9e25f02e6 [mlir][vector] Restrict vector.insert/vector.extract to disallow 0-d vectors (#121458)
This patch enforces a restriction in the Vector dialect: the non-indexed
operands of `vector.insert` and `vector.extract` must no longer be 0-D
vectors. In other words, rank-0 vector types like `vector<f32>` are
disallowed as the source or result.

EXAMPLES
--------
The following are now **illegal** (note the use of `vector<f32>`):

```mlir
%0 = vector.insert %v, %dst[0, 0] : vector<f32> into vector<2x2xf32>
%1 = vector.extract %src[0, 0] : vector<f32> from vector<2x2xf32>
```

Instead, use scalars as the source and result types:

```mlir
  %0 = vector.insert %v, %dst[0, 0] : f32 into vector<2x2xf32>
  %1 = vector.extract %src[0, 0] : f32 from vector<2x2xf32>
```

Note, this change serves three goals. These are summarised below.

## 1. REDUCED AMBIGUITY
By enforcing scalar-only semantics when the result (`vector.extract`)
or source (`vector.insert`) are rank-0, we eliminate ambiguity
in interpretation. Prior to this patch, both `f32` and `vector<f32>`
were accepted.

## 2. MATCH IMPLEMENTATION TO DOCUMENTATION
The current behaviour contradicts the documented intent. For example,
`vector.extract` states:

> Degenerates to an element type if n-k is zero.

This patch enforces that intent in code.

## 3. ENSURE SYMMETRY BETWEEN INSERT AND EXTRACT
With the stricter semantics in place, it’s natural and consistent to
make `vector.insert` behave symmetrically to `vector.extract`, i.e.,
degenerate the source type to a scalar when n = 0.

NOTES FOR REVIEWERS
-------------------
1. Main change is in "VectorOps.cpp", where stricter type checks are
   implemented.
2. Test updates in "invalid.mlir" and "ops.mlir" are minor cleanups to
   remove now-illegal examples.
2. Lowering changes in "VectorToSCF.cpp" are the main trade-off: we now
   require an additional `vector.extract` when a preceding
   `vector.transfer_read` generates a rank-0 vector.

RELATED RFC
-----------
*
https://discourse.llvm.org/t/rfc-should-we-restrict-the-usage-of-0-d-vectors-in-the-vector-dialect
2025-06-26 09:47:06 +01:00
Matthias Springer
9ccf613b34 [mlir][Transforms][NFC] Store per-pattern IR modifications in separate state (#145319)
This commit adds extra state to `ConversionPatternRewriterImpl` to store
all modified / newly-created operations and moved / newly-created blocks
in separate lists on a per-pattern basis.

This is in preparation of the One-Shot Dialect Conversion refactoring:
the new driver will no longer maintain a list of all IR rewrites, so
information about newly-created operations (which is needed to trigger
recursive legalization) must be retained in a different data structure.

This commit is also expected to improve the performance of the existing
driver. The previous implementation iterated over all new IR
modifications and then filtered them by type. It also required an
additional pointer indirection (through `std::unique_ptr<IRRewrite>`) to
retrieve the operation/block pointer.
2025-06-26 08:54:39 +02:00