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 is 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### LLVM IR operations 109 110The following operations are currently supported. The semantics of these 111operations corresponds to the semantics of the similarly-named LLVM IR 112instructions. 113 114#### Integer binary arithmetic operations 115 116Take two arguments of wrapped LLVM IR integer type, produce one value of the 117same type. 118 119- `add` 120- `sub` 121- `mul` 122- `udiv` 123- `sdiv` 124- `urem` 125- `srem` 126 127Examples: 128 129```mlir 130// Integer addition. 131%0 = llvm.add %a, %b : !llvm.i32 132 133// Unsigned integer division. 134%1 = llvm.udiv %a, %b : !llvm.i32 135``` 136 137#### Floating point binary arithmetic operations 138 139Take two arguments of wrapped LLVM IR floating point type, produce one value of 140the same type. 141 142- `fadd` 143- `fsub` 144- `fmul` 145- `fdiv` 146- `frem` 147 148Examples: 149 150```mlir 151// Float addition. 152%0 = llvm.fadd %a, %b : !llvm.float 153 154// Float division. 155%1 = llvm.fdiv %a, %b : !llvm.float 156``` 157 158#### Memory-related operations 159 160- `<r> = alloca <size> x <type>` 161- `<r> = getelementptr <address>[<index> (, <index>)+]` 162- `<r> = load <address>` 163- `store <value>, <address>` 164 165In these operations, `<size>` must be a value of wrapped LLVM IR integer type, 166`<address>` must be a value of wrapped LLVM IR pointer type, and `<value>` must 167be a value of wrapped LLVM IR type that corresponds to the pointer type of 168`<address>`. 169 170The `index` operands are integer values whose semantics is identical to the 171non-pointer arguments of LLVM IR's `getelementptr`. 172 173Examples: 174 175```mlir 176// Allocate an array of 4 floats on stack 177%c4 = llvm.mlir.constant(4) : !llvm.i64 178%0 = llvm.alloca %c4 x !llvm.float : (!llvm.i64) -> !llvm<"float*"> 179 180// Get the second element of the array (note 0-based indexing). 181%c1 = llvm.mlir.constant(1) : !llvm.i64 182%1 = llvm.getelementptr %0[%c1] : (!llvm<"float*">, !llvm.i64) 183 -> !llvm<"float*"> 184 185// Store a constant into this element. 186%cf = llvm.mlir.constant(42.0 : f32) : !llvm.float 187llvm.store %cf, %1 : !llvm<"float*"> 188 189// Load the value from this element. 190%3 = llvm.load %1 : !llvm<"float*"> 191``` 192 193#### Operations on values of aggregate type. 194 195- `<value> = extractvalue <struct>[<index> (, <index>)+]` 196- `<struct> = insertvalue <value>, <struct>[<index> (, <index>)+]` 197 198In these operations, `<struct>` must be a value of wrapped LLVM IR structure 199type and `<value>` must be a value that corresponds to one of the (nested) 200structure element types. 201 202Note the use of integer literals to designate subscripts, which is made possible 203by `extractvalue` and `insertvalue` must have constant subscripts. Internally, 204they are modeled as array attributes. 205 206Examples: 207 208```mlir 209// Get the value third element of the second element of a structure. 210%0 = llvm.extractvalue %s[1, 2] : !llvm<"{i32, {i1, i8, i16}"> 211 212// Insert the value to the third element of the second element of a structure. 213// Note that this returns a new structure-typed value. 214%1 = llvm.insertvalue %0, %s[1, 2] : !llvm<"{i32, {i1, i8, i16}"> 215``` 216 217#### Terminator operations. 218 219Branch operations: 220 221- `br [<successor>(<operands>)]` 222- `cond_br <condition> [<true-successor>(<true-operands>),` 223 `<false-successor>(<false-operands>)]` 224 225In order to comply with MLIR design, branch operations in the LLVM IR dialect 226pass arguments to basic blocks. Successors must be valid block MLIR identifiers 227and operand lists for each of them must have the same types as the arguments of 228the respective blocks. `<condition>` must be a wrapped LLVM IR `i1` type. 229 230Since LLVM IR uses the name of the predecessor basic block to identify the 231sources of a PHI node, it is invalid for two entries of the PHI node to indicate 232different values coming from the same block. Therefore, `cond_br` in the LLVM IR 233dialect disallows its successors to be the same block _if_ this block has 234arguments. 235 236Examples: 237 238```mlir 239// Branch without arguments. 240^bb0: 241 llvm.br ^bb0 242 243// Branch and pass arguments. 244^bb1(%arg: !llvm.i32): 245 llvm.br ^bb1(%arg : !llvm.i32) 246 247// Conditionally branch and pass arguments to one of the blocks. 248llvm.cond_br %cond, ^bb0, %bb1(%arg : !llvm.i32) 249 250// It's okay to use the same block without arguments, but probably useless. 251llvm.cond_br %cond, ^bb0, ^bb0 252 253// ERROR: Passing different arguments to the same block in a conditional branch. 254llvm.cond_br %cond, ^bb1(%0 : !llvm.i32), ^bb1(%1 : !llvm.i32) 255 256``` 257 258Call operations: 259 260- `<r> = call(<operands>)` 261- `call(<operands>)` 262 263In LLVM IR, functions may return either 0 or 1 value. LLVM IR dialect implements 264this behavior by providing a variadic `call` operation for 0- and 1-result 265functions. Even though MLIR supports multi-result functions, LLVM IR dialect 266disallows them. 267 268The `call` instruction supports both direct and indirect calls. Direct calls 269start with a function name (`@`-prefixed) and indirect calls start with an SSA 270value (`%`-prefixed). The direct callee, if present, is stored as a function 271attribute `callee`. The trailing type of the instruction is always the MLIR 272function type, which may be different from the indirect callee that has the 273wrapped LLVM IR function type. 274 275Examples: 276 277```mlir 278// Direct call without arguments and with one result. 279%0 = llvm.call @foo() : () -> (!llvm.float) 280 281// Direct call with arguments and without a result. 282llvm.call @bar(%0) : (!llvm.float) -> () 283 284// Indirect call with an argument and without a result. 285llvm.call %1(%0) : (!llvm.float) -> () 286``` 287 288#### Miscellaneous operations. 289 290Integer comparisons: `icmp "predicate" <lhs>, <rhs>`. The following predicate 291values are supported: 292 293- `eq` - equality comparison; 294- `ne` - inequality comparison; 295- `slt` - signed less-than comparison 296- `sle` - signed less-than-or-equal comparison 297- `sgt` - signed greater-than comparison 298- `sge` - signed greater-than-or-equal comparison 299- `ult` - unsigned less-than comparison 300- `ule` - unsigned less-than-or-equal comparison 301- `ugt` - unsigned greater-than comparison 302- `uge` - unsigned greater-than-or-equal comparison 303 304Bitwise reinterpretation: `bitcast <value>`. 305 306Selection: `select <condition>, <lhs>, <rhs>`. 307 308### Auxiliary MLIR operations 309 310These operations do not have LLVM IR counterparts but are necessary to map LLVM 311IR into MLIR. They should be prefixed with `llvm.mlir`. 312 313#### `llvm.mlir.addressof` 314 315Creates an SSA value containing a pointer to a global variable or constant 316defined by `llvm.mlir.global`. The global value can be defined after its first 317referenced. If the global value is a constant, storing into it is not allowed. 318 319Examples: 320 321```mlir 322func @foo() { 323 // Get the address of a global. 324 %0 = llvm.mlir.addressof @const : !llvm<"i32*"> 325 326 // Use it as a regular pointer. 327 %1 = llvm.load %0 : !llvm<"i32*"> 328} 329 330// Define the global. 331llvm.mlir.global @const(42 : i32) : !llvm.i32 332``` 333 334#### `llvm.mlir.constant` 335 336Unlike LLVM IR, MLIR does not have first-class constant values. Therefore, all 337constants must be created as SSA values before being used in other operations. 338`llvm.mlir.constant` creates such values for scalars and vectors. It has a 339mandatory `value` attribute, which may be an integer, floating point attribute; 340dense or sparse attribute containing integers or floats. The type of the 341attribute is one the corresponding MLIR standard types. It may be omitted for 342`i64` and `f64` types that are implied. The operation produces a new SSA value 343of the specified LLVM IR dialect type. The type of that value _must_ correspond 344to the attribute type converted to LLVM IR. 345 346Examples: 347 348```mlir 349// Integer constant, internal i32 is mandatory 350%0 = llvm.mlir.constant(42 : i32) : !llvm.i32 351 352// It's okay to omit i64. 353%1 = llvm.mlir.constant(42) : !llvm.i64 354 355// Floating point constant. 356%2 = llvm.mlir.constant(42.0 : f32) : !llvm.float 357 358// Splat dense vector constant. 359%3 = llvm.mlir.constant(dense<1.0> : vector<4xf32>) : !llvm<"<4 x float>"> 360``` 361 362#### `llvm.mlir.global` 363 364Since MLIR allows for arbitrary operations to be present at the top level, 365global variables are defined using the `llvm.mlir.global` operation. Both global 366constants and variables can be defined, and the value may also be initialized in 367both cases. 368 369There are two forms of initialization syntax. Simple constants that can be 370represented as MLIR attributes can be given in-line: 371 372```mlir 373llvm.mlir.global @variable(32.0 : f32) : !llvm.float 374``` 375 376This initialization and type syntax is similar to `llvm.mlir.constant` and may 377use two types: one for MLIR attribute and another for the LLVM value. These 378types must be compatible. 379 380More complex constants that cannot be represented as MLIR attributes can be 381given in an initializer region: 382 383```mlir 384// This global is initialized with the equivalent of: 385// i32* getelementptr (i32* @g2, i32 2) 386llvm.mlir.global constant @int_gep() : !llvm<"i32*"> { 387 %0 = llvm.mlir.addressof @g2 : !llvm<"i32*"> 388 %1 = llvm.mlir.constant(2 : i32) : !llvm.i32 389 %2 = llvm.getelementptr %0[%1] : (!llvm<"i32*">, !llvm.i32) -> !llvm<"i32*"> 390 // The initializer region must end with `llvm.return`. 391 llvm.return %2 : !llvm<"i32*"> 392} 393``` 394 395Only one of the initializer attribute or initializer region may be provided. 396 397`llvm.mlir.global` must appear at top-level of the enclosing module. It uses an 398@-identifier for its value, which will be uniqued by the module with respect to 399other @-identifiers in it. 400 401Examples: 402 403```mlir 404// Global values use @-identifiers. 405llvm.mlir.global constant @cst(42 : i32) : !llvm.i32 406 407// Non-constant values must also be initialized. 408llvm.mlir.global @variable(32.0 : f32) : !llvm.float 409 410// Strings are expected to be of wrapped LLVM i8 array type and do not 411// automatically include the trailing zero. 412llvm.mlir.global @string("abc") : !llvm<"[3 x i8]"> 413 414// For strings globals, the trailing type may be omitted. 415llvm.mlir.global constant @no_trailing_type("foo bar") 416 417// A complex initializer is constructed with an initializer region. 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 llvm.return %2 : !llvm<"i32*"> 423} 424``` 425 426#### `llvm.mlir.null` 427 428Unlike LLVM IR, MLIR does not have first-class null pointers. They must be 429explicitly created as SSA values using `llvm.mlir.null`. This operation has 430operands or attributes, and returns a null value of a wrapped LLVM IR pointer 431type. 432 433Examples: 434 435```mlir 436// Null pointer to i8 value. 437%0 = llvm.mlir.null : !llvm<"i8*"> 438 439// Null pointer to a function with signature void() value. 440%1 = llvm.mlir.null : !llvm<"void()*"> 441``` 442 443#### `llvm.mlir.undef` 444 445Unlike LLVM IR, MLIR does not have first-class undefined values. Such values 446must be created as SSA values using `llvm.mlir.undef`. This operation has no 447operands or attributes. It creates an undefined value of the specified LLVM IR 448dialect type wrapping an LLVM IR structure type. 449 450Example: 451 452```mlir 453// Create a structure with a 32-bit integer followed by a float. 454%0 = llvm.mlir.undef : !llvm<"{i32, float}"> 455``` 456