Skip to content

Commit

Permalink
dialects: Add LLVM InlineAsm op (#2203)
Browse files Browse the repository at this point in the history
This PR adds the LLVM InlineAsm op, which allows to bake in
inline assembly from within MLIR.

There's an additional attribute to select the inline assembly dialect
(not dialect in context of MLIR, choices are AT&T or Intel). I just
implemented this as an `IntegerAttr`.
  • Loading branch information
JosseVanDelm authored Feb 22, 2024
1 parent 8d74fbf commit 0be2ab3
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
16 changes: 16 additions & 0 deletions tests/filecheck/dialects/llvm/inline_asm.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: XDSL_ROUNDTRIP

%0 = "test.op"() : () -> i32
%1 = "test.op"() : () -> i32
"llvm.inline_asm"(%0, %1) <{asm_string = "csrw $0, $1", constraints = "i, r"}> {has_side_effect} : (i32, i32) -> ()

%2 = "test.op"() : () -> vector<8xf32>
%3 = "test.op"() : () -> vector<8xf32>
%4 = "llvm.inline_asm"(%2, %3) <{asm_dialect = 1 : i64, asm_string = "vaddps $0, $1, $2", constraints = "=x,x,x"}> : (vector<8xf32>, vector<8xf32>) -> vector<8xf32>

// CHECK: %0 = "test.op"() : () -> i32
// CHECK-NEXT: 1 = "test.op"() : () -> i32
// CHECK-NEXT: "llvm.inline_asm"(%0, %1) <{"asm_string" = "csrw $0, $1", "constraints" = "i, r"}> {"has_side_effect"} : (i32, i32) -> ()
// CHECK-NEXT: %2 = "test.op"() : () -> vector<8xf32>
// CHECK-NEXT: %3 = "test.op"() : () -> vector<8xf32>
// CHECK-NEXT: %4 = "llvm.inline_asm"(%2, %3) <{"asm_dialect" = 1 : i64, "asm_string" = "vaddps $0, $1, $2", "constraints" = "=x,x,x"}> : (vector<8xf32>, vector<8xf32>) -> vector<8xf32>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/// RUN: mlir-opt %s --mlir-print-op-generic | xdsl-opt --print-op-generic | filecheck %s

%0 = "test.op"() : () -> i32
%1 = "test.op"() : () -> i32
"llvm.inline_asm"(%0, %1) <{asm_string = "csrw $0, $1", constraints = "i, r"}> {has_side_effect} : (i32, i32) -> ()

%2 = "test.op"() : () -> vector<8xf32>
%3 = "test.op"() : () -> vector<8xf32>
%4 = "llvm.inline_asm"(%2, %3) <{asm_dialect = 1 : i64, asm_string = "vaddps $0, $1, $2", constraints = "=x,x,x"}> : (vector<8xf32>, vector<8xf32>) -> vector<8xf32>

// CHECK: %0 = "test.op"() : () -> i32
// CHECK-NEXT: 1 = "test.op"() : () -> i32
// CHECK-NEXT: "llvm.inline_asm"(%0, %1) <{"asm_string" = "csrw $0, $1", "constraints" = "i, r"}> {"has_side_effect"} : (i32, i32) -> ()
// CHECK-NEXT: %2 = "test.op"() : () -> vector<8xf32>
// CHECK-NEXT: %3 = "test.op"() : () -> vector<8xf32>
// CHECK-NEXT: %4 = "llvm.inline_asm"(%2, %3) <{"asm_dialect" = 1 : i64, "asm_string" = "vaddps $0, $1, $2", "constraints" = "=x,x,x"}> : (vector<8xf32>, vector<8xf32>) -> vector<8xf32>
55 changes: 55 additions & 0 deletions xdsl/dialects/llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,60 @@ def __init__(self, input: SSAValue | Operation, ptr_type: Attribute | None = Non
super().__init__(operands=[input], result_types=[ptr_type])


@irdl_op_definition
class InlineAsmOp(IRDLOperation):
"""
https://mlir.llvm.org/docs/Dialects/LLVM/#llvminline_asm-llvminlineasmop
To see what each field means, have a look at:
https://llvm.org/docs/LangRef.html#inline-assembler-expressions
"""

name = "llvm.inline_asm"

operands_: VarOperand = var_operand_def()

res: OptOpResult = opt_result_def()

# note: in MLIR upstream this is implemented as AsmDialectAttr;
# which is an instantiation of an LLVM_EnumAttr
# 0 for AT&T inline assembly dialect
# 1 for Intel inline assembly dialect
# In this context dialect does not refer to an MLIR dialect
asm_dialect = opt_prop_def(IntegerAttr[Annotated[IntegerType, IntegerType(64)]])

asm_string: StringAttr = prop_def(StringAttr)
constraints: StringAttr = prop_def(StringAttr)
has_side_effects: UnitAttr | None = opt_prop_def(UnitAttr)
is_align_stack: UnitAttr | None = opt_prop_def(UnitAttr)

def __init__(
self,
operands_: list[SSAValue | Operation],
res_types: list[Attribute],
asm_string: str,
constraints: str,
asm_dialect: int = 0,
has_side_effects: bool = False,
is_align_stack: bool = False,
):
props: dict[str, Attribute] = {
"asm_string": StringAttr(asm_string),
"constraints": StringAttr(constraints),
"asm_dialect": IntegerAttr.from_int_and_width(asm_dialect, 64),
}
if has_side_effects:
props["has_side_effects"] = UnitAttr()
if is_align_stack:
props["is_align_stack"] = UnitAttr()

super().__init__(
operands=operands_,
properties=props,
result_types=res_types,
)


@irdl_op_definition
class PtrToIntOp(IRDLOperation):
name = "llvm.ptrtoint"
Expand Down Expand Up @@ -1271,6 +1325,7 @@ def __init__(
AShrOp,
ExtractValueOp,
InsertValueOp,
InlineAsmOp,
UndefOp,
AllocaOp,
GEPOp,
Expand Down

0 comments on commit 0be2ab3

Please sign in to comment.