1965 Commits

Author SHA1 Message Date
lorenzo chelini
96c87a16a5 [MLIR][NFC] Fix comment in Region.cpp
BlockAndValueMapping has been renamed to IRMapping
2025-02-24 15:33:44 +01:00
Hongren Zheng
aa16ca3422
[mlir] Add getAlias for OpAsmTypeInterface (#126364)
See
https://discourse.llvm.org/t/rfc-introduce-opasm-type-attr-interface-for-pretty-print-in-asmprinter/83792
for detailed introduction.

This PR should be rebased once #124721 is merged.

This PR adds

* Definition of `getAlias` for `OpAsmTypeInterface`
* Integration of `OpAsmTypeInterface` with `AsmPrinter` alias handling
part

This is partly in response to
https://github.com/llvm/llvm-project/pull/124721/files#r1940399862

Cc @River707 for review.
2025-02-19 02:28:49 +08:00
Hongren Zheng
7c104b63c7
[mlir] Introduce OpAsmAttrInterface for pretty-print (#124721)
See
https://discourse.llvm.org/t/rfc-introduce-opasm-type-attr-interface-for-pretty-print-in-asmprinter/83792
for detailed introduction.

This PR adds

* Definition of `OpAsmAttrInterface`
* Integration of `OpAsmAttrInterface` with `AsmPrinter`

In
https://github.com/llvm/llvm-project/pull/121187#discussion_r1931472250
I mentioned splitting them into two PRs, but I realized that a PR with
only definition of `OpAsmAttrInterface` is hard to test as it requires a
custom Dialect with `OpAsmDialectInterface` to hook with `AsmPrinter`,
so I just put them together to have a e2e test.

Cc @River707 @jpienaar @ftynse for review.
2025-02-19 02:18:59 +08:00
Hongren Zheng
055872acc2
[mlir] Integrate OpAsmTypeInterface with AsmPrinter (#124700)
See
https://discourse.llvm.org/t/rfc-introduce-opasm-type-attr-interface-for-pretty-print-in-asmprinter/83792
for detailed introduction.

This is a follow up PR of #121187, by integrating OpAsmTypeInterface
with AsmPrinter. There are a few conditions when OpAsmTypeInterface
comes into play

* There is no OpAsmOpInterface
* Or OpAsmOpInterface::getAsmResultName/getBlockArgumentName does not
invoke `setName` (i.e. the default impl)
* All results have OpAsmTypeInterface (otherwise we can not handle
result grouping behavior)

Cc @River707 @jpienaar @ftynse for review.
2025-02-19 02:07:17 +08:00
Victor Guerra
4ac1c58a77
[mlir][NFC] Add missing ) in doc for --mlir-print-local-scope (#125721)
Signed-off-by: Victor Guerra <vguerra@gmail.com>
2025-02-13 10:43:37 +01:00
Soren Lassen
c8ca486573
[MLIR] print/parse resource handle key quoted and escaped (#119746)
resource keys have the problem that you can’t parse them from mlir
assembly if they have special or non-printable characters, but nothing
prevents you from specifying such a key when you create e.g. a
DenseResourceElementsAttr, and it works fine in other ways, including
bytecode emission and parsing

this PR solves the parsing by quoting and escaping keys with special or
non-printable characters in mlir assembly, in the same way as symbols,
e.g.:
```
module attributes {
  fst = dense_resource<resource_fst> : tensor<2xf16>,
  snd = dense_resource<"resource\09snd"> : tensor<2xf16>
} {}

{-#
  dialect_resources: {
    builtin: {
      resource_fst: "0x0200000001000200",
      "resource\09snd": "0x0200000008000900"
    }
  }
#-}
```

by not quoting keys without special or non-printable characters, the
change is effectively backwards compatible

the change is tested by:
1. adding a test with a dense resource handle key with special
characters to `dense-resource-elements-attr.mlir`
2. adding special and unprintable characters to some resource keys in
the existing lit tests `pretty-resources-print.mlir` and
`mlir/test/Bytecode/resources.mlir`
2025-02-04 13:49:15 -07:00
Hongren Zheng
3c64f86314
[mlir] Add OpAsmTypeInterface for pretty-print (#121187)
See
https://discourse.llvm.org/t/rfc-introduce-opasm-type-attr-interface-for-pretty-print-in-asmprinter/83792
for detailed introduction.

This PR acts as the first part of it
* Add `OpAsmTypeInterface` and `getAsmName` API for deducing ASM name
from type
* Add default impl in `OpAsmOpInterface` to respect this API when
available.

The `OpAsmAttrInterface` / hooking into Alias system part should be
another PR, using a `getAlias` API.

### Discussion

* Instead of using `StringRef getAsmName()` as the API, I use `void
getAsmName(OpAsmSetNameFn)`, as returning StringRef might be unsafe
(std::string constructed inside then returned a _ref_; and this aligns
with the design of `getAsmResultNames`.
* On the result packing of an op, the current approach is that when not
all of the result types are `OpAsmTypeInterface`, then do nothing (old
default impl)

### Review 

Cc @j2kun and @Alexanderviand-intel for downstream; Cc @River707 and
@joker-eph for relevent commit history; Cc @ftynse for discourse.
2025-01-28 13:31:41 +08:00
Jacques Pienaar
3b35b4c7f9
[mlir] Allow fallback from file line col range to loc (#124321)
This was discussed during the original review but I made it stricter
than discussed. Making it a pure view but adding a helper for bytecode
serialization (I could avoid the helper, but it ends up with more logic
and stronger coupling).
2025-01-24 18:08:44 -08:00
Jakub Kuderski
98de5dfe6a
[mlir] Add NamedAttribute ctor taking StringRef. NFC. (#123974)
This is a small QoL improvement so that we don't have to go through
helpers when building `NamedAttribute`s.
2025-01-22 19:02:17 -05:00
Matthias Springer
6aaa8f25b6
[mlir][IR][NFC] Move free-standing functions to MemRefType (#123465)
Turn free-standing `MemRefType`-related helper functions in
`BuiltinTypes.h` into member functions.
2025-01-21 08:48:09 +01:00
Matthias Springer
7a77f14c0a
[mlir][IR] Remove isF...() type API for low-precision FP types (#123326)
Remove `type.isFloat4E2M1FN()` etc. Use `isa<Float4E2M1FNType>(type)`
instead.

For details, see:
https://discourse.llvm.org/t/rethink-on-approach-to-low-precision-fp-types/82361/28
2025-01-20 09:22:53 +01:00
Matthias Springer
f4943464d7
[mlir][IR] Remove builder API + caching for low-precision FP types (#123321)
Remove builder API (e.g., `b.getFloat4E2M1FNType()`) and caching in
`MLIRContext` for low-precision FP types. Types are still cached in the
type uniquer.

For details, see:
https://discourse.llvm.org/t/rethink-on-approach-to-low-precision-fp-types/82361/28

Note for LLVM integration: Use `b.getType<Float4E2M1FNType>()` or
`Float4E2M1FNType::get(b.getContext())` instead of
`b.getFloat4E2M1FNType()`.
2025-01-18 10:38:51 +01:00
JoelWee
8815c505be
[MLIR] Allow setting call stack limit for SourceMgrDiagnosticHandler (#123373)
Otherwise for deeply nested code, the callstack will always be truncated
2025-01-17 17:59:18 +00:00
Emilio Cota
628976c834
Revert "[mlir] Make single value ValueRanges memory safer" (#123187)
Reverts llvm/llvm-project#121996 because it broke an emscripten build
with `--target=wasm32-unknown-emscripten`:

```
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:17: error: static assertion failed due to requirement '3U <= PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>::NumLowBitsAvailable': PointerIntPair with integer size too large for pointer
  172 |   static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:111:13: note: in instantiation of template class 'llvm::PointerIntPairInfo<void *, 3, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>' requested here
  111 |     Value = Info::updateInt(Info::updatePointer(0, PtrVal),
      |             ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:89:5: note: in instantiation of member function 'llvm::PointerIntPair<void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>::setPointerAndInt' requested here
   89 |     setPointerAndInt(PtrVal, IntVal);
      |     ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:77:16: note: in instantiation of member function 'llvm::PointerIntPair<void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>::PointerIntPair' requested here
   77 |         : Base(ValTy(const_cast<void *>(
      |                ^
llvm/llvm-project/mlir/include/mlir/IR/TypeRange.h:49:36: note: in instantiation of member function 'llvm::pointer_union_detail::PointerUnionMembers<llvm::PointerUnion<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>, llvm::PointerIntPair<void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>, 4, mlir::Type>::PointerUnionMembers' requested here
   49 |   TypeRange(Type type) : TypeRange(type, /*count=*/1) {}
      |                                    ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:25: note: expression evaluates to '3 <= 2'
  172 |   static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
      |                 ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
```
2025-01-16 11:33:13 +00:00
Matthias Springer
f023da12d1
[mlir][IR] Remove factory methods from FloatType (#123026)
This commit removes convenience methods from `FloatType` to make it
independent of concrete interface implementations.

See discussion here:
https://discourse.llvm.org/t/rethink-on-approach-to-low-precision-fp-types/82361

Note for LLVM integration: Replace `FloatType::getF32(` with
`Float32Type::get(` etc.
2025-01-16 08:56:09 +01:00
Markus Böck
ab6e63a0df
[mlir] Make single value ValueRanges memory safer (#121996)
A very common mistake users (and yours truly) make when using
`ValueRange`s is assigning a temporary `Value` to it. Example:
```cpp
ValueRange values = op.getOperand();
apiThatUsesValueRange(values);
```

The issue is caused by the implicit `const Value&` constructor: As per
C++ rules a const reference can be constructed from a temporary and the
address of it taken. After the statement, the temporary goes out of
scope and `stack-use-after-free` error occurs.

This PR fixes that issue by making `ValueRange` capable of owning a
single `Value` instance for that case specifically. While technically a
departure from the other owner types that are non-owning, I'd argue that
this behavior is more intuitive for the majority of users that usually
don't need to care about the lifetime of `Value` instances.

`TypeRange` has similarly been adopted to accept a single `Type`
instance to implement `getTypes`.
2025-01-15 18:57:11 +01:00
Matthias Springer
c24ce324d5
[mlir][IR] Turn FloatType into a type interface (#118891)
This makes it possible to add new MLIR floating point types in
downstream projects. (Adding new APFloat semantics in downstream
projects is not possible yet, so parsing/printing/converting float
literals of newly added types is not supported.)

Also removes two functions where we had to hard-code all existing
floating point types (`FloatType::classof`). See discussion here:
https://discourse.llvm.org/t/rethink-on-approach-to-low-precision-fp-types/82361

No measurable compilation time changes for these lit tests:
```
Benchmark 1: mlir-opt ./mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir -split-input-file -convert-vector-to-llvm -o /dev/null
  BEFORE
  Time (mean ± σ):     248.4 ms ±   3.2 ms    [User: 237.0 ms, System: 20.1 ms]
  Range (min … max):   243.3 ms … 255.9 ms    30 runs

  AFTER
  Time (mean ± σ):     246.8 ms ±   3.2 ms    [User: 233.2 ms, System: 21.8 ms]
  Range (min … max):   240.2 ms … 252.1 ms    30 runs


Benchmark 2: mlir-opt- ./mlir/test/Dialect/Arith/canonicalize.mlir -split-input-file -canonicalize -o /dev/null
  BEFORE
  Time (mean ± σ):      37.3 ms ±   1.8 ms    [User: 31.6 ms, System: 30.4 ms]
  Range (min … max):    34.6 ms …  42.0 ms    200 runs

  AFTER
  Time (mean ± σ):      37.5 ms ±   2.0 ms    [User: 31.5 ms, System: 29.2 ms]
  Range (min … max):    34.5 ms …  43.0 ms    200 runs


Benchmark 3: mlir-opt ./mlir/test/Dialect/Tensor/canonicalize.mlir -split-input-file -canonicalize -allow-unregistered-dialect -o /dev/null
  BEFORE
  Time (mean ± σ):     152.2 ms ±   2.5 ms    [User: 140.1 ms, System: 12.2 ms]
  Range (min … max):   147.6 ms … 161.8 ms    200 runs

  AFTER
  Time (mean ± σ):     151.9 ms ±   2.7 ms    [User: 140.5 ms, System: 11.5 ms]
  Range (min … max):   147.2 ms … 159.1 ms    200 runs
```

A micro benchmark that parses + prints 32768 floats with random
floating-point type shows a slowdown from 55.1 ms -> 48.3 ms.
2025-01-15 09:47:12 +01:00
Michael Jungmair
1fb98b5a7e
[mlir][Transforms] Make LocationSnapshotPass respect OpPrintingFlags (#119373)
The current implementation of LocationSnapshotPass takes an
OpPrintingFlags argument and stores it as member, but does not use it
for printing.

Properly implement the printing flags, also supporting command line args.

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-01-07 12:14:35 +01:00
Matthias Springer
2d424765f4
[mlir][IR][NFC] DominanceInfo: Share same impl for block/op dominance (#115587)
The `properlyDominates` implementations for blocks and ops are very
similar. This commit replaces them with a single implementation that
operates on block iterators. That implementation can be used to
implement both `properlyDominates` variants.

Before:
```c++
template <bool IsPostDom>
bool DominanceInfoBase<IsPostDom>::properlyDominatesImpl(Block *a,
                                                         Block *b) const;
template <bool IsPostDom>
bool DominanceInfoBase<IsPostDom>::properlyDominatesImpl(
    Operation *a, Operation *b, bool enclosingOpOk) const;
```

After:
```c++
template <bool IsPostDom>
bool DominanceInfoBase<IsPostDom>::properlyDominatesImpl(
    Block *aBlock, Block::iterator aIt, Block *bBlock, Block::iterator bIt,
    bool enclosingOk) const;
```

Note: A subsequent commit will add a new public `properlyDominates`
overload that accepts block iterators. That functionality can then be
used to find a valid insertion point at which a range of values is
defined (by utilizing post dominance).
2025-01-04 09:12:03 +01:00
Christopher Bate
8272b6bd61
[mlir][IR] Fix bug in AffineExpr simplifier lhs % rhs where lhs = lhs floordiv rhs (#119245)
Fixes an issue where the `SimpleAffineExprFlattener` would simplify
`lhs % rhs` to just `-(lhs floordiv rhs)` instead of 
`lhs - (lhs floordiv rhs)`
if `lhs` happened to be equal to `lhs floordiv rhs`.

The reported failure case was 
`(d0, d1) -> (((d1 - (d1 + 2)) floordiv 8) % 8)`
from https://github.com/llvm/llvm-project/issues/114654.

Note that many paths that simplify AffineMaps (e.g. the AffineApplyOp
folder and canonicalization) would not observe this bug because of
of slightly different paths taken by the code. Slightly different
grouping of the terms could also result in avoiding the bug.

Resolves https://github.com/llvm/llvm-project/issues/114654.
2024-12-18 15:22:57 -07:00
weiwei chen
644643a4ee
[mlir] Add Operation::dumpPrettyPrinted (#120117)
- [x] Add `Operation::dumpPrettyPrinted` to get more readable print
during debugging when the IR may not be able to pass verify yet.
2024-12-17 23:44:36 -05:00
Maksim Levental
f539e00c70
[mlir] add option to print SSA IDs using NameLocs as prefixes (#119996)
This PR adds an `AsmPrinter` option `-mlir-use-nameloc-as-prefix` which
uses trailing `NameLoc`s, if the source IR provides them, as prefixes
when printing SSA IDs.
2024-12-17 07:59:11 -08:00
Mehdi Amini
72e8b9aeaa
[MLIR] Add a BlobAttr interface for attribute to wrap arbitrary content and use it as linkLibs for ModuleToObject (#120116)
This change allows to expose through an interface attributes wrapping
content as external resources, and the usage inside the ModuleToObject
show how we will be able to provide runtime libraries without relying on
the filesystem.
2024-12-17 01:30:56 +01:00
Kazu Hirata
fcb1591b46
[IR] Migrate away from PointerUnion::{is,get} (NFC) (#119802)
Note that PointerUnion::{is,get} have been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

I'm not touching PointerUnion::dyn_cast for now because it's a bit
complicated; we could blindly migrate it to dyn_cast_if_present, but
we should probably use dyn_cast when the operand is known to be
non-null.
2024-12-13 08:00:45 -08:00
Ian Wood
06514c5501
[MLIR][Linalg] Fix linalg crash during elementwise op fusion (#117667)
`isOpOperandCanBeDroppedAfterFusedLinalgs` crashes when `indexingMaps`
is empty. This can occur when `producer` only has DPS init operands and
`consumer ` only has a single DPS input operand (all operands are
ignored and nothing gets added to `indexingMaps`). This is because
`concatAffineMaps` wasn't handling the maps being empty properly.


Similar to `canOpOperandsBeDroppedImpl`, I added an early return when
the maps are of size zero. Additionally, `concatAffineMaps`'s
declaration comment says it returns an empty map when `maps` is empty
but it has no way to get the `MLIRContext` needed to construct the empty
affine map when the array is empty. So, I changed this to take the
context.


__NOTE: concatAffineMaps now takes an MLIRContext to be able to
construct an empty map in the case where `maps` is empty.__

---------

Signed-off-by: Ian Wood <ianwood2024@u.northwestern.edu>
Co-authored-by: Quinn Dawkins <quinn.dawkins@gmail.com>
2024-11-26 16:00:18 -08:00
Jakub Kuderski
f4d7586343
[mlir] Use llvm::filter_to_vector. NFC. (#117655)
This got recently added to SmallVectorExtras:
https://github.com/llvm/llvm-project/pull/117460.
2024-11-26 09:11:36 -05:00
Jacques Pienaar
01e75646a5
[mlir] Add FileRange location type. (#80213)
This location type represents a contiguous range inside a file. It is
effectively a pair of FileLineCols. Add new type and make FileLineCol a
view for case where it matches existing previous one.

The location includes filename and optional start line & col, and end
line & col. Considered common cases are file:line, file:line:col,
file:line:start_col to file:line:end_col and general range within same
file. In memory its encoded as trailing objects. This keeps the memory
requirement the same as FileLineColLoc today (makes the rather common
File:Line cheaper) at the expense of extra work at decoding time. Kept the unsigned
type.

There was the option to always have file range be castable to
FileLineColLoc. This cast would just drop other fields. That may result
in some simpler staging. TBD.

This is a rather minimal change, it does not yet add bindings (C or
Python), lowering to LLVM debug locations etc. that supports end line:cols.

---------

Co-authored-by: River Riddle <riddleriver@gmail.com>
2024-11-23 05:12:04 -08:00
donald chen
dbe159b3f7
[mlir] [IR] Allow zero strides in StridedLayoutAttr (#116463)
Disabling memrefs with a stride of 0 was intended to prevent internal
aliasing, but this does not address all cases : internal aliasing can
still occur when the stride is less than the shape.

On the other hand, a stride of 0 can be very useful in certain
scenarios. For example, in architectures that support multi-dimensional
DMA, we can use memref::copy with a stride of 0 to achieve a broadcast
effect.

This commit removes the restriction that strides in memrefs cannot be 0.
2024-11-21 14:17:28 +08:00
Matthias Springer
67a1fdb014
[mlir][IR] Treat tf32 as 19-bit float (#116738)
TF32 is a variant of F32 that is truncated to 19 bits. There used to be
special handling in `FloatType::getWidth()` so that TF32 was treated as
a 32-bit float in some places. (Some places use `FloatType::getWidth`,
others directly query the `APFloat` semantics.) This caused problems
because `FloatType::getWidth` did not agree with the underlying
`APFloat` semantics.

In particular, creating an elements attr / array attr with `tf32`
element type crashed. E.g.:
```
"foo"() {attr = dense<4.0> : tensor<tf32>} : () -> ()

mlir-opt: llvm-project/llvm/lib/Support/APFloat.cpp:4108: void llvm::detail::IEEEFloat::initFromAPInt(const fltSemantics *, const APInt &): Assertion `api.getBitWidth() == Sem->sizeInBits' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
```

```
"foo"() {f32attr = array<tf32: 1024.>} : () -> ()

mlir-opt: llvm-project/mlir/lib/AsmParser/AttributeParser.cpp:847: void (anonymous namespace)::DenseArrayElementParser::append(const APInt &): Assertion `data.getBitWidth() % 8 == 0' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
```

It is unclear why the special handling for TF32 is needed. For
reference: #107372
2024-11-20 17:33:06 +09:00
Matthias Springer
804d3c4ce1
[mlir][IR] Add Block::isReachable helper function (#114928)
Add a new helper function `isReachable` to `Block`. This function
traverses all successors of a block to determine if another block is
reachable from the current block.

This functionality has been reimplemented in multiple places in MLIR.
Possibly additional copies in downstream projects. Therefore, moving it
to a common place.
2024-11-13 14:58:09 +09:00
Matthias Springer
e65c5428ad
[mlir][IR] DominanceInfo: Deduplicate properlyDominates implementation (#115433)
The implementations of `DominanceInfo::properlyDominates` and
`PostDominanceInfo::properlyPostDominates` are almost identical: only
one line of code is different (apart from the missing `enclosingOpOk`
flag). Define the function in `DominanceInfoBase` to avoid the code
duplication.

Also rename the helper in `DominanceInfoBase` to
`properlyDominatesImpl`.

Note: This commit is not marked as NFC because
`PostDominanceInfo::properlyPostDominates` now also has an
`enclosingOpOk` argument.

Depends on #115430.
2024-11-12 19:58:24 +09:00
Matthias Springer
01dcc41cb8
[mlir][IR][NFC] DominanceInfo: Minor code cleanups (#115430)
Remove `properlyDominatesImpl` and implement the functionality in
`properlyDominates` directly.
2024-11-12 18:56:57 +09:00
Matthias Springer
595f3e925a
[mlir][IR][NFC] PostDominanceInfo: Mark all functions as const (#115597)
Same as `DominanceInfo`, all functions should be `const`.
2024-11-11 11:43:04 +09:00
Matthias Springer
e4c14190bb
[mlir][IR] DominanceInfo: Fix inconsistency in proper block/op dominance (#115413)
An operation is considered to properly dominate itself in a graph
region. That's because there is no concept of "dominance" in a graph
region. (`dominates` returns "true" for all pairs of ops in the same
block. It makes sense to do the same for `properlyDominates`.)

Previously, a block was *not* considered to dominate itself in a graph
region. This commit fixes this asymmetry between ops and blocks: both
are now properly dominating themselves in a graph region.
2024-11-10 15:20:03 +09:00
Kazu Hirata
a4819d6aa3
[mlir] Simplify code with StringMap::operator[] (NFC) (#115427) 2024-11-08 07:34:31 -08:00
Kazu Hirata
6ce44266fc
[mlir] Use heterogenous lookups with std::map (NFC) (#115426)
Heterogenous lookups allow us to call find with StringRef, avoiding a
temporary heap allocation of std::string.
2024-11-08 07:33:59 -08:00
Rajveer Singh Bharadwaj
b091701d01
[mlir] Add a method on MLIRContext to retrieve the operations for a given dialect (#112344)
Currently we have `MLIRContext::getRegisteredOperations` which returns
all operations for the given context, with the addition of
`MLIRContext::getRegisteredOperationsByDialect` we can now retrieve the
same for a given dialect class.

Closes #111591
2024-10-17 12:02:24 +02:00
Nikita Popov
267be4a7f4 [MLIR] Reference issue for implicit trunc TODOs (NFC) 2024-10-17 09:03:39 +02:00
Nikita Popov
e692af8596
[MLIR] Update APInt construction to correctly set isSigned/implicitTrunc (#110466)
This fixes all the places in MLIR that hit the new assertion added in
#106524, in preparation for enabling it by default. That is, cases where
the value passed to the APInt constructor is not an N-bit
signed/unsigned integer, where N is the bit width and signedness is
determined by the isSigned flag.

The fixes either set the correct value for isSigned, or set the
implicitTrunc flag to retain the old behavior. I've left TODOs for the
latter case in some places, where I think that it may be worthwhile to
stop doing implicit truncation in the future.

Note that the assertion is currently still disabled by default, so this
patch is mostly NFC.

This is just the MLIR changes split off from
https://github.com/llvm/llvm-project/pull/80309.
2024-10-14 15:01:05 +02:00
long.chen
51a2f50ee7
[mlir][affine] fix the issue of ceildiv-mul-ceildiv form expression not satisfying commutative (#111254)
my prove:
we can simple `(n * s) ceildiv a ceildiv s` to `n ceildiv a`
because `(n * s) ceildiv a ceildiv b` <=> `(n * s) ceildiv s ceildiv a`
<=> `n ceildiv a`

let's prove the `s floordiv a floor b` <=> `s floordiv b floor a`
let `s = ka +m (m < a)` so `s floordiv a` <=> `s / a - m / a`

similarly, it can be proven that: 
`s floordiv a floordiv b` <=> `s / (a * b) - m / (a * b) - n / (b)   constrain  (n < b)` 
<=> `s / (a * b) - (m + a*n) / (a*b)`

because `a* b - (m + a*n)` <=> `a*b - a*n - m` > `a - m` > `0`
so `s floordiv a floordiv b` <=> `[s / (a*b)]` <=> `s floordiv b floordiv a`
but if `s floordiv b` mutiply a factor above didn't always hold true.

Fixes https://github.com/llvm/llvm-project/issues/107508
2024-10-12 11:25:57 -04:00
Sergey Kozub
3f9cabae00
[MLIR] Add f8E8M0FNU type (#111028)
This PR adds `f8E8M0FNU` type to MLIR.

`f8E8M0FNU` type is proposed in [OpenCompute MX
Specification](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf).
It defines a 8-bit floating point number with bit layout S0E8M0. Unlike
IEEE-754 types, there are no infinity, denormals, zeros or negative
values.

```c
f8E8M0FNU
- Exponent bias: 127
- Maximum stored exponent value: 254 (binary 1111'1110)
- Maximum unbiased exponent value: 254 - 127 = 127
- Minimum stored exponent value: 0 (binary 0000'0000)
- Minimum unbiased exponent value: 0 − 127 = -127
- Doesn't have zero
- Doesn't have infinity
- NaN is encoded as binary 1111'1111

Additional details:
- Zeros cannot be represented
- Negative values cannot be represented
- Mantissa is always 1
```

Related PRs:
- [PR-107127](https://github.com/llvm/llvm-project/pull/107127)
[APFloat] Add APFloat support for E8M0 type
- [PR-105573](https://github.com/llvm/llvm-project/pull/105573) [MLIR]
Add f6E3M2FN type - was used as a template for this PR
- [PR-107999](https://github.com/llvm/llvm-project/pull/107999) [MLIR]
Add f6E2M3FN type
- [PR-108877](https://github.com/llvm/llvm-project/pull/108877) [MLIR]
Add f4E2M1FN type
2024-10-04 09:23:12 +02:00
Aman LaChapelle
759a7b5933
[mlir] Add the ability to define dialect-specific location attrs. (#105584)
This patch adds the capability to define dialect-specific location
attrs. This is useful in particular for defining location structure that
doesn't necessarily fit within the core MLIR location hierarchy, but
doesn't make sense to push upstream (i.e. a custom use case).

This patch adds an AttributeTrait, `IsLocation`, which is tagged onto
all the builtin location attrs, as well as the test location attribute.
This is necessary because previously LocationAttr::classof only returned
true if the attribute was one of the builtin location attributes, and
well, the point of this patch is to allow dialects to define their own
location attributes.

There was an alternate implementation I considered wherein LocationAttr
becomes an AttrInterface, but that was discarded because there are
likely to be *many* locations in a single program, and I was concerned
that forcing every MLIR user to pay the cost of the additional
lookup/dispatch was unacceptable. It also would have been a *much* more
invasive change. It would have allowed for more flexibility in terms of
pretty printing, but it's unclear how useful/necessary that flexibility
would be given how much customizability there already is for attribute
definitions.
2024-10-03 10:25:44 -07:00
Shoaib Meenai
8773bd0e6e
[mlir] Print aliases for recursive types (#110346)
We're already keeping track of the alias depth to ensure that aliases
are printed before they're referenced. For recursive types, we can
additionally track whether an alias has been printed and only reference
it if so, to lift the restrictions on not printing aliases inside
mutable types.
2024-09-28 18:15:14 -07:00
Andrzej Warzyński
6d11494414
[mlir][Linalg] Refine how broadcast dims are treated (#99015)
This PR fixes how broadcast dims (identified as "zero" results in
permutation maps) corresponding to a reduction iterator are vectorised
in the case of generic Ops. Here's an example:

```mlir
  #map = affine_map<(d0, d1, d2, d3) -> (d0, d1, d2, d3)>
  #map1 = affine_map<(d0, d1, d2, d3) -> (d0, d1, d2, 0)>

  func.func @generic_with_reduction_and_broadcast(%arg0: tensor<1x12x197x197xf32>) -> (tensor<1x12x197x1xf32>) {
    %0 = tensor.empty() : tensor<1x12x197x1xf32>

    %1 = linalg.generic {indexing_maps = [#map, #map1],
                        iterator_types = ["parallel", "parallel", "parallel", "reduction"]}
      ins(%arg0 : tensor<1x12x197x197xf32>)
      outs(%0 : tensor<1x12x197x1xf32>) {

    ^bb0(%in: f32, %out: f32):
      %818 = arith.addf %in, %out : f32
      linalg.yield %818 : f32
    } -> tensor<1x12x197x1xf32>
    return %1 : tensor<1x12x197x1xf32>
  }
```

This is a perfectly valid Generic Op, but currently triggers two issues
in the vectoriser. The root cause is this map:

```mlir
  #map1 = affine_map<(d0, d1, d2, d3) -> (d0, d1, d2, 0)>
```

This map triggers an assert in `reindexIndexingMap` -  this hook
incorrectly assumes that every result in the input map is a `dim`
expression and that there are no constants. That's not the case in this
example. `reindexIndexingMap` is extended to allow maps like the one
above. For now, only constant "zero" results are allowed. This can be
extended in the future once a good motivating example is available.

Separately, the permutation map highlighted above "breaks" mask
calculation (ATM masks are always computed, even in the presence of
static shapes). When applying the following permutation:
```mlir
  (d0, d1, d2, d3) -> (d0, d1, d2, 0)
```

to these canonical shapes (corresponding to the example above):
```
  (1, 12, 197, 197)
```
we end up with the following error:
```bash
error: vector types must have positive constant sizes but got 1, 12, 197, 0
```

The error makes sense and indicates that we should update the
permutation map above to:
```
  (d0, d1, d2, d3) -> (d0, d1, d2)
```

This would correctly give the following vector type:
```
  vector<1x12x197xi1>
```

Fixes #97247
2024-09-26 16:17:15 +01:00
Sergey Kozub
2c58063435
[MLIR] Add f4E2M1FN type (#108877)
This PR adds `f4E2M1FN` type to mlir.

`f4E2M1FN` type is proposed in [OpenCompute MX
Specification](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf).
It defines a 4-bit floating point number with bit layout S1E2M1. Unlike
IEEE-754 types, there are no infinity or NaN values.

```c
f4E2M1FN
- Exponent bias: 1
- Maximum stored exponent value: 3 (binary 11)
- Maximum unbiased exponent value: 3 - 1 = 2
- Minimum stored exponent value: 1 (binary 01)
- Minimum unbiased exponent value: 1 − 1 = 0
- Has Positive and Negative zero
- Doesn't have infinity
- Doesn't have NaNs

Additional details:
- Zeros (+/-): S.00.0
- Max normal number: S.11.1 = ±2^(2) x (1 + 0.5) = ±6.0
- Min normal number: S.01.0 = ±2^(0) = ±1.0
- Min subnormal number: S.00.1 = ±2^(0) x 0.5 = ±0.5
```

Related PRs:
- [PR-95392](https://github.com/llvm/llvm-project/pull/95392) [APFloat]
Add APFloat support for FP4 data type
- [PR-105573](https://github.com/llvm/llvm-project/pull/105573) [MLIR]
Add f6E3M2FN type - was used as a template for this PR
- [PR-107999](https://github.com/llvm/llvm-project/pull/107999) [MLIR]
Add f6E2M3FN type
2024-09-24 08:22:48 +02:00
wang-y-z
041b0a81b0
[MLIR][Operation] Fix isBeforeInBlock crash bug mentioned in https://github.com/llvm/llvm-project/issues/60909 (#101172)
# summary
This MR fix `isBeforeInBlock` crash bug mentioned in
https://github.com/llvm/llvm-project/issues/60909. Fixes #60909.
# Trigger condition
1. A block only have one operation.
2. `block->isOpOrderValid()` is true, but `op->hasValidOrder()` is
false.
3. call: `op->isBeforeInBlock(op)`, compared with op itself.

Will crash on `assert(blockFront != blockBack && "expected more than one
operation");`

# Case study
Simplified repro case in
`mlir/test/Pass/scf2cf-print-liveness-crash.mlir`
When put `-convert-scf-to-cf -test-print-liveness` together in one cmd
line, the first pass will work normally and crash on the second pass.
Details please refer  https://github.com/llvm/llvm-project/issues/60909

# Solutions
option1. in `isBeforeInBlock`, check if block only have one operation
before step into `updateOrderIfNecessary`, if have only one, it must
return false
option2. in `isBeforeInBlock`, check if `this == other`, if true return
false
option3. fix `addNodeToList` logic

I prefer option3: 

When a block contains only one operation and the user calls
op->isBeforeInBlock(op), if block->isOpOrderValid() returns true,
updateOrderIfNecessary is called. If op->hasValidOrder() is false, it
will crash at the assertion assert(blockFront != blockBack && "expected
more than one operation");.

This behavior is abnormal and needs fixing. I discovered that after the
first pass of `-convert-scf-to-cf`, there is a block with only one
operation where the block order is valid but the operation order is
invalid, leading to a crash when `-test-print-liveness` pass runs.

---------

Co-authored-by: isaacw <isaacw@nvidia.com>
2024-09-21 23:40:52 +08:00
Billy Zhu
a1d64626ba
[MLIR][IR] Fix InProgressAliasInfo init for non-alias (#109013)
When visiting an attr/type that is NoAlias, the created
`InProgressAliasInfo` was not getting its `canBeDeferred` and `isType`
fields set. Not setting `canBeDeferred` when it should be true breaks
the assumption that all nested elements are also false. This will cause
problems when at a later point the attr/type needs to be converted by
`markAliasNonDeferrable`, as recursion will stop when a
`canBeDeferred=false` attr/type is reached, leaving its nested elements
not flipped. This causes nested elements to be printed later in the
textual IR and cannot be parsed back in.
2024-09-17 14:27:31 -07:00
JOE1994
884221eddb [mlir] Tidy uses of llvm::raw_stream_ostream (NFC)
As specified in the docs,
1) raw_string_ostream is always unbuffered and
2) the underlying buffer may be used directly

( 65b13610a5226b84889b923bae884ba395ad084d for further reference )

* Don't call raw_string_ostream::flush(), which is essentially a no-op.
* Avoid unneeded calls to raw_string_ostream::str(), to avoid excess indirection.
2024-09-16 23:23:25 -04:00
Sergey Kozub
73d83f20c9
[MLIR] Add f6E2M3FN type (#107999)
This PR adds `f6E2M3FN` type to mlir.

`f6E2M3FN` type is proposed in [OpenCompute MX
Specification](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf).
It defines a 6-bit floating point number with bit layout S1E2M3. Unlike
IEEE-754 types, there are no infinity or NaN values.

```c
f6E2M3FN
- Exponent bias: 1
- Maximum stored exponent value: 3 (binary 11)
- Maximum unbiased exponent value: 3 - 1 = 2
- Minimum stored exponent value: 1 (binary 01)
- Minimum unbiased exponent value: 1 − 1 = 0
- Has Positive and Negative zero
- Doesn't have infinity
- Doesn't have NaNs

Additional details:
- Zeros (+/-): S.00.000
- Max normal number: S.11.111 = ±2^(2) x (1 + 0.875) = ±7.5
- Min normal number: S.01.000 = ±2^(0) = ±1.0
- Max subnormal number: S.00.111 = ±2^(0) x 0.875 = ±0.875
- Min subnormal number: S.00.001 = ±2^(0) x 0.125 = ±0.125
```

Related PRs:
- [PR-94735](https://github.com/llvm/llvm-project/pull/94735) [APFloat]
Add APFloat support for FP6 data types
- [PR-105573](https://github.com/llvm/llvm-project/pull/105573) [MLIR]
Add f6E3M2FN type - was used as a template for this PR
2024-09-16 21:09:27 +02:00
Sergey Kozub
083e25c1d4
[MLIR] [NFC] Use APFloat semantics to get floating type width (#107372)
As suggested in the comments of
https://github.com/llvm/llvm-project/pull/105573
2024-09-10 10:50:34 +02:00