120 Commits

Author SHA1 Message Date
Eugene Zhulenev
519f5917b4 [mlir] Add fma operation to std dialect
Will remove `vector.fma` operation in the followup CLs.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D96801
2021-02-17 10:06:01 -08:00
Stephan Herhut
4348d8ab7f [mlir][math] Split off the math dialect.
This does not split transformations, yet. Those will be done as future clean ups.

Differential Revision: https://reviews.llvm.org/D96272
2021-02-12 10:55:12 +01:00
Nicolas Vasilache
49c9c3a59e [mlir][Standard] Extend n-D vector lowering to LLVM to [s|z]exti ops.
[s|z]exti ops do not have the same operand and result type.
As a consequence, the lowering of the n-D vector form needs to be relaxed a bit.
This revision additionally performs a few NFC renamings of variables to make them more intuitive.

Differential Revision: https://reviews.llvm.org/D95760
2021-02-02 07:45:50 +00:00
Nicolas Vasilache
5133673df4 [mlir] Extend semantic of OffsetSizeAndStrideOpInterface.
OffsetSizeAndStrideOpInterface now have the ability to specify only a leading subset of
offset, sizes, strides operands/attributes.
The size of that leading subset must be limited by the corresponding entry in `getArrayAttrMaxRanks` to avoid overflows.
Missing trailing dimensions are assumed to span the whole range (i.e. [0 .. dim)).
This brings more natural semantics to slice-like op on top of subview and is a simplifies to removing all uses of SliceOp in dependent projects.

Differential revision: https://reviews.llvm.org/D95441
2021-01-27 09:02:35 +00:00
Alexander Belyaev
fc58bfd02f [mlir] Remove complex ops from Standard dialect.
`complex` dialect should be used instead.
https://llvm.discourse.group/t/rfc-split-the-complex-dialect-from-std/2496/2

Differential Revision: https://reviews.llvm.org/D95077
2021-01-21 10:34:26 +01:00
River Riddle
93592b726c [mlir][OpFormatGen] Format enum attribute cases as keywords when possible
In the overwhelmingly common case, enum attribute case strings represent valid identifiers in MLIR syntax. This revision updates the format generator to format as a keyword in these cases, removing the need to wrap values in a string. The parser still retains the ability to parse the string form, but the printer will use the keyword form when applicable.

Differential Revision: https://reviews.llvm.org/D94575
2021-01-14 11:35:49 -08:00
Alex Zinenko
bd30a796fc [mlir] use built-in vector types instead of LLVM dialect types when possible
Continue the convergence between LLVM dialect and built-in types by using the
built-in vector type whenever possible, that is for fixed vectors of built-in
integers and built-in floats. LLVM dialect vector type is still in use for
pointers, less frequent floating point types that do not have a built-in
equivalent, and scalable vectors. However, the top-level `LLVMVectorType` class
has been removed in favor of free functions capable of inspecting both built-in
and LLVM dialect vector types: `LLVM::getVectorElementType`,
`LLVM::getNumVectorElements` and `LLVM::getFixedVectorType`. Additional work is
necessary to design an implemented the extensions to built-in types so as to
remove the `LLVMFixedVectorType` entirely.

Note that the default output format for the built-in vectors does not have
whitespace around the `x` separator, e.g., `vector<4xf32>` as opposed to the
LLVM dialect vector type format that does, e.g., `!llvm.vec<4 x fp128>`. This
required changing the FileCheck patterns in several tests.

Reviewed By: mehdi_amini, silvas

Differential Revision: https://reviews.llvm.org/D94405
2021-01-12 10:04:28 +01:00
Alex Zinenko
dd5165a920 [mlir] replace LLVM dialect float types with built-ins
Continue the convergence between LLVM dialect and built-in types by replacing
the bfloat, half, float and double LLVM dialect types with their built-in
counterparts. At the API level, this is a direct replacement. At the syntax
level, we change the keywords to `bf16`, `f16`, `f32` and `f64`, respectively,
to be compatible with the built-in type syntax. The old keywords can still be
parsed but produce a deprecation warning and will be eventually removed.

Depends On D94178

Reviewed By: mehdi_amini, silvas, antiagainst

Differential Revision: https://reviews.llvm.org/D94179
2021-01-08 17:38:12 +01:00
Alex Zinenko
2230bf99c7 [mlir] replace LLVMIntegerType with built-in integer type
The LLVM dialect type system has been closed until now, i.e. did not support
types from other dialects inside containers. While this has had obvious
benefits of deriving from a common base class, it has led to some simple types
being almost identical with the built-in types, namely integer and floating
point types. This in turn has led to a lot of larger-scale complexity: simple
types must still be converted, numerous operations that correspond to LLVM IR
intrinsics are replicated to produce versions operating on either LLVM dialect
or built-in types leading to quasi-duplicate dialects, lowering to the LLVM
dialect is essentially required to be one-shot because of type conversion, etc.
In this light, it is reasonable to trade off some local complexity in the
internal implementation of LLVM dialect types for removing larger-scale system
complexity. Previous commits to the LLVM dialect type system have adapted the
API to support types from other dialects.

Replace LLVMIntegerType with the built-in IntegerType plus additional checks
that such types are signless (these are isolated in a utility function that
replaced `isa<LLVMType>` and in the parser). Temporarily keep the possibility
to parse `!llvm.i32` as a synonym for `i32`, but add a deprecation notice.

Reviewed By: mehdi_amini, silvas, antiagainst

Differential Revision: https://reviews.llvm.org/D94178
2021-01-07 19:48:31 +01:00
Alex Zinenko
96076a2edb [mlir] Support index and memref types in llvm.mlir.cast
This operation is designed to support partial conversion, more specifically the
IR state in which some operations expect or produce built-in types and some
operations produce and expect LLVM dialect types. It is reasonable for it to
support cast between built-in types and any equivalent that could be produced
by the type conversion. (At the same time, we don't want the dialect to depend
on the type conversion as it could lead to a dependency cycle). Introduce
support for casting from index to any integer type and back, and from memref to
bare pointer or memref descriptor type and back.

Contrary to what the TODO in the code stated, there are no particular
precautions necessary to handle the bare pointer conversion for memerfs. This
conversion applies exclusively to statically-shaped memrefs, so we can always
recover the full descriptor contents from the type.

This patch simultaneously tightens the verification for other types to only
accept matching pairs of types, e.g., i64 and !llvm.i64, as opposed to the
previous implementation that only checked if the types were generally allowed
byt not for matching, e.g. i64 could be "casted" to !llvm.bfloat, which is not
the intended semantics.

Move the relevant test under test/Dialect/LLVMIR because it is not specific to
the conversion pass, but rather exercises an op in the dialect. If we decide
this op does not belong to the LLVM dialect, both the dialect and the op should
move together.

Reviewed By: silvas, ezhulenev

Differential Revision: https://reviews.llvm.org/D93405
2020-12-17 09:21:42 +01:00
Tres Popp
c77ea40528 [mlir] Add std.pow lowering to LLVMIR
Differential Revision: https://reviews.llvm.org/D93311
2020-12-15 18:54:29 +01:00
Alex Zinenko
9bb5bff570 [mlir] Add an assertion on creating an Operation with null result types
Null types are commonly used as an error marker. Catch them in the constructor
of Operation if they are present in the result type list, as otherwise this
could lead to further surprising behavior when querying op result types.

Fix AsyncToLLVM and StandardToLLVM that were using null types when constructing
operations.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D91770
2020-11-19 22:28:38 +01:00
Christian Sigg
8b97e17d16 [mlir] Simplify code generated by ConvertToLLVMPattern::getStridedElementPtr().
Make the interface match the one of ConvertToLLVMPattern::getDataPtr() (to be removed in a separate change).

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D91599
2020-11-18 11:52:09 +01:00
Christian Sigg
bedaad4495 [mlir] Simplify std.alloc lowering to LLVM.
std.alloc only supports memrefs with identity layout, which means we can simplify the lowering to LLVM and compute strides only from (static and dynamic) sizes.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D91549
2020-11-17 18:55:34 +01:00
Rahul Joshi
b7382ed3fe [MLIR] Extend Symbol verification to reject public symbol declarations.
- Extend the Symbol interface with `isDeclaration` to identify operations that declare
  a symbol as opposed to define it.
- Extend verification to disallow public declarations as per the discussion in
   https://llvm.discourse.group/t/rfc-symbol-definition-declaration-x-visibility-checks/2140
- Adopt the new interface for `FuncOp` and fix test and code to not have/create public
  function declarations.

Differential Revision: https://reviews.llvm.org/D91456
2020-11-16 16:05:32 -08:00
Christian Sigg
04481f26fa [mlir] Require std.alloc() ops to have canonical layout during LLVM lowering.
The current code allows strided layouts, but the number of elements allocated is ambiguous. It could be either the number of elements in the shape (the current implementation), or the amount of elements required to not index out-of-bounds with the given maps (which would require evaluating the layout map).

If we require the canonical layouts, the two will be the same.

Reviewed By: nicolasvasilache, ftynse

Differential Revision: https://reviews.llvm.org/D91523
2020-11-16 17:29:36 +01:00
Rahul Joshi
a97e357e8e [MLIR] Support global_memref and get_global_memref in standard -> LLVM conversion.
- Convert `global_memref` to LLVM::GlobalOp.
- Convert `get_global_memref` to a memref descriptor with a pointer to the first element
  of the global stashed in it.
- Extend unit test and a mlir-cpu-runner test to validate the generated LLVM IR.

Differential Revision: https://reviews.llvm.org/D90803
2020-11-09 10:54:21 -08:00
Alexander Belyaev
9925168576 [mlir] Convert memref_reshape to LLVM.
https://llvm.discourse.group/t/rfc-standard-memref-cast-ops/1454/15

Differential Revision: https://reviews.llvm.org/D90377
2020-11-03 11:39:08 +01:00
Alexander Belyaev
d6ab0474c6 [mlir] Convert MemRefReinterpretCastOp to LLVM.
https://llvm.discourse.group/t/rfc-standard-memref-cast-ops/1454/15

Differential Revision: https://reviews.llvm.org/D90033
2020-10-26 20:13:17 +01:00
Christian Sigg
665371d0b2 [mlir] Split alloc-like op LLVM lowerings into base and separate derived classes.
The previous code did the lowering to alloca, malloc, and aligned_malloc
in a single class with different code paths that are somewhat difficult to
follow.

This change moves the common code to a base class and has a separte
derived class per lowering target that contains the specifics.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D88696
2020-10-05 17:36:01 +02:00
Benjamin Kramer
6e2b267d1c Promote transpose from linalg to standard dialect
While affine maps are part of the builtin memref type, there is very
limited support for manipulating them in the standard dialect. Add
transpose to the set of ops to complement the existing view/subview ops.
This is a metadata transformation that encodes the transpose into the
strides of a memref.

I'm planning to use this when lowering operations on strided memrefs,
using the transpose to remove the stride without adding a dependency on
linalg dialect.

Differential Revision: https://reviews.llvm.org/D88651
2020-10-05 10:58:20 +02:00
Diego Caballero
a611f9a5c6 [mlir] Fix call op conversion in bare-ptr calling convention
We hit an llvm_unreachable related to unranked memrefs for call ops
with scalar types. Removing the llvm_unreachable since the conversion
should gracefully bail out in the presence of unranked memrefs. Adding
tests to verify that.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D88709
2020-10-02 08:48:21 -07:00
Diego Caballero
a89fc12653 [mlir] Support return and call ops in bare-ptr calling convention
This patch adds support for the 'return' and 'call' ops to the bare-ptr
calling convention. These changes also align the bare-ptr calling
convention code with the latest changes in the default calling convention
and reduce the amount of customization code needed.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D87724
2020-09-29 12:00:47 -07:00
Alex Zinenko
967c7b6936 [mlir] check for failures when packing function sigunatures in std->llvm conversion
When packing function results into a structure during the standard-to-llvm
dialect conversion, do not assume the conversion was successful and propagate
nullptr as error state.

Fixes PR45184.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D87605
2020-09-15 12:30:44 +02:00
Lubomir Litchev
ef7a255c03 Add support for casting elements in vectors for certain Std dialect type conversion operations.
Added support to the Std dialect cast operations to do casts in vector types when feasible.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D87410
2020-09-14 07:45:46 -07:00
Alex Zinenko
5cac85c931 [mlir] Check for type conversion success in std->llvm function conversion
Type converter may fail and return nullptr on unconvertible types. The function
conversion did not include a check and was attempting to use a nullptr type to
construct an LLVM function, leading to a crash. Add a check and return early.
The rest of the call stack propagates errors properly.

Fixes PR47403.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D87075
2020-09-14 13:16:42 +02:00
Nicolas Vasilache
8d64df9f13 [mlir][Vector] Revisit VectorToSCF.
Vector to SCF conversion still had issues due to the interaction with the natural alignment derived by the LLVM data layout. One traditional workaround is to allocate aligned. However, this does not always work for vector sizes that are non-powers of 2.

This revision implements a more portable mechanism where the intermediate allocation is always a memref of elemental vector type. AllocOp is extended to use the natural LLVM DataLayout alignment for non-scalar types, when the alignment is not specified in the first place.

An integration test is added that exercises the transfer to scf.for + scalar lowering with a 5x5 transposition.

Differential Revision: https://reviews.llvm.org/D87150
2020-09-07 05:19:43 -04:00
Kazuaki Ishizaki
40cbb2484d [mlir] NFC: fix typo in FileCheck prefix
CHECL -> CHECK

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D86550
2020-08-26 03:12:14 +09:00
Mars Saxman
d34df52377 Implement FPToUI and UIToFP ops in standard dialect
Add the unsigned complements to the existing FPToSI and SIToFP operations in the
standard dialect, with one-to-one lowerings to the corresponding LLVM operations.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D85557
2020-08-19 22:49:09 +02: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
9c4825ce28 [mlir] do not use llvm.cmpxchg with floats
According to the LLVM Language Reference, 'cmpxchg' accepts integer or pointer
types. Several MLIR tests were using it with floats as it appears possible to
programmatically construct and print such an instruction, but it cannot be
parsed back. Use integers instead.

Depends On D85899

Reviewed By: flaub, rriddle

Differential Revision: https://reviews.llvm.org/D85900
2020-08-17 15:44:23 +02:00
Alex Zinenko
168213f91c [mlir] Move data layout from LLVMDialect to module Op attributes
Legacy implementation of the LLVM dialect in MLIR contained an instance of
llvm::Module as it was required to parse LLVM IR types. The access to the data
layout of this module was exposed to the users for convenience, but in practice
this layout has always been the default one obtained by parsing an empty layout
description string. Current implementation of the dialect no longer relies on
wrapping LLVM IR types, but it kept an instance of DataLayout for
compatibility. This effectively forces a single data layout to be used across
all modules in a given MLIR context, which is not desirable. Remove DataLayout
from the LLVM dialect and attach it as a module attribute instead. Since MLIR
does not yet have support for data layouts, use the LLVM DataLayout in string
form with verification inside MLIR. Introduce the layout when converting a
module to the LLVM dialect and keep the default "" description for
compatibility.

This approach should be replaced with a proper MLIR-based data layout when it
becomes available, but provides an immediate solution to compiling modules with
different layouts, e.g. for GPUs.

This removes the need for LLVMDialectImpl, which is also removed.

Depends On D85650

Reviewed By: aartbik

Differential Revision: https://reviews.llvm.org/D85652
2020-08-17 15:12:36 +02:00
Alex Zinenko
339eba0805 [mlir] do not emit bitcasts between structs in StandardToLLVM
The convresion of memref cast operaitons from the Standard dialect to the LLVM
dialect has been emitting bitcasts from a struct type to itself. Beyond being
useless, such casts are invalid as bitcast does not operate on aggregate types.
This kept working by accident because LLVM IR bitcast construction API skips
the construction if types are equal before it verifies that the types are
acceptable in a bitcast. Do not emit such bitcasts, the memref cast that only
adds/erases size information is in fact a noop on the current descriptor as it
always contains dynamic values for all sizes.

Reviewed By: pifon2a

Differential Revision: https://reviews.llvm.org/D85899
2020-08-14 11:33:10 +02:00
Alexander Belyaev
3effc35015 [mlir] Lower DimOp to LLVM for unranked memrefs.
Differential Revision: https://reviews.llvm.org/D85361
2020-08-06 11:46:11 +02:00
Alexander Belyaev
bc7456fd8a [mlir] Fix rank bitwidth in UnrankedMemRefType conversion.
Differential Revision: https://reviews.llvm.org/D85300
2020-08-05 18:35:23 +02:00
Alex Zinenko
bdb9295664 [mlir] Fix convert-to-llvmir.mlir test broken due to syntax change
The syntax of the LLVM dialect types changed between the time the code
was written and it was submitted, leading to a test failure. Update the
syntax.
2020-08-05 13:29:35 +02:00
Arpith C. Jacob
fab4b59961 [mlir] Conversion of ViewOp with memory space to LLVM.
Handle the case where the ViewOp takes in a memref that has
an memory space.

Reviewed By: ftynse, bondhugula, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D85048
2020-08-05 12:19:52 +02:00
Alexander Belyaev
a3d427d30c [mlir] Lower RankOp to LLVM for unranked memrefs.
Differential Revision: https://reviews.llvm.org/D85273
2020-08-05 12:13:43 +02:00
Alex Zinenko
ec1f4e7c3b [mlir] switch the modeling of LLVM types to use the new mechanism
A new first-party modeling for LLVM IR types in the LLVM dialect has been
developed in parallel to the existing modeling based on wrapping LLVM `Type *`
instances. It resolves the long-standing problem of modeling identified
structure types, including recursive structures, and enables future removal of
LLVMContext and related locking mechanisms from LLVMDialect.

This commit only switches the modeling by (a) renaming LLVMTypeNew to LLVMType,
(b) removing the old implementaiton of LLVMType, and (c) updating the tests. It
is intentionally minimal. Separate commits will remove the infrastructure built
for the transition and update API uses where appropriate.

Depends On D85020

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D85021
2020-08-04 14:29:25 +02:00
Alexander Belyaev
6b8c641d8e [mlir] NFC: Expose getElementPtrType and getSizes methods of AllocOpLowering.
Differential Revision: https://reviews.llvm.org/D84917
2020-07-30 20:18:29 +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
Frederik Gossen
fb1e571687 [MLIR][Standard] Add default lowering for assert
The default lowering of `assert` calls `abort` in case the assertion is
violated. The failure message is ignored but should be used by custom lowerings
that can assume more about their environment.

Differential Revision: https://reviews.llvm.org/D83886
2020-07-24 08:31:12 +00:00
River Riddle
4589dd924d [mlir][DialectConversion] Enable deeper integration of type conversions
This revision adds support for much deeper type conversion integration into the conversion process, and enables auto-generating cast operations when necessary. Type conversions are now largely automatically managed by the conversion infra when using a ConversionPattern with a provided TypeConverter. This removes the need for patterns to do type cast wrapping themselves and moves the burden to the infra. This makes it much easier to perform partial lowerings when type conversions are involved, as any lingering type conversions will be automatically resolved/legalized by the conversion infra.

To support this new integration, a few changes have been made to the type materialization API on TypeConverter. Materialization has been split into three separate categories:
* Argument Materialization: This type of materialization is used when converting the type of block arguments when calling `convertRegionTypes`. This is useful for contextually inserting additional conversion operations when converting a block argument type, such as when converting the types of a function signature.
* Source Materialization: This type of materialization is used to convert a legal type of the converter into a non-legal type, generally a source type. This may be called when uses of a non-legal type persist after the conversion process has finished.
* Target Materialization: This type of materialization is used to convert a non-legal, or source, type into a legal, or target, type. This type of materialization is used when applying a pattern on an operation, but the types of the operands have not yet been converted.

Differential Revision: https://reviews.llvm.org/D82831
2020-07-23 19:40:31 -07:00
Alex Zinenko
cba733edf5 [mlir] LLVM dialect: use addressof instead of constant to create function pointers
`llvm.mlir.constant` was originally introduced as an LLVM dialect counterpart
to `std.constant`. As such, it was supporting "function pointer" constants
derived from the symbol name. This is different from `std.constant` that allows
for creation of a "function" constant since MLIR, unlike LLVM IR, supports
this. Later, `llvm.mlir.addressof` was introduced as an Op that obtains a
constant pointer to a global in the LLVM dialect. It naturally extends to
functions (in LLVM IR, functions are globals) and should be used for defining
"function pointer" values instead.

Fixes PR46344.

Differential Revision: https://reviews.llvm.org/D82667
2020-06-29 12:21:33 +02:00
Alex Zinenko
6323065fd6 [mlir] support returning unranked memrefs
Initially, unranked memref descriptors in the LLVM dialect were designed only
to be passed into functions. An assertion was guarding against returning
unranked memrefs from functions in the standard-to-LLVM conversion. This is
insufficient for functions that wish to return an unranked memref such that the
caller does not know the rank in advance, and hence cannot allocate the
descriptor and pass it in as an argument.

Introduce a calling convention for returning unranked memref descriptors as
follows. An unranked memref descriptor always points to a ranked memref
descriptor stored on stack of the current function. When an unranked memref
descriptor is returned from a function, the ranked memref descriptor it points
to is copied to dynamically allocated memory, the ownership of which is
transferred to the caller. The caller is responsible for deallocating the
dynamically allocated memory and for copying the pointed-to ranked memref
descriptor onto its stack.

Provide default lowerings for std.return, std.call and std.indirect_call that
maintain the conversion defined above.

This convention is additionally exercised by a runtime test to guard against
memory errors.

Differential Revision: https://reviews.llvm.org/D82647
2020-06-26 15:37:37 +02:00
Frederik Gossen
0990f1a3ad [MLIR][Standard] Lower std.dim with dynamic dimension operand to LLVM
Implement the missing lowering from `std.dim` to the LLVM dialect in case of a
dynamic dimension.

Differential Revision: https://reviews.llvm.org/D81834
2020-06-16 20:57:42 +00: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
Mehdi Amini
83d920c72a Fix MLIR test: -dump-input-on-failure is no longer a valid option 2020-06-10 15:58:58 +00: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
Diego Caballero
5c990d6994 [mlir] Add support for bf16 to StandardToLLVM conversion
Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D81127
2020-06-04 14:36:36 -07:00