Commit Graph

518 Commits

Author SHA1 Message Date
Sean Silva 84a6da67e6 [mlir] Fix some edge cases around 0-element TensorFromElementsOp
This introduces a builder for the more general case that supports zero
elements (where the element type can't be inferred from the ValueRange,
since it might be empty).

Also, fix up some cases in ShapeToStandard lowering that hit this. It
happens very easily when dealing with shapes of 0-D tensors.

The SameOperandsAndResultElementType is redundant with the new
TypesMatchWith and prevented having zero elements.

Differential Revision: https://reviews.llvm.org/D87492
2020-09-11 10:58:35 -07:00
MaheshRavishankar 0a391c6079 [mlir][Analysis] Allow Slice Analysis to work with linalg::LinalgOp
Differential Revision: https://reviews.llvm.org/D87307
2020-09-10 18:54:22 -07:00
Frederik Gossen 018f6936db [MLIR][Standard] Simplify `tensor_from_elements`
Define assembly format and add required traits.

Differential Revision: https://reviews.llvm.org/D87366
2020-09-10 14:42:51 +00:00
Frederik Gossen 133322d2e3 [MLIR][Standard] Update `tensor_from_elements` assembly format
Remove the redundant parenthesis that are used for none of the other operation
formats.

Differential Revision: https://reviews.llvm.org/D86287
2020-09-09 07:45:46 +00:00
Mehdi Amini 63d1dc6665 Add a doc/tutorial on traversing the IR
Reviewed By: stephenneuendorffer

Differential Revision: https://reviews.llvm.org/D87221
2020-09-08 00:07:03 +00:00
Kazuaki Ishizaki a23d055912 [mlir] NFC: fix trivial typo under test and tools
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D86648
2020-08-27 15:37:42 +09:00
Rob Suderman 5556575230 Added std.floor operation to match std.ceil
There should be an equivalent std.floor op to std.ceil. This includes
matching lowerings for SPIRV, NVVM, ROCDL, and LLVM.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D85940
2020-08-18 10:25:32 -07:00
Alex Zinenko 674f2df4fe [mlir] Fix printing of unranked memrefs in non-default memory space
The type printer was ignoring the memory space on unranked memrefs.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D86096
2020-08-18 09:32:35 +02:00
Mehdi Amini de71b46a51 Add missing parsing for attributes to std.generic_atomic_rmw op
Fix llvm.org/pr47182

Differential Revision: https://reviews.llvm.org/D86030
2020-08-16 22:13:58 +00:00
Sean Silva b0d76f454d [mlir] Centralize handling of memref element types.
This also beefs up the test coverage:
- Make unranked memref testing consistent with ranked memrefs.
- Add testing for the invalid element type cases.

This is not quite NFC: index types are now allowed in unranked memrefs.

Differential Revision: https://reviews.llvm.org/D85541
2020-08-07 15:17:23 -07:00
Alexander Belyaev 9c94908320 BEGIN_PUBLIC
[mlir] Add support for unranked case for `tensor_store` and `tensor_load` ops.
END_PUBLIC

Differential Revision: https://reviews.llvm.org/D85518
2020-08-07 14:32:52 +02:00
Stephan Herhut e12db3ed99 [mlir] Allow index as element type of memref
Differential Revision: https://reviews.llvm.org/D84934
2020-07-30 14:35:22 +02:00
Stephan Herhut 823ffef009 [mlir][Standard] Allow unranked memrefs as operands to dim and rank
`std.dim` currently only accepts ranked memrefs and `std.rank` is limited to
tensors.

Differential Revision: https://reviews.llvm.org/D84790
2020-07-29 14:42:58 +02:00
Alex Zinenko a51829913d [mlir] Support for mutable types
Introduce support for mutable storage in the StorageUniquer infrastructure.
This makes MLIR have key-value storage instead of just uniqued key storage. A
storage instance now contains a unique immutable key and a mutable value, both
stored in the arena allocator that belongs to the context. This is a
preconditio for supporting recursive types that require delayed initialization,
in particular LLVM structure types.  The functionality is exercised in the test
pass with trivial self-recursive type. So far, recursive types can only be
printed in parsed in a closed type system. Removing this restriction is left
for future work.

Differential Revision: https://reviews.llvm.org/D84171
2020-07-27 13:07:44 +02:00
Stephen Neuendorffer 628288658c [MLIR] Add RegionKindInterface
Some dialects have semantics which is not well represented by common
SSA structures with dominance constraints.  This patch allows
operations to declare the 'kind' of their contained regions.
Currently, two kinds are allowed: "SSACFG" and "Graph".  The only
difference between them at the moment is that SSACFG regions are
required to have dominance, while Graph regions are not required to
have dominance.  The intention is that this Interface would be
generated by ODS for existing operations, although this has not yet
been implemented. Presumably, if someone were interested in code
generation, we might also have a "CFG" dialect, which defines control
flow, but does not require SSA.

The new behavior is mostly identical to the previous behavior, since
registered operations without a RegionKindInterface are assumed to
contain SSACFG regions.  However, the behavior has changed for
unregistered operations.  Previously, these were checked for
dominance, however the new behavior allows dominance violations, in
order to allow the processing of unregistered dialects with Graph
regions.  One implication of this is that regions in unregistered
operations with more than one op are no longer CSE'd (since it
requires dominance info).

I've also reorganized the LangRef documentation to remove assertions
about "sequential execution", "SSA Values", and "Dominance".  Instead,
the core IR is simply "ordered" (i.e. totally ordered) and consists of
"Values".  I've also clarified some things about how control flow
passes between blocks in an SSACFG region. Control Flow must enter a
region at the entry block and follow terminator operation successors
or be returned to the containing op.  Graph regions do not define a
notion of control flow.

see discussion here:
https://llvm.discourse.group/t/rfc-allowing-dialects-to-relax-the-ssa-dominance-condition/833/53

Differential Revision: https://reviews.llvm.org/D80358
2020-07-15 14:27:05 -07:00
Jeremy Bruestle 2ede891875 [MLIR] IR changes to add yield semantics for affine.if and affine.parallel
Reviewed By: bondhugula, flaub

Differential Revision: https://reviews.llvm.org/D82600
2020-07-09 12:12:42 -07:00
River Riddle 24aa4efffd [mlir] Print 0 element DenseElementsAttr as dense<> to fix parser bugs with expected shape.
Depending on where the 0 dimension is within the shape, the parser will currently reject .mlir generated by the printer.

Differential Revision: https://reviews.llvm.org/D83445
2020-07-08 18:44:23 -07:00
River Riddle 9db53a1827 [mlir][NFC] Remove usernames and google bug numbers from TODO comments.
These were largely leftover from when MLIR was a google project, and don't really follow LLVM guidelines.
2020-07-07 01:40:52 -07:00
Rahul Joshi 52af9c59e3 [MLIR] Add a NoRegionArguments trait
- This trait will verify that all regions attached to an Op have no arguments
- Fixes https://bugs.llvm.org/show_bug.cgi?id=46521 : Add trait NoRegionArguments

Differential Revision: https://reviews.llvm.org/D83016
2020-07-06 09:05:38 -07:00
Alex Zinenko 42de94f839 [mlir] do not hardcode the name of the undefined function in the error message
The error message in the `std.constant` verifier for function-typed constants
had the name of the undefined function hardcoded to `bar`. Report the actual
name instead.

Differential Revision: https://reviews.llvm.org/D82666
2020-06-29 10:05:06 +02:00
Rahul Joshi e81bf67e8c [MLIR] Modify HasParent trait to allow one of several op's as a parent
- Modify HasParent trait to allow one of several op's as a parent -
- Expose this trait in the ODS framework using the ParentOneOf<> trait.

Differential Revision: https://reviews.llvm.org/D81880
2020-06-16 04:50:56 +00:00
Jacques Pienaar 3dbb6678a5 [mlir] Mark CastOp class's shape constraint
These ops have the same operands and result shapes.

Differential Revision: https://reviews.llvm.org/D81664
2020-06-12 06:50:07 -07:00
Mehdi Amini 95371ce9c2 Enable FileCheck -enable-var-scope by default in MLIR test
This option avoids to accidentally reuse variable across -LABEL match,
it can be explicitly opted-in by prefixing the variable name with $

Differential Revision: https://reviews.llvm.org/D81531
2020-06-12 00:43:09 +00:00
Rahul Joshi a0dd5e876f [MLIR] Print function name when ReturnOp verification fails
Summary:
- Print function name when ReturnOp verification fails
- This helps easily finding the invalid ReturnOp in an IR dump.

Differential Revision: https://reviews.llvm.org/D81513
2020-06-10 17:22:49 -07:00
Frederik Gossen 904f91db5f [MLIR][Standard] Make the `dim` operation index an operand.
Allow for dynamic indices in the `dim` operation.
Rather than an attribute, the index is now an operand of type `index`.
This allows to apply the operation to dynamically ranked tensors.
The correct lowering of dynamic indices remains to be implemented.

Differential Revision: https://reviews.llvm.org/D81551
2020-06-10 13:54:47 +00:00
Mehdi Amini d31c9e5a46 Change filecheck default to dump input on failure
Having the input dumped on failure seems like a better
default: I debugged FileCheck tests for a while without knowing
about this option, which really helps to understand failures.

Remove `-dump-input-on-failure` and the environment variable
FILECHECK_DUMP_INPUT_ON_FAILURE which are now obsolete.

Differential Revision: https://reviews.llvm.org/D81422
2020-06-09 18:57:46 +00:00
Diego Caballero 7d59f49bda [mlir] Fix representation of BF16 constants
This patch is a follow-up on https://reviews.llvm.org/D81127

BF16 constants were represented as 64-bit floating point values due to the lack
of support for BF16 in APFloat. APFloat was recently extended to support
BF16 so this patch is fixing the BF16 constant representation to be 16-bit.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D81218
2020-06-05 17:43:06 -07:00
Jacques Pienaar b0921f68e1 [mlir] Add verify method to adaptor
This allows verifying op-indepent attributes (e.g., attributes that do not require the op to have been created) before constructing an operation. These include checking whether required attributes are defined or constraints on attributes (such as I32 attribute). This is not perfect (e.g., if one had a disjunctive constraint where one part relied on the op and the other doesn't, then this would not try and extract the op independent from the op dependent).

The next step is to move these out to a trait that could be verified earlier than in the generated method. The first use case is for inferring the return type while constructing the op. At that point you don't have an Operation yet and that ends up in one having to duplicate the same checks, e.g., verify that attribute A is defined before querying A in shape function which requires that duplication. Instead this allows one to invoke a method to verify all the traits and, if this is checked first during verification, then all other traits could use attributes knowing they have been verified.

It is a little bit funny to have these on the adaptor, but I see the adaptor as a place to collect information about the op before the op is constructed (e.g., avoiding stringly typed accessors, verifying what is possible to verify before the op is constructed) while being cheap to use even with constructed op (so layer of indirection between the op constructed/being constructed). And from that point of view it made sense to me.

Differential Revision: https://reviews.llvm.org/D80842
2020-06-05 09:47:37 -07:00
River Riddle c0cd1f1c5c [mlir] Refactor BoolAttr to be a special case of IntegerAttr
This simplifies a lot of handling of BoolAttr/IntegerAttr. For example, a lot of places currently have to handle both IntegerAttr and BoolAttr. In other places, a decision is made to pick one which can lead to surprising results for users. For example, DenseElementsAttr currently uses BoolAttr for i1 even if the user initialized it with an Array of i1 IntegerAttrs.

Differential Revision: https://reviews.llvm.org/D81047
2020-06-04 16:41:24 -07:00
Alexander Belyaev c3098e4f40 [MLIR] Add TensorFromElementsOp to Standard ops.
Differential Revision: https://reviews.llvm.org/D80705
2020-05-28 15:48:10 +02:00
Stephen Neuendorffer 9de4ee3815 [MLIR] Allow unreachable blocks to violate dominance property.
It is possible for optimizations to create SSA code which violates
the dominance property in unreachable blocks.  Equivalently, dominance
computed using normal mechanisms is undefined in unreachable blocks.

See discussion here: https://llvm.discourse.group/t/rfc-allowing-dialects-to-relax-the-ssa-dominance-condition/833/51

This patch only checks the dominance condition inside blocks which are
reachable from the the entry block of their region.  Note that the
dominance conditions of regions contained in an unreachable block are
still checked.

Differential Revision: https://reviews.llvm.org/D79922
2020-05-15 10:31:57 -07:00
Nicolas Vasilache 63c0e72b2f [mlir] Revisit std.subview handling of static information.
The main objective of this revision is to change the way static information is represented, propagated and canonicalized in the SubViewOp.

In the current implementation the issue is that canonicalization may strictly lose information because static offsets are combined in irrecoverable ways into the result type, in order to fit the strided memref representation.

The core semantics of the op do not change but the parser and printer do: the op always requires `rank` offsets, sizes and strides. These quantities can now be either SSA values or static integer attributes.

The result type is automatically deduced from the static information and more powerful canonicalizations (as powerful as the representation with sentinel `?` values allows). Previously static information was inferred on a best-effort basis from looking at the source and destination type.

Relevant tests are rewritten to use the idiomatic `offset: x, strides : [...]`-form. Bugs are corrected along the way that were not trivially visible in flattened strided memref form.

Lowering to LLVM is updated, simplified and now supports all cases.
A mixed static-dynamic mode test that wouldn't previously lower is added.

It is an open question, and a longer discussion, whether a better result type representation would be a nicer alternative. For now, the subview op carries the required semantic.

Differential Revision: https://reviews.llvm.org/D79662
2020-05-12 20:04:44 -04:00
Sam McCall 691e826995 Revert "[mlir] Revisit std.subview handling of static information."
This reverts commit 80d133b24f.

Per Stephan Herhut: The canonicalizer pattern that was added creates
forms of the subview op that cannot be lowered.

This is shown by failing Tensorflow XLA tests such as:
  tensorflow/compiler/xla/service/mlir_gpu/tests:abs.hlo.test
Will provide more details offline, they rely on logs from private CI.
2020-05-12 15:18:50 +02:00
Nicolas Vasilache 80d133b24f [mlir] Revisit std.subview handling of static information.
Summary:
The main objective of this revision is to change the way static information is represented, propagated and canonicalized in the SubViewOp.

In the current implementation the issue is that canonicalization may strictly lose information because static offsets are combined in irrecoverable ways into the result type, in order to fit the strided memref representation.

The core semantics of the op do not change but the parser and printer do: the op always requires `rank` offsets, sizes and strides. These quantities can now be either SSA values or static integer attributes.

The result type is automatically deduced from the static information and more powerful canonicalizations (as powerful as the representation with sentinel `?` values allows). Previously static information was inferred on a best-effort basis from looking at the source and destination type.

Relevant tests are rewritten to use the idiomatic `offset: x, strides : [...]`-form. Bugs are corrected along the way that were not trivially visible in flattened strided memref form.

It is an open question, and a longer discussion, whether a better result type representation would be a nicer alternative. For now, the subview op carries the required semantic.

Reviewers: ftynse, mravishankar, antiagainst, rriddle!, andydavis1, timshen, asaadaldien, stellaraccident

Reviewed By: mravishankar

Subscribers: aartbik, bondhugula, mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, arpith-jacob, mgester, lucyrfox, liufengdb, stephenneuendorffer, Joonsoo, bader, grosul1, frgossen, Kayjukh, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D79662
2020-05-11 17:44:24 -04:00
Nicolas Vasilache 6ed61a26c2 [mlir] Simplify and better document std.view semantics
This [discussion](https://llvm.discourse.group/t/viewop-isnt-expressive-enough/991/2) raised some concerns with ViewOp.

In particular, the handling of offsets is incorrect and does not match the op description.
Note that with an elemental type change, offsets cannot be part of the type in general because sizeof(srcType) != sizeof(dstType).

Howerver, offset is a poorly chosen term for this purpose and is renamed to byte_shift.

Additionally, for all intended purposes, trying to support non-identity layouts for this op does not bring expressive power but rather increases code complexity.

This revision simplifies the existing semantics and implementation.
This simplification effort is voluntarily restrictive and acts as a stepping stone towards supporting richer semantics: treat the non-common cases as YAGNI for now and reevaluate based on concrete use cases once a round of simplification occurred.

Differential revision: https://reviews.llvm.org/D79541
2020-05-11 12:29:23 -04:00
Hanhan Wang b80da04b44 [mlir] Add FPToSIOp to Standard dialect.
Summary:
Cast from a value interpreted as floating-point to the corresponding signed
integer value. Similar to an element-wise `static_cast` in C++, performs an
element-wise conversion operation.

Differential Revision: https://reviews.llvm.org/D79373
2020-05-11 01:26:02 -07:00
Renato Golin 5010b5b7e6 Check type for forward reference definition
The types of forward references are checked that they match with other
uses, but they do not check they match with the definition.

    func @forward_reference_type_check() -> (i8) {
      br ^bb2

    ^bb1:
      return %1 : i8

    ^bb2:
      %1 = "bar"() : () -> (f32)
      br ^bb1
    }

Would be parsed and the use site of '%1' would be silently changed to
'f32'.

This commit adds a test for this case, and a check during parsing for
the types to match.

Patch by Matthew Parkinson <mattpark@microsoft.com>

Closes D79317.
2020-05-06 14:34:18 +01:00
River Riddle 24ad385884 [mlir][DenseElementsAttr] Add support for opaque APFloat/APInt complex values.
This revision allows for creating DenseElementsAttrs and accessing elements using std::complex<APInt>/std::complex<APFloat>. This allows for opaquely accessing and transforming complex values. This is used by the printer/parser to provide pretty printing for complex values. The form for complex values matches that of std::complex, i.e.:

```
// `(` element `,` element `)`
dense<(10,10)> : tensor<complex<i64>>
```

Differential Revision: https://reviews.llvm.org/D79296
2020-05-05 12:42:37 -07:00
River Riddle da2a6f4e3b [mlir][DenseElementsAttr] Add support for ComplexType elements
This revision adds support for storing ComplexType elements inside of a DenseElementsAttr. We store complex objects as an array of two elements, matching the  definition of std::complex. There is no current attribute storage for ComplexType, but DenseElementsAttr provides API for access/creation using std::complex<>. Given that the internal implementation of DenseElementsAttr is already fairly opaque, the only real complexity here is in the printing/parsing. This revision keeps it simple for now and always uses hex when printing complex elements. A followup will add prettier syntax for this.

Differential Revision: https://reviews.llvm.org/D79281
2020-05-05 12:42:37 -07:00
Alex Zinenko 9d273c0ef0 [mlir] Harden verifiers for DMA ops
DMA operation classes in the Standard dialect (`DmaStartOp` and `DmaWaitOp`)
provide helper functions that make numerous assumptions about the number and
order of operands, and about their types. However, these assumptions were not
checked in the verifier, leading to assertion failures or crashes when helper
functions were used on ill-formed ops. Some of the assuptions were checked in
the custom parser (and thus could not check assumption violations in ops
constructed programmatically, e.g., during rewrites) and others were not
checked at all. Introduce the verifiers for all these assumptions and drop
unnecessary checks in the parser that are now covered by the verifier.

Addresses PR45560.

Differential Revision: https://reviews.llvm.org/D79408
2020-05-05 20:40:41 +02:00
Frederik Gossen 031265ad8a [MLIR] Add complex numbers to standard dialect
Add `CreateComplexOp`, `ReOp`, and `ImOp` to the standard dialect.
This is the first step to support complex numbers.

Differential Revision: https://reviews.llvm.org/D79159
2020-05-04 14:04:28 +00:00
River Riddle cb9ae0025c [mlir] Add a new context flag for disabling/enabling multi-threading
This is useful for several reasons:
* In some situations the user can guarantee that thread-safety isn't necessary and don't want to pay the cost of synchronization, e.g., when parsing a very large module.

* For things like logging threading is not desirable as the output is not guaranteed to be in stable order.

This flag also subsumes the pass manager flag for multi-threading.

Differential Revision: https://reviews.llvm.org/D79266
2020-05-02 12:32:25 -07:00
MaheshRavishankar 43b89ecdb9 [mlir] Add sine operation to Standard dialect.
Also add lowering of sine operation to SPIR-V dialect.

Differential Revision: https://reviews.llvm.org/D79102
2020-04-30 22:15:42 -07:00
Sean Silva 9c9f479a7d Make ops with StructAttr's actually verify `isa<TheStruct>`.
Previously, they would only only verify `isa<DictionaryAttr>` on such attrs
which resulted in crashes down the line from code assuming that the
verifier was doing the more thorough check introduced in this patch.
The key change here is for StructAttr to use
`CPred<"$_self.isa<" # name # ">()">` instead of `isa<DictionaryAttr>`.

To test this, introduce struct attrs to the test dialect. Previously,
StructAttr was only being tested by unittests/, which didn't verify how
StructAttr interacted with ODS.

Differential Revision: https://reviews.llvm.org/D78975
2020-04-28 14:00:18 -07:00
Sean Silva 15fcdac498 Don't crash on duplicate keys in dictionary attrs.
Differential Revision: https://reviews.llvm.org/D78966
2020-04-27 15:23:49 -07:00
Rob Suderman fb674e3329 [mlir] Add support for sparse DenseStringElements.
Summary: Added support for sparse strings elements. This is a follow up from the original DenseStringElements.

Differential Revision: https://reviews.llvm.org/D78844
2020-04-25 01:21:40 -07:00
Rob Suderman 5b89c1dd68 [mlir] DenseStringElementsAttr added to default attribute types
Summary:
Implemented a DenseStringsElements attr for handling arrays / tensors of strings. This includes the
necessary logic for parsing and printing the attribute from MLIR's text format.

To store the attribute we perform a single allocation that includes all wrapped string data tightly packed.
This means no padding characters and no null terminators (as they could be present in the string). This
buffer includes a first chunk of data that represents an array of StringRefs, that contain address pointers
into the string data, with the length of each string wrapped. At this point there is no Sparse representation
however strings are not typically represented sparsely.

Differential Revision: https://reviews.llvm.org/D78600
2020-04-23 19:02:15 -07:00
Sean Silva 1b2c7877a4 Add support for IndexType inside DenseIntElementsAttr.
This also fixes issues discovered in the parsing/printing path.
2020-04-23 17:42:33 -07:00
River Riddle 7f85adb54d [mlir][Standard] Allow select to use an i1 for vector and tensor values
It currently requires that the condition match the shape of the selected value, but this is only really useful for things like masks. This revision allows for the use of i1 to mean that all of the vector/tensor is selected. This also matches the behavior of LLVM select. A benefit of this change is that transformations that want to generate selects, like those on the CFG, don't have to special case vector/tensor. Previously the only way to generate  a select from an i1 was to use a splat, but that doesn't support dynamically shaped/unranked tensors.

Differential Revision: https://reviews.llvm.org/D78690
2020-04-23 04:50:09 -07:00
River Riddle af331bc52d [mlir][Standard] Add a canonicalization to simplify cond_br when the successors are identical
This revision adds support for canonicalizing the following:

```
cond_br %cond, ^bb1(A, ..., N), ^bb1(A, ..., N)

br ^bb1(A, ..., N)
```

 If the operands to the successor are different and the cond_br is the only predecessor, we emit selects for the branch operands.

```
cond_br %cond, ^bb1(A), ^bb1(B)

%select = select %cond, A, B
br ^bb1(%select)
```

Differential Revision: https://reviews.llvm.org/D78682
2020-04-23 04:42:02 -07:00