<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/mlir/test/lib/Dialect/Test/TestPatterns.cpp, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[mlir] Dialect Conversion: Add support for post-order legalization order (#166292)</title>
<updated>2025-11-05T12:04:32+00:00</updated>
<author>
<name>Matthias Springer</name>
<email>me@m-sp.org</email>
</author>
<published>2025-11-05T12:04:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=a38e0942407ef3395264831ef971838b69d2a652'/>
<id>a38e0942407ef3395264831ef971838b69d2a652</id>
<content type='text'>
By default, the dialect conversion driver processes operations in
pre-order: the initial worklist is populated pre-order. (New/modified
operations are immediately legalized recursively.)

This commit adds a new API for selective post-order legalization.
Patterns can request an operation / region legalization via
`ConversionPatternRewriter::legalize`. They can call these helper
functions on nested regions before rewriting the operation itself.

Note: In rollback mode, a failed recursive legalization typically leads
to a conversion failure. Since recursive legalization is performed by
separate pattern applications, there is no way for the original pattern
to recover from such a failure.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
By default, the dialect conversion driver processes operations in
pre-order: the initial worklist is populated pre-order. (New/modified
operations are immediately legalized recursively.)

This commit adds a new API for selective post-order legalization.
Patterns can request an operation / region legalization via
`ConversionPatternRewriter::legalize`. They can call these helper
functions on nested regions before rewriting the operation itself.

Note: In rollback mode, a failed recursive legalization typically leads
to a conversion failure. Since recursive legalization is performed by
separate pattern applications, there is no way for the original pattern
to recover from such a failure.</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir][Transforms] Dialect Conversion: Convert entry block only (#165180)</title>
<updated>2025-11-03T23:34:52+00:00</updated>
<author>
<name>Matthias Springer</name>
<email>me@m-sp.org</email>
</author>
<published>2025-11-03T23:34:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=d4c41b7fa30be06b5250c0d5abc7a26a83420321'/>
<id>d4c41b7fa30be06b5250c0d5abc7a26a83420321</id>
<content type='text'>
When converting a function, convert only the entry block signature. The
remaining block signatures should be converted by the respective
branching ops. The `FuncToLLVM` / `ControlFlowToLLVM` patterns already
use that design.

```c++
struct BranchOpLowering : public ConvertOpToLLVMPattern&lt;cf::BranchOp&gt; {

  LogicalResult
  matchAndRewrite(cf::BranchOp op, OneToNOpAdaptor adaptor,
                  ConversionPatternRewriter &amp;rewriter) const override {
    // Convert successor block.
    SmallVector&lt;Value&gt; flattenedAdaptor = flattenValues(adaptor.getOperands());
    FailureOr&lt;Block *&gt; convertedBlock =
        getConvertedBlock(rewriter, getTypeConverter(), op, op.getSuccessor(),
                          TypeRange(ValueRange(flattenedAdaptor)));
    // ...
  }
};
```

This is consistent with the fact that operations from unreachable blocks
are not put on the initial worklist.

With this change, parent ops are no longer recursively legalized when
inserting a block, simplifying the conversion driver a bit.

Note for LLVM integration: If you are seeing failures, make sure to:
- Drop `converter.isLegal(&amp;op.getBody())` when checking the legality of
a function op. Only the entry block signature / function type should be
taken into account.
- If you need to convert all reachable blocks and are using `cf`
branching ops, add `populateCFStructuralTypeConversionsAndLegality`.
- If you need to convert all reachable blocks and are using custom
branching ops, implement and populate custom structural type conversion
patterns, similar to `populateCFStructuralTypeConversionsAndLegality`.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When converting a function, convert only the entry block signature. The
remaining block signatures should be converted by the respective
branching ops. The `FuncToLLVM` / `ControlFlowToLLVM` patterns already
use that design.

```c++
struct BranchOpLowering : public ConvertOpToLLVMPattern&lt;cf::BranchOp&gt; {

  LogicalResult
  matchAndRewrite(cf::BranchOp op, OneToNOpAdaptor adaptor,
                  ConversionPatternRewriter &amp;rewriter) const override {
    // Convert successor block.
    SmallVector&lt;Value&gt; flattenedAdaptor = flattenValues(adaptor.getOperands());
    FailureOr&lt;Block *&gt; convertedBlock =
        getConvertedBlock(rewriter, getTypeConverter(), op, op.getSuccessor(),
                          TypeRange(ValueRange(flattenedAdaptor)));
    // ...
  }
};
```

This is consistent with the fact that operations from unreachable blocks
are not put on the initial worklist.

With this change, parent ops are no longer recursively legalized when
inserting a block, simplifying the conversion driver a bit.

Note for LLVM integration: If you are seeing failures, make sure to:
- Drop `converter.isLegal(&amp;op.getBody())` when checking the legality of
a function op. Only the entry block signature / function type should be
taken into account.
- If you need to convert all reachable blocks and are using `cf`
branching ops, add `populateCFStructuralTypeConversionsAndLegality`.
- If you need to convert all reachable blocks and are using custom
branching ops, implement and populate custom structural type conversion
patterns, similar to `populateCFStructuralTypeConversionsAndLegality`.</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir][CF] Add structural type conversion patterns (#165629)</title>
<updated>2025-10-30T01:12:40+00:00</updated>
<author>
<name>Matthias Springer</name>
<email>me@m-sp.org</email>
</author>
<published>2025-10-30T01:12:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=ca84e9e8260983d17f02a76de8b1ee51cd3ed896'/>
<id>ca84e9e8260983d17f02a76de8b1ee51cd3ed896</id>
<content type='text'>
Add structural type conversion patterns for CF dialect ops. These
patterns are similar to the SCF structural type conversion patterns.

This commit adds missing functionality and is in preparation of #165180,
which changes the way blocks are converted. (Only entry blocks are
converted.)</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add structural type conversion patterns for CF dialect ops. These
patterns are similar to the SCF structural type conversion patterns.

This commit adds missing functionality and is in preparation of #165180,
which changes the way blocks are converted. (Only entry blocks are
converted.)</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir] Switch uses of deprecated .create methods to free function. NFC. (#164635)</title>
<updated>2025-10-22T14:51:03+00:00</updated>
<author>
<name>Jakub Kuderski</name>
<email>jakub@nod-labs.com</email>
</author>
<published>2025-10-22T14:51:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=ae11c5c2c4d7ae4cba4a8e05f0c7d85b316a2cf0'/>
<id>ae11c5c2c4d7ae4cba4a8e05f0c7d85b316a2cf0</id>
<content type='text'>
See https://discourse.llvm.org/t/psa-opty-create-now-with-100-more-tab-complete/87339.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
See https://discourse.llvm.org/t/psa-opty-create-now-with-100-more-tab-complete/87339.</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir] Execute same operand name constraints before user constraints. (#162526)</title>
<updated>2025-10-09T23:19:47+00:00</updated>
<author>
<name>Chenguang Wang</name>
<email>w3cing@gmail.com</email>
</author>
<published>2025-10-09T23:19:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=a75565a54401571b896e1a3c60939e4dcdc0b13a'/>
<id>a75565a54401571b896e1a3c60939e4dcdc0b13a</id>
<content type='text'>
For a pattern like this:

    Pat&lt;(MyOp $x, $x),
        (...),
        [(MyCheck $x)]&gt;;

The old implementation generates:

    Pat&lt;(MyOp $x0, $x1),
        (...),
        [(MyCheck $x0),
         ($x0 == $x1)]&gt;;

This is not very straightforward, because the $x name appears in the
source pattern; it's attempting to assume equality check will be
performed as part of the source pattern matching.

This commit moves the equality checks before the other constraints,
i.e.:

    Pat&lt;(MyOp $x0, $x1),
        (...),
        [($x0 == $x1),
         (MyCheck $x0)]&gt;;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For a pattern like this:

    Pat&lt;(MyOp $x, $x),
        (...),
        [(MyCheck $x)]&gt;;

The old implementation generates:

    Pat&lt;(MyOp $x0, $x1),
        (...),
        [(MyCheck $x0),
         ($x0 == $x1)]&gt;;

This is not very straightforward, because the $x name appears in the
source pattern; it's attempting to assume equality check will be
performed as part of the source pattern matching.

This commit moves the equality checks before the other constraints,
i.e.:

    Pat&lt;(MyOp $x0, $x1),
        (...),
        [($x0 == $x1),
         (MyCheck $x0)]&gt;;</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir] Add base class type aliases for rewrites/conversions. NFC. (#158433)</title>
<updated>2025-09-15T14:59:53+00:00</updated>
<author>
<name>Jakub Kuderski</name>
<email>jakub@nod-labs.com</email>
</author>
<published>2025-09-15T14:59:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=c88f3c582dc2ef5f2fdfd0c5887f5f7562f49095'/>
<id>c88f3c582dc2ef5f2fdfd0c5887f5f7562f49095</id>
<content type='text'>
This is to simplify writing rewrite/conversion patterns that usually
start with:
```c++
struct MyPattern : public OpRewritePattern&lt;MyOp&gt; {
  using OpRewritePattern::OpRewritePattern;
```

and allow for:
```c++
struct MyPattern : public OpRewritePattern&lt;MyOp&gt; {
  using Base::Base;
```

similar to how we enable it for pass classes.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is to simplify writing rewrite/conversion patterns that usually
start with:
```c++
struct MyPattern : public OpRewritePattern&lt;MyOp&gt; {
  using OpRewritePattern::OpRewritePattern;
```

and allow for:
```c++
struct MyPattern : public OpRewritePattern&lt;MyOp&gt; {
  using Base::Base;
```

similar to how we enable it for pass classes.</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir][Transforms] Add support for `ConversionPatternRewriter::replaceAllUsesWith` (#155244)</title>
<updated>2025-09-06T09:17:55+00:00</updated>
<author>
<name>Matthias Springer</name>
<email>me@m-sp.org</email>
</author>
<published>2025-09-06T09:17:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=2929a2978cc3bdb0ff12a0e5d0a9236ff221f668'/>
<id>2929a2978cc3bdb0ff12a0e5d0a9236ff221f668</id>
<content type='text'>
This commit generalizes `replaceUsesOfBlockArgument` to
`replaceAllUsesWith`. In rollback mode, the same restrictions keep
applying: a value cannot be replaced multiple times and a call to
`replaceAllUsesWith` will replace all current and future uses of the
`from` value.

`replaceAllUsesWith` is now fully supported and its behavior is
consistent with the remaining dialect conversion API. Before this
commit, `replaceAllUsesWith` was immediately reflected in the IR when
running in rollback mode. After this commit, `replaceAllUsesWith`
changes are materialized in a delayed fashion, at the end of the dialect
conversion. This is consistent with the `replaceUsesOfBlockArgument` and
`replaceOp` APIs.

`replaceAllUsesExcept` etc. are still not supported and will be
deactivated on the `ConversionPatternRewriter` (when running in rollback
mode) in a follow-up commit.

Note for LLVM integration: Replace `replaceUsesOfBlockArgument` with
`replaceAllUsesWith`. If you are seeing failures, you may have patterns
that use `replaceAllUsesWith` incorrectly (e.g., being called multiple
times on the same value) or bypass the rewriter API entirely. E.g., such
failures were mitigated in Flang by switching to the walk-patterns
driver (#156171).

You can temporarily reactivate the old behavior by calling
`RewriterBase::replaceAllUsesWith`. However, note that that behavior is
faulty in a dialect conversion. E.g., the base
`RewriterBase::replaceAllUsesWith` implementation does not see uses of
the `from` value that have not materialized yet and will, therefore, not
replace them.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit generalizes `replaceUsesOfBlockArgument` to
`replaceAllUsesWith`. In rollback mode, the same restrictions keep
applying: a value cannot be replaced multiple times and a call to
`replaceAllUsesWith` will replace all current and future uses of the
`from` value.

`replaceAllUsesWith` is now fully supported and its behavior is
consistent with the remaining dialect conversion API. Before this
commit, `replaceAllUsesWith` was immediately reflected in the IR when
running in rollback mode. After this commit, `replaceAllUsesWith`
changes are materialized in a delayed fashion, at the end of the dialect
conversion. This is consistent with the `replaceUsesOfBlockArgument` and
`replaceOp` APIs.

`replaceAllUsesExcept` etc. are still not supported and will be
deactivated on the `ConversionPatternRewriter` (when running in rollback
mode) in a follow-up commit.

Note for LLVM integration: Replace `replaceUsesOfBlockArgument` with
`replaceAllUsesWith`. If you are seeing failures, you may have patterns
that use `replaceAllUsesWith` incorrectly (e.g., being called multiple
times on the same value) or bypass the rewriter API entirely. E.g., such
failures were mitigated in Flang by switching to the walk-patterns
driver (#156171).

You can temporarily reactivate the old behavior by calling
`RewriterBase::replaceAllUsesWith`. However, note that that behavior is
faulty in a dialect conversion. E.g., the base
`RewriterBase::replaceAllUsesWith` implementation does not see uses of
the `from` value that have not materialized yet and will, therefore, not
replace them.</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir][Transforms] Dialect conversion: Context-aware type conversions (#140434)</title>
<updated>2025-08-27T07:13:52+00:00</updated>
<author>
<name>Matthias Springer</name>
<email>me@m-sp.org</email>
</author>
<published>2025-08-27T07:13:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=337707a5417dbdc8751c2a11eda920e250417b5a'/>
<id>337707a5417dbdc8751c2a11eda920e250417b5a</id>
<content type='text'>
This commit adds support for context-aware type conversions: type
conversion rules that can return different types depending on the IR.

There is no change for existing (context-unaware) type conversion rules:
```c++
// Example: Conversion any integer type to f32.
converter.addConversion([](IntegerType t) {
  return Float32Type::get(t.getContext());
}
```

There is now an additional overload to register context-aware type
conversion rules:
```c++
// Example: Type conversion rule for integers, depending on the context:
// Get the defining op of `v`, read its "increment" attribute and return an
// integer with a bitwidth that is increased by "increment".
converter.addConversion([](Value v) -&gt; std::optional&lt;Type&gt; {
  auto intType = dyn_cast&lt;IntegerType&gt;(v.getType());
  if (!intType)
    return std::nullopt;
  Operation *op = v.getDefiningOp();
  if (!op)
    return std::nullopt;
  auto incrementAttr = op-&gt;getAttrOfType&lt;IntegerAttr&gt;("increment");
  if (!incrementAttr)
    return std::nullopt;
  return IntegerType::get(v.getContext(),
                          intType.getWidth() + incrementAttr.getInt());
});
```

For performance reasons, the type converter caches the result of type
conversions. This is no longer possible when there context-aware type
conversions because each conversion could compute a different type
depending on the context. There is no performance degradation when there
are only context-unaware type conversions.

Note: This commit just adds context-aware type conversions to the
dialect conversion framework. There are many existing patterns that
still call `converter.convertType(someValue.getType())`. These should be
gradually updated in subsequent commits to call
`converter.convertType(someValue)`.

Co-authored-by: Markus Böck &lt;markus.boeck02@gmail.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit adds support for context-aware type conversions: type
conversion rules that can return different types depending on the IR.

There is no change for existing (context-unaware) type conversion rules:
```c++
// Example: Conversion any integer type to f32.
converter.addConversion([](IntegerType t) {
  return Float32Type::get(t.getContext());
}
```

There is now an additional overload to register context-aware type
conversion rules:
```c++
// Example: Type conversion rule for integers, depending on the context:
// Get the defining op of `v`, read its "increment" attribute and return an
// integer with a bitwidth that is increased by "increment".
converter.addConversion([](Value v) -&gt; std::optional&lt;Type&gt; {
  auto intType = dyn_cast&lt;IntegerType&gt;(v.getType());
  if (!intType)
    return std::nullopt;
  Operation *op = v.getDefiningOp();
  if (!op)
    return std::nullopt;
  auto incrementAttr = op-&gt;getAttrOfType&lt;IntegerAttr&gt;("increment");
  if (!incrementAttr)
    return std::nullopt;
  return IntegerType::get(v.getContext(),
                          intType.getWidth() + incrementAttr.getInt());
});
```

For performance reasons, the type converter caches the result of type
conversions. This is no longer possible when there context-aware type
conversions because each conversion could compute a different type
depending on the context. There is no performance degradation when there
are only context-unaware type conversions.

Note: This commit just adds context-aware type conversions to the
dialect conversion framework. There are many existing patterns that
still call `converter.convertType(someValue.getType())`. These should be
gradually updated in subsequent commits to call
`converter.convertType(someValue)`.

Co-authored-by: Markus Böck &lt;markus.boeck02@gmail.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir][Transforms] Dialect conversion: Add flag to dump materialization kind (#119532)</title>
<updated>2025-08-18T13:25:18+00:00</updated>
<author>
<name>Matthias Springer</name>
<email>me@m-sp.org</email>
</author>
<published>2025-08-18T13:25:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=f84aaa6eaa316bf0a1dc5f4c7524409a3c5bf800'/>
<id>f84aaa6eaa316bf0a1dc5f4c7524409a3c5bf800</id>
<content type='text'>
Add a debugging flag to the dialect conversion to dump the
materialization kind. This flag is useful to find out whether a missing
materialization rule is for source or target materializations.

Also add missing test coverage for the `buildMaterializations` flag.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add a debugging flag to the dialect conversion to dump the
materialization kind. This flag is useful to find out whether a missing
materialization rule is for source or target materializations.

Also add missing test coverage for the `buildMaterializations` flag.</pre>
</div>
</content>
</entry>
<entry>
<title>[mlir][Transforms] Turn 1:N -&gt; 1:1 dispatch fatal error into match failure (#153605)</title>
<updated>2025-08-15T09:45:25+00:00</updated>
<author>
<name>Markus Böck</name>
<email>markus.boeck02@gmail.com</email>
</author>
<published>2025-08-15T09:45:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=8582025f1fb9485ced594efe0661ed4a4a80d5c9'/>
<id>8582025f1fb9485ced594efe0661ed4a4a80d5c9</id>
<content type='text'>
Prior to this PR, the default behaviour of a conversion pattern which
receives operands of a 1:N is to abort the compilation. This has
historically been useful when the 1:N type conversion got merged into
the dialect conversion as it allowed us to easily find patterns that
should be capable of handling 1:N type conversions but didn't.

However, this behaviour has the disadvantage of being non-composable:
While the pattern in question cannot handle the 1:N type conversion,
another pattern part of the set might, but doesn't get the chance as
compilation is aborted.

This PR fixes this behaviour by failing to match and instead of
aborting, giving other patterns the chance to legalize an op. The
implementation uses a reusable function called `dispatchTo1To1` to allow
derived conversion patterns to also implement the behaviour.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Prior to this PR, the default behaviour of a conversion pattern which
receives operands of a 1:N is to abort the compilation. This has
historically been useful when the 1:N type conversion got merged into
the dialect conversion as it allowed us to easily find patterns that
should be capable of handling 1:N type conversions but didn't.

However, this behaviour has the disadvantage of being non-composable:
While the pattern in question cannot handle the 1:N type conversion,
another pattern part of the set might, but doesn't get the chance as
compilation is aborted.

This PR fixes this behaviour by failing to match and instead of
aborting, giving other patterns the chance to legalize an op. The
implementation uses a reusable function called `dispatchTo1To1` to allow
derived conversion patterns to also implement the behaviour.</pre>
</div>
</content>
</entry>
</feed>
