Skip to content

Commit

Permalink
Give assembly formats for cf
Browse files Browse the repository at this point in the history
  • Loading branch information
alexarice committed Sep 2, 2024
1 parent 55c734e commit ee5bb7b
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 42 deletions.
4 changes: 2 additions & 2 deletions tests/dialects/test_cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def test_assert():

assert c.arg is a.result
assert d.arg is b.result
assert c.properties["msg"] == StringAttr("a")
assert d.properties["msg"] == StringAttr("b")
assert c.attributes["msg"] == StringAttr("a")
assert d.attributes["msg"] == StringAttr("b")


def test_branch():
Expand Down
75 changes: 52 additions & 23 deletions tests/filecheck/dialects/cf/cf_ops.mlir
Original file line number Diff line number Diff line change
@@ -1,52 +1,81 @@
// RUN: XDSL_ROUNDTRIP
// RUN: XDSL_GENERIC_ROUNDTRIP

builtin.module {
func.func private @assert() {
%cond = arith.constant true
"cf.assert"(%cond) {"msg" = "some message"} : (i1) -> ()
cf.assert %cond , "some message"
func.return
}
// CHECK: func.func private @assert() {
// CHECK-NEXT: %{{.*}} = arith.constant true
// CHECK-NEXT: "cf.assert"(%{{.*}}) <{"msg" = "some message"}> : (i1) -> ()
// CHECK-NEXT: func.return
// CHECK-NEXT: }
// CHECK-NEXT: %cond = arith.constant true
// CHECK-NEXT: cf.assert %cond, "some message"
// CHECK-NEXT: func.return
// CHECK-NEXT: }

// CHECK-GENERIC: "func.func"() <{"sym_name" = "assert", "function_type" = () -> (), "sym_visibility" = "private"}> ({
// CHECK-GENERIC-NEXT: %{{.*}} = "arith.constant"() <{"value" = true}> : () -> i1
// CHECK-GENERIC-NEXT: "cf.assert"(%{{.*}}) {"msg" = "some message"} : (i1) -> ()
// CHECK-GENERIC-NEXT: "func.return"() : () -> ()
// CHECK-GENERIC-NEXT: }

func.func private @unconditional_br() {
"cf.br"() [^0] : () -> ()
cf.br ^0
^0:
"cf.br"() [^0] : () -> ()
cf.br ^0
}
// CHECK: func.func private @unconditional_br() {
// CHECK-NEXT: "cf.br"() [^{{.*}}] : () -> ()
// CHECK-NEXT: ^{{.*}}:
// CHECK-NEXT: "cf.br"() [^{{.*}}] : () -> ()
// CHECK-NEXT: cf.br ^0
// CHECK-NEXT: ^0:
// CHECK-NEXT: cf.br ^0
// CHECK-NEXT: }

// CHECK-GENERIC: "func.func"() <{"sym_name" = "unconditional_br", "function_type" = () -> (), "sym_visibility" = "private"}> ({
// CHECK-GENERIC-NEXT: "cf.br"() [^{{.*}}] : () -> ()
// CHECK-GENERIC-NEXT: ^{{.*}}:
// CHECK-GENERIC-NEXT: "cf.br"() [^{{.*}}] : () -> ()
// CHECK-GENERIC-NEXT: }

func.func private @br(%0 : i32) {
"cf.br"(%0) [^0] : (i32) -> ()
cf.br ^0(%0 : i32)
^0(%1 : i32):
"cf.br"(%1) [^0] : (i32) -> ()
cf.br ^0(%1 : i32)
}
// CHECK: func.func private @br(%{{.*}} : i32) {
// CHECK-NEXT: "cf.br"(%{{.*}}) [^{{.*}}] : (i32) -> ()
// CHECK-NEXT: ^{{.*}}(%{{.*}} : i32):
// CHECK-NEXT: "cf.br"(%{{.*}}) [^{{.*}}] : (i32) -> ()
// CHECK: func.func private @br(%0 : i32) {
// CHECK-NEXT: cf.br ^0(%0 : i32)
// CHECK-NEXT: ^0(%1 : i32):
// CHECK-NEXT: cf.br ^0(%1 : i32)
// CHECK-NEXT: }

// CHECK-GENERIC: "func.func"() <{"sym_name" = "br", "function_type" = (i32) -> (), "sym_visibility" = "private"}> ({
// CHECK-GENERIC-NEXT: ^{{.*}}(%{{.*}} : i32):
// CHECK-GENERIC-NEXT: "cf.br"(%{{.*}}) [^{{.*}}] : (i32) -> ()
// CHECK-GENERIC-NEXT: ^{{.*}}(%{{.*}} : i32):
// CHECK-GENERIC-NEXT: "cf.br"(%{{.*}}) [^{{.*}}] : (i32) -> ()
// CHECK-GENERIC-NEXT: }


func.func private @cond_br(%2 : i1, %3 : i32) -> i32 {
"cf.br"(%2, %3) [^0] : (i1, i32) -> ()
cf.br ^0(%2, %3 : i1, i32)
^0(%4 : i1, %5 : i32):
"cf.cond_br"(%4, %4, %5, %5, %5, %5) [^0, ^1] {"operandSegmentSizes" = array<i32: 1, 2, 3>} : (i1, i1, i32, i32, i32, i32) -> ()
cf.cond_br %4 , ^0(%4, %5 : i1, i32) , ^1(%5, %5, %5 : i32, i32, i32)
^1(%6 : i32, %7 : i32, %8 : i32):
func.return %6 : i32
}
// CHECK: func.func private @cond_br(%0 : i1, %1 : i32) -> i32 {
// CHECK-NEXT: "cf.br"(%{{.*}}, %{{.*}}) [^{{.*}}] : (i1, i32) -> ()
// CHECK-NEXT: ^{{.*}}(%{{.*}} : i1, %{{.*}} : i32):
// CHECK-NEXT: "cf.cond_br"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) [^{{.*}}, ^{{.*}}] <{"operandSegmentSizes" = array<i32: 1, 2, 3>}> : (i1, i1, i32, i32, i32, i32) -> ()
// CHECK-NEXT: ^{{.*}}(%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32):
// CHECK-NEXT: func.return %{{.*}} : i32
// CHECK-NEXT: cf.br ^0(%0, %1 : i1, i32)
// CHECK-NEXT: ^0(%2 : i1, %3 : i32):
// CHECK-NEXT: cf.cond_br %2, ^0(%2, %3 : i1, i32), ^1(%3, %3, %3 : i32, i32, i32)
// CHECK-NEXT: ^1(%4 : i32, %5 : i32, %6 : i32):
// CHECK-NEXT: func.return %4 : i32
// CHECK-NEXT: }

// CHECK-GENERIC: "func.func"() <{"sym_name" = "cond_br", "function_type" = (i1, i32) -> i32, "sym_visibility" = "private"}> ({
// CHECK-GENERIC-NEXT: ^{{.*}}(%{{.*}} : i1, %{{.*}} : i32):
// CHECK-GENERIC-NEXT: "cf.br"(%{{.*}}, %{{.*}}) [^{{.*}}] : (i1, i32) -> ()
// CHECK-GENERIC-NEXT: ^{{.*}}(%{{.*}} : i1, %{{.*}} : i32):
// CHECK-GENERIC-NEXT: "cf.cond_br"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) [^{{.*}}, ^{{.*}}] <{"operandSegmentSizes" = array<i32: 1, 2, 3>}> : (i1, i1, i32, i32, i32, i32) -> ()
// CHECK-GENERIC-NEXT: ^{{.*}}(%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32):
// CHECK-GENERIC-NEXT: "func.return"(%{{.*}}) : (i32) -> ()
// CHECK-GENERIC-NEXT: }
}
4 changes: 2 additions & 2 deletions tests/filecheck/frontend/dialects/cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

p = FrontendProgram()
with CodeContext(p):
# CHECK: "cf.assert"(%{{.*}}) <{"msg" = ""}> : (i1) -> ()
# CHECK: cf.assert %{{.*}}, ""
def test_assert_I(cond: i1):
assert cond
return

# CHECK: "cf.assert"(%{{.*}}) <{"msg" = "some message"}> : (i1) -> ()
# CHECK: cf.assert %{{.*}}, "some message"
def test_assert_II(cond: i1):
assert cond, "some message"
return
Expand Down
24 changes: 12 additions & 12 deletions tests/filecheck/transforms/cse.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -134,20 +134,20 @@ func.func @different_ops() -> (i32, i32) {
func.func @down_propagate() -> i32 {
%27 = arith.constant 1 : i32
%28 = arith.constant true
"cf.cond_br"(%28, %27) [^1, ^2] <{"operandSegmentSizes" = array<i32: 1, 0, 1>}> : (i1, i32) -> ()
cf.cond_br %28, ^1, ^2(%27 : i32)
^1:
%29 = arith.constant 1 : i32
"cf.br"(%29) [^2] : (i32) -> ()
cf.br ^2(%29 : i32)
^2(%30 : i32):
func.return %30 : i32
}

// CHECK: %0 = arith.constant 1 : i32
// CHECK-NEXT: %1 = arith.constant true
// CHECK-NEXT: "cf.cond_br"(%1, %0) [^0, ^1] <{"operandSegmentSizes" = array<i32: 1, 0, 1>}> : (i1, i32) -> ()
// CHECK-NEXT: cf.cond_br %1, ^0, ^1(%0 : i32)
// CHECK-NEXT: ^0:
// CHECK-NEXT: %2 = arith.constant 1 : i32
// CHECK-NEXT: "cf.br"(%2) [^1] : (i32) -> ()
// CHECK-NEXT: cf.br ^1(%2 : i32)
// CHECK-NEXT: ^1(%3 : i32):
// CHECK-NEXT: func.return %3 : i32
// CHECK-NEXT: }
Expand Down Expand Up @@ -179,10 +179,10 @@ func.func @down_propagate() -> i32 {
func.func @up_propagate() -> i32 {
%33 = arith.constant 0 : i32
%34 = arith.constant true
"cf.cond_br"(%34, %33) [^4, ^5] <{"operandSegmentSizes" = array<i32: 1, 0, 1>}> : (i1, i32) -> ()
cf.cond_br %34, ^4, ^5(%33 : i32)
^4:
%35 = arith.constant 1 : i32
"cf.br"(%35) [^5] : (i32) -> ()
cf.br ^5(%35 : i32)
^5(%36 : i32):
%37 = arith.constant 1 : i32
%38 = arith.addi %36, %37 : i32
Expand All @@ -191,10 +191,10 @@ func.func @up_propagate() -> i32 {

// CHECK: %0 = arith.constant 0 : i32
// CHECK-NEXT: %1 = arith.constant true
// CHECK-NEXT: "cf.cond_br"(%1, %0) [^0, ^1] <{"operandSegmentSizes" = array<i32: 1, 0, 1>}> : (i1, i32) -> ()
// CHECK-NEXT: cf.cond_br %1, ^0, ^1(%0 : i32)
// CHECK-NEXT: ^0:
// CHECK-NEXT: %2 = arith.constant 1 : i32
// CHECK-NEXT: "cf.br"(%2) [^1] : (i32) -> ()
// CHECK-NEXT: cf.br ^1(%2 : i32)
// CHECK-NEXT: ^1(%3 : i32):
// CHECK-NEXT: %4 = arith.constant 1 : i32
// CHECK-NEXT: %5 = arith.addi %3, %4 : i32
Expand All @@ -208,10 +208,10 @@ func.func @up_propagate_region() -> i32 {
%39 = "foo.region"() ({
%40 = arith.constant 0 : i32
%41 = arith.constant true
"cf.cond_br"(%41, %40) [^6, ^7] <{"operandSegmentSizes" = array<i32: 1, 0, 1>}> : (i1, i32) -> ()
cf.cond_br %41, ^6, ^7(%40 : i32)
^6:
%42 = arith.constant 1 : i32
"cf.br"(%42) [^7] : (i32) -> ()
cf.br ^7(%42 : i32)
^7(%43 : i32):
%44 = arith.constant 1 : i32
%45 = arith.addi %43, %44 : i32
Expand All @@ -223,10 +223,10 @@ func.func @up_propagate_region() -> i32 {
// CHECK: %0 = "foo.region"() ({
// CHECK-NEXT: %1 = arith.constant 0 : i32
// CHECK-NEXT: %2 = arith.constant true
// CHECK-NEXT: "cf.cond_br"(%2, %1) [^0, ^1] <{"operandSegmentSizes" = array<i32: 1, 0, 1>}> : (i1, i32) -> ()
// CHECK-NEXT: cf.cond_br %2, ^0, ^1(%1 : i32)
// CHECK-NEXT: ^0:
// CHECK-NEXT: %3 = arith.constant 1 : i32
// CHECK-NEXT: "cf.br"(%3) [^1] : (i32) -> ()
// CHECK-NEXT: cf.br ^1(%3 : i32)
// CHECK-NEXT: ^1(%4 : i32):
// CHECK-NEXT: %5 = arith.constant 1 : i32
// CHECK-NEXT: %6 = arith.addi %4, %5 : i32
Expand Down
4 changes: 2 additions & 2 deletions tests/filecheck/transforms/reconcile_unrealized_casts.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ builtin.module {
%1 = "builtin.unrealized_conversion_cast"(%0) : (i16) -> i1
%2 = "builtin.unrealized_conversion_cast"(%1) : (i1) -> i64
%3 = "builtin.unrealized_conversion_cast"(%1) : (i1) -> i16
"cf.br"(%c0)[^bb1] : (i32) -> ()
cf.br ^bb1(%c0 : i32)
^bb1(%33: i32): // pred: ^bb0
%4 = "builtin.unrealized_conversion_cast"(%3) : (i16) -> i64
%5 = "test.op"(%2, %4) : (i64, i64) -> i64
Expand All @@ -58,7 +58,7 @@ builtin.module {

// CHECK-NEXT: func.func @cycle_multiblock(%{{.*}} : i64) -> i64 {
// CHECK-NEXT: %c0 = "test.op"() : () -> i32
// CHECK-NEXT: "cf.br"(%c0) [^0] : (i32) -> ()
// CHECK-NEXT: cf.br ^0(%c0 : i32)
// CHECK-NEXT: ^0(%0 : i32):
// CHECK-NEXT: %1 = "test.op"(%{{.*}}, %{{.*}}) : (i64, i64) -> i64
// CHECK-NEXT: func.return %1 : i64
Expand Down
11 changes: 10 additions & 1 deletion xdsl/dialects/cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, arg: Operation | SSAValue, msg: str | StringAttr):
msg = StringAttr(msg)
super().__init__(
operands=[arg],
properties={"msg": msg},
attributes={"msg": msg},
)

assembly_format = "$arg `,` $msg attr-dict"
Expand All @@ -53,6 +53,8 @@ class Branch(IRDLOperation):
def __init__(self, dest: Block, *ops: Operation | SSAValue):
super().__init__(operands=[[op for op in ops]], successors=[dest])

assembly_format = "$successor (`(` $arguments^ `:` type($arguments) `)`)? attr-dict"


@irdl_op_definition
class ConditionalBranch(IRDLOperation):
Expand Down Expand Up @@ -83,6 +85,13 @@ def __init__(
operands=[cond, then_ops, else_ops], successors=[then_block, else_block]
)

assembly_format = """
$cond `,`
$then_block (`(` $then_arguments^ `:` type($then_arguments) `)`)? `,`
$else_block (`(` $else_arguments^ `:` type($else_arguments) `)`)?
attr-dict
"""


Cf = Dialect(
"cf",
Expand Down

0 comments on commit ee5bb7b

Please sign in to comment.