• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 'llvm' Dialect
2
3This dialect wraps the LLVM IR types and instructions into MLIR types and
4operations. It provides several additional operations that are necessary to
5cover for the differences in the IR structure (e.g., MLIR does not have `phi`
6operations and LLVM IR does not have a `constant` operation).
7
8In this document, we use "LLVM IR" to designate the
9[intermediate representation of LLVM](https://llvm.org/docs/LangRef.html) and
10"LLVM IR _dialect_" to refer to the MLIR dialect reflecting LLVM instructions
11and types.
12
13[TOC]
14
15## Context and Module Association
16
17The LLVM IR dialect object _contains_ an LLVM Context and an LLVM Module that it
18uses to define, print, parse and manage LLVM IR types. These objects can be
19obtained from the dialect object using `.getLLVMContext()` and
20`getLLVMModule()`. All LLVM IR objects that interact with the LLVM IR dialect
21must exist in the dialect's context.
22
23## Types
24
25The LLVM IR dialect defines a single MLIR type, `LLVM::LLVMType`, that can wrap
26any existing LLVM IR type. Its syntax is as follows
27
28```
29type ::= `!llvm<"` llvm-canonical-type `">
30llvm-canonical-type ::= <canonical textual representation defined by LLVM>
31```
32
33For example, one can use primitive types `!llvm.i32`, pointer types
34`!llvm<"i8*">`, vector types `!llvm<"<4 x float>">` or structure types
35`!llvm<"{i32, float}">`. The parsing and printing of the canonical form are
36delegated to the LLVM assembly parser and printer.
37
38LLVM IR dialect types contain an `llvm::Type*` object that can be obtained by
39calling `.getUnderlyingType()` and used in LLVM API calls directly. These
40objects are allocated within the LLVM context associated with the LLVM IR
41dialect and may be linked to the properties of the associated LLVM module.
42
43LLVM IR dialect type can be constructed from any `llvm::Type*` that is
44associated with the LLVM context of the dialect. In this document, we use the
45term "wrapped LLVM IR type" to refer to the LLVM IR dialect type containing a
46specific LLVM IR type.
47
48## Operations
49
50All operations in the LLVM IR dialect have a custom form in MLIR. The mnemonic
51of an operation is that used in LLVM IR prefixed with "`llvm.`".
52
53### LLVM functions
54
55MLIR functions are defined by an operation that is not built into the IR itself.
56The LLVM IR dialect provides an `llvm.func` operation to define functions
57compatible with LLVM IR. These functions have wrapped LLVM IR function type but
58use MLIR syntax to express it. They are required to have exactly one result
59type. LLVM function operation is intended to capture additional properties of
60LLVM functions, such as linkage and calling convention, that may be modeled
61differently by the built-in MLIR function.
62
63```mlir
64// The type of @bar is !llvm<"i64 (i64)">
65llvm.func @bar(%arg0: !llvm.i64) -> !llvm.i64 {
66  llvm.return %arg0 : !llvm.i64
67}
68
69// Type type of @foo is !llvm<"void (i64)">
70// !llvm.void type is omitted
71llvm.func @foo(%arg0: !llvm.i64) {
72  llvm.return
73}
74
75// A function with `internal` linkage.
76llvm.func internal @internal_func() {
77  llvm.return
78}
79
80```
81
82#### Attribute pass-through
83
84An LLVM IR dialect function provides a mechanism to forward function-level
85attributes to LLVM IR using the `passthrough` attribute. This is an array
86attribute containing either string attributes or array attributes. In the former
87case, the value of the string is interpreted as the name of LLVM IR function
88attribute. In the latter case, the array is expected to contain exactly two
89string attributes, the first corresponding to the name of LLVM IR function
90attribute, and the second corresponding to its value. Note that even integer
91LLVM IR function attributes have their value represented in the string form.
92
93Example:
94
95```mlir
96llvm.func @func() attributes {
97  passthrough = ["noinline",           // value-less attribute
98                 ["alignstack", "4"],  // integer attribute with value
99                 ["other", "attr"]]    // attribute unknown to LLVM
100} {
101  llvm.return
102}
103```
104
105If the attribute is not known to LLVM IR, it will be attached as a string
106attribute.
107
108#### Linkage
109
110An LLVM IR dialect function has a linkage attribute derived from LLVM IR
111[linkage types](https://llvm.org/docs/LangRef.html#linkage-types). Linkage is
112specified by the same keyword as in LLVM IR and is located between `llvm.func`
113and the symbol name. If no linkage keyword is present, `external` linkage is
114assumed by default.
115
116### LLVM IR operations
117
118The following operations are currently supported. The semantics of these
119operations corresponds to the semantics of the similarly-named LLVM IR
120instructions.
121
122#### Integer binary arithmetic operations
123
124Take two arguments of wrapped LLVM IR integer type, produce one value of the
125same type.
126
127-   `add`
128-   `sub`
129-   `mul`
130-   `udiv`
131-   `sdiv`
132-   `urem`
133-   `srem`
134
135Examples:
136
137```mlir
138// Integer addition.
139%0 = llvm.add %a, %b : !llvm.i32
140
141// Unsigned integer division.
142%1 = llvm.udiv %a, %b : !llvm.i32
143```
144
145#### Floating point binary arithmetic operations
146
147Take two arguments of wrapped LLVM IR floating point type, produce one value of
148the same type.
149
150-   `fadd`
151-   `fsub`
152-   `fmul`
153-   `fdiv`
154-   `frem`
155
156Examples:
157
158```mlir
159// Float addition.
160%0 = llvm.fadd %a, %b : !llvm.float
161
162// Float division.
163%1 = llvm.fdiv %a, %b : !llvm.float
164```
165
166#### Memory-related operations
167
168-   `<r> = alloca <size> x <type>`
169-   `<r> = getelementptr <address>[<index> (, <index>)+]`
170-   `<r> = load <address>`
171-   `store <value>, <address>`
172
173In these operations, `<size>` must be a value of wrapped LLVM IR integer type,
174`<address>` must be a value of wrapped LLVM IR pointer type, and `<value>` must
175be a value of wrapped LLVM IR type that corresponds to the pointer type of
176`<address>`.
177
178The `index` operands are integer values whose semantics is identical to the
179non-pointer arguments of LLVM IR's `getelementptr`.
180
181Examples:
182
183```mlir
184// Allocate an array of 4 floats on stack
185%c4 = llvm.mlir.constant(4) : !llvm.i64
186%0 = llvm.alloca %c4 x !llvm.float : (!llvm.i64) -> !llvm<"float*">
187
188// Get the second element of the array (note 0-based indexing).
189%c1 = llvm.mlir.constant(1) : !llvm.i64
190%1 = llvm.getelementptr %0[%c1] : (!llvm<"float*">, !llvm.i64)
191                                   -> !llvm<"float*">
192
193// Store a constant into this element.
194%cf = llvm.mlir.constant(42.0 : f32) : !llvm.float
195llvm.store %cf, %1 : !llvm<"float*">
196
197// Load the value from this element.
198%3 = llvm.load %1 : !llvm<"float*">
199```
200
201#### Operations on values of aggregate type.
202
203-   `<value> = extractvalue <struct>[<index> (, <index>)+]`
204-   `<struct> = insertvalue <value>, <struct>[<index> (, <index>)+]`
205
206In these operations, `<struct>` must be a value of wrapped LLVM IR structure
207type and `<value>` must be a value that corresponds to one of the (nested)
208structure element types.
209
210Note the use of integer literals to designate subscripts, which is made possible
211by `extractvalue` and `insertvalue` must have constant subscripts. Internally,
212they are modeled as array attributes.
213
214Examples:
215
216```mlir
217// Get the value third element of the second element of a structure.
218%0 = llvm.extractvalue %s[1, 2] : !llvm<"{i32, {i1, i8, i16}">
219
220// Insert the value to the third element of the second element of a structure.
221// Note that this returns a new structure-typed value.
222%1 = llvm.insertvalue %0, %s[1, 2] : !llvm<"{i32, {i1, i8, i16}">
223```
224
225#### Terminator operations.
226
227Branch operations:
228
229-   `br [<successor>(<operands>)]`
230-   `cond_br <condition> [<true-successor>(<true-operands>),`
231    `<false-successor>(<false-operands>)]`
232
233In order to comply with MLIR design, branch operations in the LLVM IR dialect
234pass arguments to basic blocks. Successors must be valid block MLIR identifiers
235and operand lists for each of them must have the same types as the arguments of
236the respective blocks. `<condition>` must be a wrapped LLVM IR `i1` type.
237
238Since LLVM IR uses the name of the predecessor basic block to identify the
239sources of a PHI node, it is invalid for two entries of the PHI node to indicate
240different values coming from the same block. Therefore, `cond_br` in the LLVM IR
241dialect disallows its successors to be the same block _if_ this block has
242arguments.
243
244Examples:
245
246```mlir
247// Branch without arguments.
248^bb0:
249  llvm.br ^bb0
250
251// Branch and pass arguments.
252^bb1(%arg: !llvm.i32):
253  llvm.br ^bb1(%arg : !llvm.i32)
254
255// Conditionally branch and pass arguments to one of the blocks.
256llvm.cond_br %cond, ^bb0, %bb1(%arg : !llvm.i32)
257
258// It's okay to use the same block without arguments, but probably useless.
259llvm.cond_br %cond, ^bb0, ^bb0
260
261// ERROR: Passing different arguments to the same block in a conditional branch.
262llvm.cond_br %cond, ^bb1(%0 : !llvm.i32), ^bb1(%1 : !llvm.i32)
263
264```
265
266Call operations:
267
268-   `<r> = call(<operands>)`
269-   `call(<operands>)`
270
271In LLVM IR, functions may return either 0 or 1 value. LLVM IR dialect implements
272this behavior by providing a variadic `call` operation for 0- and 1-result
273functions. Even though MLIR supports multi-result functions, LLVM IR dialect
274disallows them.
275
276The `call` instruction supports both direct and indirect calls. Direct calls
277start with a function name (`@`-prefixed) and indirect calls start with an SSA
278value (`%`-prefixed). The direct callee, if present, is stored as a function
279attribute `callee`. The trailing type of the instruction is always the MLIR
280function type, which may be different from the indirect callee that has the
281wrapped LLVM IR function type.
282
283Examples:
284
285```mlir
286// Direct call without arguments and with one result.
287%0 = llvm.call @foo() : () -> (!llvm.float)
288
289// Direct call with arguments and without a result.
290llvm.call @bar(%0) : (!llvm.float) -> ()
291
292// Indirect call with an argument and without a result.
293llvm.call %1(%0) : (!llvm.float) -> ()
294```
295
296#### Miscellaneous operations.
297
298Integer comparisons: `icmp "predicate" <lhs>, <rhs>`. The following predicate
299values are supported:
300
301-   `eq` - equality comparison;
302-   `ne` - inequality comparison;
303-   `slt` - signed less-than comparison
304-   `sle` - signed less-than-or-equal comparison
305-   `sgt` - signed greater-than comparison
306-   `sge` - signed greater-than-or-equal comparison
307-   `ult` - unsigned less-than comparison
308-   `ule` - unsigned less-than-or-equal comparison
309-   `ugt` - unsigned greater-than comparison
310-   `uge` - unsigned greater-than-or-equal comparison
311
312Bitwise reinterpretation: `bitcast <value>`.
313
314Selection: `select <condition>, <lhs>, <rhs>`.
315
316### Auxiliary MLIR Operations for Constants and Globals
317
318LLVM IR has broad support for first-class constants, which is not the case for
319MLIR. Instead, constants are defined in MLIR as regular SSA values produced by
320operations with specific traits. The LLVM dialect provides a set of operations
321that model LLVM IR constants. These operations do not correspond to LLVM IR
322instructions and are therefore prefixed with `llvm.mlir`.
323
324Inline constants can be created by `llvm.mlir.constant`, which currently
325supports integer, float, string or elements attributes (constant structs are not
326currently supported). LLVM IR constant expressions are expected to be
327constructed as sequences of regular operations on SSA values produced by
328`llvm.mlir.constant`. Additionally, MLIR provides semantically-charged
329operations `llvm.mlir.undef` and `llvm.mlir.null` for the corresponding
330constants.
331
332LLVM IR globals can be defined using `llvm.mlir.global` at the module level,
333except for functions that are defined with `llvm.func`. Globals, both variables
334and functions, can be accessed by taking their address with the
335`llvm.mlir.addressof` operation, which produces a pointer to the named global,
336unlike the `llvm.mlir.constant` that produces the value of the same type as the
337constant.
338
339#### `llvm.mlir.addressof`
340
341Creates an SSA value containing a pointer to a global variable or constant
342defined by `llvm.mlir.global`. The global value can be defined after its first
343referenced. If the global value is a constant, storing into it is not allowed.
344
345Examples:
346
347```mlir
348func @foo() {
349  // Get the address of a global variable.
350  %0 = llvm.mlir.addressof @const : !llvm<"i32*">
351
352  // Use it as a regular pointer.
353  %1 = llvm.load %0 : !llvm<"i32*">
354
355  // Get the address of a function.
356  %2 = llvm.mlir.addressof @foo : !llvm<"void ()*">
357
358  // The function address can be used for indirect calls.
359  llvm.call %2() : () -> ()
360}
361
362// Define the global.
363llvm.mlir.global @const(42 : i32) : !llvm.i32
364```
365
366#### `llvm.mlir.constant`
367
368Unlike LLVM IR, MLIR does not have first-class constant values. Therefore, all
369constants must be created as SSA values before being used in other operations.
370`llvm.mlir.constant` creates such values for scalars and vectors. It has a
371mandatory `value` attribute, which may be an integer, floating point attribute;
372dense or sparse attribute containing integers or floats. The type of the
373attribute is one of the corresponding MLIR builtin types. It may be omitted for
374`i64` and `f64` types that are implied. The operation produces a new SSA value
375of the specified LLVM IR dialect type. The type of that value _must_ correspond
376to the attribute type converted to LLVM IR.
377
378Examples:
379
380```mlir
381// Integer constant, internal i32 is mandatory
382%0 = llvm.mlir.constant(42 : i32) : !llvm.i32
383
384// It's okay to omit i64.
385%1 = llvm.mlir.constant(42) : !llvm.i64
386
387// Floating point constant.
388%2 = llvm.mlir.constant(42.0 : f32) : !llvm.float
389
390// Splat dense vector constant.
391%3 = llvm.mlir.constant(dense<1.0> : vector<4xf32>) : !llvm<"<4 x float>">
392```
393
394#### `llvm.mlir.global`
395
396Since MLIR allows for arbitrary operations to be present at the top level,
397global variables are defined using the `llvm.mlir.global` operation. Both global
398constants and variables can be defined, and the value may also be initialized in
399both cases.
400
401There are two forms of initialization syntax. Simple constants that can be
402represented as MLIR attributes can be given in-line:
403
404```mlir
405llvm.mlir.global @variable(32.0 : f32) : !llvm.float
406```
407
408This initialization and type syntax is similar to `llvm.mlir.constant` and may
409use two types: one for MLIR attribute and another for the LLVM value. These
410types must be compatible.
411
412More complex constants that cannot be represented as MLIR attributes can be
413given in an initializer region:
414
415```mlir
416// This global is initialized with the equivalent of:
417//   i32* getelementptr (i32* @g2, i32 2)
418llvm.mlir.global constant @int_gep() : !llvm<"i32*"> {
419  %0 = llvm.mlir.addressof @g2 : !llvm<"i32*">
420  %1 = llvm.mlir.constant(2 : i32) : !llvm.i32
421  %2 = llvm.getelementptr %0[%1] : (!llvm<"i32*">, !llvm.i32) -> !llvm<"i32*">
422  // The initializer region must end with `llvm.return`.
423  llvm.return %2 : !llvm<"i32*">
424}
425```
426
427Only one of the initializer attribute or initializer region may be provided.
428
429`llvm.mlir.global` must appear at top-level of the enclosing module. It uses an
430@-identifier for its value, which will be uniqued by the module with respect to
431other @-identifiers in it.
432
433Examples:
434
435```mlir
436// Global values use @-identifiers.
437llvm.mlir.global constant @cst(42 : i32) : !llvm.i32
438
439// Non-constant values must also be initialized.
440llvm.mlir.global @variable(32.0 : f32) : !llvm.float
441
442// Strings are expected to be of wrapped LLVM i8 array type and do not
443// automatically include the trailing zero.
444llvm.mlir.global @string("abc") : !llvm<"[3 x i8]">
445
446// For strings globals, the trailing type may be omitted.
447llvm.mlir.global constant @no_trailing_type("foo bar")
448
449// A complex initializer is constructed with an initializer region.
450llvm.mlir.global constant @int_gep() : !llvm<"i32*"> {
451  %0 = llvm.mlir.addressof @g2 : !llvm<"i32*">
452  %1 = llvm.mlir.constant(2 : i32) : !llvm.i32
453  %2 = llvm.getelementptr %0[%1] : (!llvm<"i32*">, !llvm.i32) -> !llvm<"i32*">
454  llvm.return %2 : !llvm<"i32*">
455}
456```
457
458Similarly to functions, globals have a linkage attribute. In the custom syntax,
459this attribute is placed between `llvm.mlir.global` and the optional `constant`
460keyword. If the attribute is omitted, `external` linkage is assumed by default.
461
462Examples:
463
464```mlir
465// A constant with internal linkage will not participate in linking.
466llvm.mlir.global internal constant @cst(42 : i32) : !llvm.i32
467
468// By default, "external" linkage is assumed and the global participates in
469// symbol resolution at link-time.
470llvm.mlir.global @glob(0 : f32) : !llvm.float
471```
472
473#### `llvm.mlir.null`
474
475Unlike LLVM IR, MLIR does not have first-class null pointers. They must be
476explicitly created as SSA values using `llvm.mlir.null`. This operation has
477no operands or attributes, and returns a null value of a wrapped LLVM IR
478pointer type.
479
480Examples:
481
482```mlir
483// Null pointer to i8 value.
484%0 = llvm.mlir.null : !llvm<"i8*">
485
486// Null pointer to a function with signature void() value.
487%1 = llvm.mlir.null : !llvm<"void()*">
488```
489
490#### `llvm.mlir.undef`
491
492Unlike LLVM IR, MLIR does not have first-class undefined values. Such values
493must be created as SSA values using `llvm.mlir.undef`. This operation has no
494operands or attributes. It creates an undefined value of the specified LLVM IR
495dialect type wrapping an LLVM IR structure type.
496
497Example:
498
499```mlir
500// Create a structure with a 32-bit integer followed by a float.
501%0 = llvm.mlir.undef : !llvm<"{i32, float}">
502```
503