67 Commits

Author SHA1 Message Date
Hanhan Wang
c80484e16e [mlir][StandardToSPIRV] Add support for lowering trunci to SPIR-V to i1 types.
Add a pattern to converting some value to a boolean. spirv.S/UConvert does not
work on i1 types. Thus, the pattern is lowered to cmpi + select.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D96851
2021-02-17 07:23:41 -08:00
Benjamin Kramer
530d6ea97b [mlir][spirv] Lower sexti -> SConvert 2021-02-12 15:04:12 +01: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
Lei Zhang
9f622b3d5d [mlir][spirv] Add more vector conversion patterns
This patch introduces a few more straightforward patterns
to convert vector ops operating on 1-4 element vectors
to their corresponding SPIR-V counterparts.

This patch also enables converting vector<1xT> to T.

Reviewed By: ThomasRaoux

Differential Revision: https://reviews.llvm.org/D96042
2021-02-05 09:11:16 -05:00
Lei Zhang
e27197f360 [mlir][spirv] Define spv.IsNan/spv.IsInf and add lowerings
spv.Ordered/spv.Unordered are meant for OpenCL Kernel capability.
For Vulkan Shader capability, we should use spv.IsNan to check
whether a number is NaN.

Add a new pattern for converting `std.cmpf ord|uno` to spv.IsNan
and bumped the pattern converting to spv.Ordered/spv.Unordered
to a higher benefit. The SPIR-V target environment will properly
select between these two patterns.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D95237
2021-01-22 13:09:33 -05:00
Lei Zhang
167fb9b4b4 [mlir][spirv] Fix script for availability autogen and refresh ops
Previously we only autogen the availability for ops that are
direct instantiating `SPV_Op` and expected other subclasses of
`SPV_Op` to define aggregated availability for all ops. This is
quite error prone and we can miss capabilities for certain ops.
Also it's arguable to have multiple levels of subclasses and try
to deduplicate too much: having the availability directly in the
op can be quite explicit and clear. A few extra lines of
declarative code is fine.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D95236
2021-01-22 13:07:36 -05:00
Hanhan Wang
2cb130f766 [mlir][StandardToSPIRV] Add support for lowering uitofp to SPIR-V
- Extend spirv::ConstantOp::getZero/One to handle float, vector of int, and vector of float.
- Refactor ZeroExtendI1Pattern to use getZero/One methods.
- Add one more test for lowering std.zexti which extends vector<4xi1> to vector<4xi64>.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D95120
2021-01-21 22:20:32 -08:00
MaheshRavishankar
615167c9f7 [mlir]][SPIRV] Define OrderedOp and UnorderedOp and add lowerings from Standard.
Define OrderedOp and UnorderedOp instructions in SPIR-V and convert
cmpf operations with `ord` and `uno` tag to these instructions
respectively.

Differential Revision: https://reviews.llvm.org/D95098
2021-01-21 07:56:44 -08: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
Lei Zhang
7c3ae48fe8 [mlir][spirv] Replace SPIRVOpLowering with OpConversionPattern
The dialect conversion framework was enhanced to handle type
conversion automatically. OpConversionPattern already contains
a pointer to the TypeConverter. There is no need to duplicate it
in a separate subclass. This removes the only reason for a
SPIRVOpLowering subclass. It adapts to use core infrastructure
and simplifies the code.

Also added a utility function to OpConversionPattern for getting
TypeConverter as a certain subclass.

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D94080
2021-01-09 08:04:53 -05:00
Lei Zhang
42980a789d [mlir][spirv] Convert functions returning one value
Reviewed By: hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D93468
2020-12-23 13:27:31 -05:00
ergawy
9793edd5bf [MLIR][SPIRV] Rename spv._address_of to spv.mlir.addressof
This commit does the renaming mentioned in the title in order to bring
`spv` dialect closer to the MLIR naming conventions.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D91609
2020-11-17 12:12:27 -05:00
Hanhan Wang
47fd19f22e [mlir][StandardToSPIRV] Extend support for lowering cmpi to SPIRV.
The logic of vector on boolean was missed. This patch adds the logic and test on
it.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D91403
2020-11-16 06:51:05 -08:00
Thomas Raoux
ac2cf07195 [spirv] Fix legalize standard to spir-v for transfer ops
Forward missing attributes when creating the new transfer op otherwise the
builder would use default values.

Differential Revision: https://reviews.llvm.org/D89907
2020-10-21 13:56:01 -07:00
ergawy
bddaa7a848 [MLIR][SPIRV] Support identified and recursive structs.
This PR adds support for identified and recursive structs.
This includes: parsing, printing, serializing, and
deserializing such structs.

The following C struct:

```C
struct A {
  A* next;
};
```

which is translated to the following MLIR code as:

```mlir
!spv.struct<A, (!spv.ptr<!spv.struct<A>, Generic>)>
```

would be represented in the SPIR-V module as:

```spirv
OpName %A "A"
OpTypeForwardPointer %APtr Generic
%A = OpTypeStruct %APtr
%APtr = OpTypePointer Generic %A
```

In particular the following changes are included:
- SPIR-V structs can now be either identified or literal
  (i.e. non-identified).
- All structs now have their members surrounded by a ()-pair.
- For recursive references,
  (1) an OpTypeForwardPointer instruction is emitted before
  the OpTypeStruct instruction defining the recursive struct
  (2) an OpTypePointer instruction is emitted after the
  OpTypeStruct instruction which actually defines the recursive
  pointer to struct type.

Reviewed By: antiagainst, rriddle, ftynse

Differential Revision: https://reviews.llvm.org/D87206
2020-10-13 10:18:21 -04:00
Hanhan Wang
1909b6ac0d [mlir][StandardToSPIRV] Handle vector of i1 case for lowering zexti to SPIR-V.
Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D87887
2020-09-18 07:07:22 -07:00
Lei Zhang
8d420fb3a0 [spirv][nfc] Simplify resource limit with default values
These deafult values are gotten from Vulkan required limits.

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D87090
2020-09-03 13:29:26 -04: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
Lei Zhang
0d03b3901d [mlir][StandardToSPIRV] Use spv.UMod for index re-calculation
Per Vulkan's SPIR-V environment spec: "While the OpSRem and OpSMod
instructions are supported by the Vulkan environment, they require
non-negative values and thus do not enable additional functionality
beyond what OpUMod provides."

The `getOffsetForBitwidth` function is used for lowering std.load
and std.store, whose indices are of `index` type and cannot be
negative. So we should be okay to use spv.UMod directly here to
be exact. Also made the comment explicit about the assumption.

Differential Revision: https://reviews.llvm.org/D83714
2020-08-05 14:52:04 -04:00
Lei Zhang
48378a32af [spirv] Fix bitwidth emulation for Workgroup storage class
If Int16 is not available, 16-bit integers inside Workgroup storage
class should be emulated via 32-bit integers. This was previously
broken because the capability querying logic was incorrectly
intercepting all storage classes where it meant to only handle
interface storage classes. Adjusted where we return to fix this.

Differential Revision: https://reviews.llvm.org/D85308
2020-08-05 14:44:03 -04:00
Thomas Raoux
59156bad03 [mlir][spirv] Add support for converting memref of vector to SPIR-V
This allow declaring buffers and alloc of vectors so that we can support vector
load/store.

Differential Revision: https://reviews.llvm.org/D84982
2020-07-30 15:05:40 -07:00
George Mitenkov
be15284ef6 [MLIR][StdToSPIRV] Fixed a typo in ops conversion tests
Fixed a typo in `std-ops-to-spitv.mlir` test.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D83791
2020-07-14 21:46:07 +03:00
Lei Zhang
4ba45a778a [mlir][StandardToSPIRV] Fix conversion for signed remainder
Per the Vulkan's SPIR-V environment spec, "for the OpSRem and OpSMod
instructions, if either operand is negative the result is undefined."
So we cannot directly use spv.SRem/spv.SMod if either operand can be
negative. Emulate it via spv.UMod.

Because the emulation uses spv.SNegate, this commit also defines
spv.SNegate.

Differential Revision: https://reviews.llvm.org/D83679
2020-07-13 16:15:31 -04:00
Thomas Raoux
670455c77d [mlir][spirv] Legalize subviewop when used with vector transfer
Subview operations are not natively supported downstream in the spirv path.
This change allows removing subview when used by vector transfer the same way
we already do it when they are used by LoadOp/StoreOp

Differential Revision: https://reviews.llvm.org/D82106
2020-06-19 17:33:15 -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
Hanhan Wang
0b025d2733 [mlir][StandardToSPIRV] Handle i1 case for lowering std.zexti to SPIR-V.
Differential Revision: https://reviews.llvm.org/D80965
2020-06-03 15:01:18 -07:00
MaheshRavishankar
4d6f44f5f0 [mlir][spirv] Lower allocation/deallocations of workgroup memory.
This allocation of a workgroup memory is lowered to a
spv.globalVariable. Only static size allocation with element type
being int or float is handled. The lowering does account for the
element type that are not supported in the lowered spv.module based on
the extensions/capabilities and adjusts the number of elements to get
the same byte length.

Differential Revision: https://reviews.llvm.org/D80411
2020-05-27 09:53:16 -07:00
MaheshRavishankar
0e88eb5c51 [mlir][spirv] Adapt subview legalization to the updated op semantics.
The subview semantics changes recently to allow for more natural
representation of constant offsets and strides. The legalization of
subview op for lowering to SPIR-V needs to account for this.
Also change the linearization to use the strides from the affine map
of a memref.

Differential Revision: https://reviews.llvm.org/D80270
2020-05-20 12:00:21 -07:00
Hanhan Wang
520a570268 [mlir][StandardToSPIRV] Fix signedness issue in bitwidth emulation.
Summary:
Previously, after applying the mask, a negative number would convert to a
positive number because the sign flag was forgotten. This patch adds two more
shift operations to do the sign extension. This assumes that we're using two's
complement.

This patch applies sign extension unconditionally when loading a unspported integer width, and it relies the pattern to do the casting because the signedness semantic is carried by operator itself.

Differential Revision: https://reviews.llvm.org/D79753
2020-05-19 11:00:01 -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 80d133b24f77d1b9d351251315606441c971ef9b.

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
Hanhan Wang
756d6959d7 [mlir][StandardToSPIRV] Add support for lowering index_cast to SPIR-V.
Differential Revision: https://reviews.llvm.org/D79644
2020-05-11 15:41:25 -07: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
Hanhan Wang
ac691c4fe7 [mlir][StandardToSPIRV] Add support for lowering FPToSIOp to SPIR-V.
Summary: Depends On D79373

Differential Revision: https://reviews.llvm.org/D79374
2020-05-11 01:27:54 -07:00
Hanhan Wang
5d10613b6e [mlir][StandardToSPIRV] Emulate bitwidths not supported for store op.
Summary:
As D78974, this patch implements the emulation for store op. The emulation is
done with atomic operations. E.g., if the storing value is i8, rewrite the
StoreOp to:

 1) load a 32-bit integer
 2) clear 8 bits in the loading value
 3) store 32-bit value back
 4) load a 32-bit integer
 5) modify 8 bits in the loading value
 6) store 32-bit value back

The step 1 to step 3 are done by AtomicAnd as one atomic step, and the step 4
to step 6 are done by AtomicOr as another atomic step.

Differential Revision: https://reviews.llvm.org/D79272
2020-05-04 15:18:44 -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
Hanhan Wang
be0ad5b034 [mlir][StandardToSPIRV] Add support for lowering integer casting.
Summary:
Maps ZeroExtendIOp and TruncateIOp to spirv::UConvertOp and spirv::SConvertOp.

Depends On D78974

Differential Revision: https://reviews.llvm.org/D79143
2020-04-30 19:29:31 -07:00
Hanhan Wang
6601b65aed [mlir][StandardToSPIRV] Emulate bitwidths not supported for load op.
Summary:
The current implementation in SPIRVTypeConverter just unconditionally turns
everything into 32-bit if it doesn't meet the requirements of extensions or
capabilities. In this case, we can load a 32-bit value and then do bit
extraction to get the value.

Differential Revision: https://reviews.llvm.org/D78974
2020-04-30 19:27:45 -07:00
MaheshRavishankar
1c12a95d9c [mlir][StandardToSPIRV] Handle conversion of cmpi operation with i1
type operands.

The instructions used to convert std.cmpi cannot have i1 types
according to SPIR-V specification. A different set of operations are
specified in the SPIR-V spec for comparing boolean types. Enhance the
StandardToSPIRV lowering to target these instructions when operands to
std.cmpi operation are of i1 type.

Differential Revision: https://reviews.llvm.org/D79049
2020-04-29 10:09:03 -07:00
Tres Popp
2d2d696137 [MLIR] Propagate input side effect information
Summary:
Previously operations like std.load created methods for obtaining their
effects but did not inherit from the SideEffect interfaces when their
parameters were decorated with the information. The resulting situation
was that passes had no information on the SideEffects of std.load/store
and had to treat them more cautiously. This adds the inheritance
information when creating the methods.

As a side effect, many tests are modified, as they were using std.load
for testing and this oepration would be folded away as part of pattern
rewriting. Tests are modified to use store or to reutn the result of the
std.load.

Reviewers: mravishankar, antiagainst, nicolasvasilache, herhut, aartbik, ftynse!

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

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D78802
2020-04-27 11:35:52 +02:00
MaheshRavishankar
9391941bd3 [mlir][StandardToSPIRV] Fix test cases where DCE removes all the code.
Differential Revision: https://reviews.llvm.org/D78727
2020-04-23 09:48:37 -07:00
Lei Zhang
ba49096817 [mlir][spirv] Lower memref with dynamic dimensions to runtime arrays
memref types with dynamic dimensions do not have a compile-time
known size. They should be mapped to SPIR-V runtime array types.

Differential Revision: https://reviews.llvm.org/D78197
2020-04-20 11:48:47 -04:00
Lei Zhang
a290c3af9d [mlir][spirv] Improve stride support in array types
This commit added stride support in runtime array types. It also
adjusted the assembly form for the stride from `[N]` to `stride=N`.
This makes the IR more readable, especially for the cases where
one mix array types and struct types.

Differential Revision: https://reviews.llvm.org/D78034
2020-04-13 14:08:17 -04:00
Mehdi Amini
bab5bcf8fd Add a flag on the context to protect against creation of operations in unregistered dialects
Differential Revision: https://reviews.llvm.org/D76903
2020-03-30 19:37:31 +00:00
Kazuaki Ishizaki
b632bd88a6 [mlir] NFC: fix trivial typo in documents
Reviewers: mravishankar, antiagainst, nicolasvasilache, herhut, aartbik, mehdi_amini, bondhugula

Reviewed By: mehdi_amini, bondhugula

Subscribers: bondhugula, jdoerfert, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, csigg, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, bader, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D76993
2020-03-30 00:34:23 +09:00
Hanhan Wang
58cdb8bff0 [mlir][StandardToSPIRV] Add support for lowering unary ops
Differential Revision: https://reviews.llvm.org/D76661
2020-03-24 09:16:10 -04:00
Lei Zhang
73431a492b [mlir][spirv] Consolidate std.constant to spv.constant conversions
This commit merges the DRR pattern for std.constant to spv.constant
conversion into the C++ OpConversionPattern. This allows us to have
remove the DRR pattern file. Along the way, this commit enhanced
std.constant to spv.constant conversion to consider type conversions,
which means converting the underlying attributes if necessary.

Differential Revision: https://reviews.llvm.org/D76246
2020-03-18 20:11:05 -04:00
Lei Zhang
ffd4583c6a [mlir][spirv] Change standard op patterns to consider type conversion
Previously we have a few patterns that were written with DRR. DRR
at the moment does not work nicely with dialect conversion framework.
It generates normal RewritePatterns, while the dialect conversion
framework requires ConversionPatterns to take into consideration
the type conversion. So this commit starts to change existing DRR
patterns for standard ops to OpConversionPattern to incorporate the
SPIR-V type conversion. All patterns are converted except the one
for constant ops, which will happen in a subsequent commit.

Differential Revision: https://reviews.llvm.org/D76245
2020-03-18 20:11:05 -04:00
Lei Zhang
9efb4b4023 [mlir][spirv] Make SPIRVTypeConverter target environment aware
Non-32-bit scalar types requires special hardware support that may
not exist on all Vulkan-capable GPUs. This is reflected as non-32-bit
scalar types require special capabilities or extensions to be used.
This commit makes SPIRVTypeConverter target environment aware so
that it can properly convert standard types to what is accepted on
the target environment.

Right now if a scalar type bitwidth is not supported in the target
environment, we use 32-bit unconditionally. This requires Vulkan
runtime to also feed in data with a matched bitwidth and layout,
especially for interface types. The Vulkan runtime can do that by
inspecting the SPIR-V module. Longer term, we might want to introduce
a way to control how such case are handled and explicitly fail
if wanted.

Differential Revision: https://reviews.llvm.org/D76244
2020-03-18 20:11:05 -04:00
Lei Zhang
67e8690e53 [mlir][spirv] Let SPIRVConversionTarget consider type availability
Previously we only consider the version/extension/capability requirement
on the op itself. This commit updates SPIRVConversionTarget to also
take into consideration the values' types when deciding op legality.

Differential Revision: https://reviews.llvm.org/D75876
2020-03-18 20:11:04 -04:00