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