Skip to content

Commit 685a98c

Browse files
authored
[mlir][emitc] Support array result for emitc.member and emitc.member_of_ptr (llvm#155224)
This PR adds array type as a valid result type for `emitc.member` and `emitc.member_of_ptr`, enabling direct access and assignment to struct array members in EmitC.
1 parent 200a9a8 commit 685a98c

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

mlir/include/mlir/Dialect/EmitC/IR/EmitC.td

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,14 +1051,16 @@ def EmitC_MemberOp : EmitC_Op<"member"> {
10511051
```mlir
10521052
%0 = "emitc.member" (%arg0) {member = "a"}
10531053
: (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
1054+
%1 = "emitc.member" (%arg0) {member = "b"}
1055+
: (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.array<2xi32>
10541056
```
10551057
}];
10561058

10571059
let arguments = (ins
10581060
Arg<StrAttr, "the member to access">:$member,
10591061
EmitC_LValueOf<[EmitC_OpaqueType]>:$operand
10601062
);
1061-
let results = (outs EmitC_LValueOf<[EmitCType]>);
1063+
let results = (outs AnyTypeOf<[EmitC_ArrayType, EmitC_LValueType]>);
10621064
}
10631065

10641066
def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
@@ -1073,14 +1075,17 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
10731075
%0 = "emitc.member_of_ptr" (%arg0) {member = "a"}
10741076
: (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>)
10751077
-> !emitc.lvalue<i32>
1078+
%1 = "emitc.member_of_ptr" (%arg0) {member = "b"}
1079+
: (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>)
1080+
-> !emitc.array<2xi32>
10761081
```
10771082
}];
10781083

10791084
let arguments = (ins
10801085
Arg<StrAttr, "the member to access">:$member,
10811086
EmitC_LValueOf<[EmitC_OpaqueType,EmitC_PointerType]>:$operand
10821087
);
1083-
let results = (outs EmitC_LValueOf<[EmitCType]>);
1088+
let results = (outs AnyTypeOf<[EmitC_ArrayType, EmitC_LValueType]>);
10841089
}
10851090

10861091
def EmitC_ConditionalOp : EmitC_Op<"conditional",

mlir/test/Dialect/EmitC/ops.mlir

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,11 @@ func.func @assign_global(%arg0 : i32) {
286286

287287
func.func @member_access(%arg0: !emitc.lvalue<!emitc.opaque<"mystruct">>, %arg1: !emitc.lvalue<!emitc.opaque<"mystruct_ptr">>, %arg2: !emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) {
288288
%0 = "emitc.member" (%arg0) {member = "a"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
289-
%1 = "emitc.member_of_ptr" (%arg1) {member = "a"} : (!emitc.lvalue<!emitc.opaque<"mystruct_ptr">>) -> !emitc.lvalue<i32>
290-
%2 = "emitc.member_of_ptr" (%arg2) {member = "a"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.lvalue<i32>
289+
%1 = "emitc.member" (%arg0) {member = "b"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.array<2xi32>
290+
%2 = "emitc.member_of_ptr" (%arg1) {member = "a"} : (!emitc.lvalue<!emitc.opaque<"mystruct_ptr">>) -> !emitc.lvalue<i32>
291+
%3 = "emitc.member_of_ptr" (%arg1) {member = "b"} : (!emitc.lvalue<!emitc.opaque<"mystruct_ptr">>) -> !emitc.array<2xi32>
292+
%4 = "emitc.member_of_ptr" (%arg2) {member = "a"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.lvalue<i32>
293+
%5 = "emitc.member_of_ptr" (%arg2) {member = "b"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.array<2xi32>
291294
return
292295
}
293296

mlir/test/Target/Cpp/member.mlir

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s -check-prefix=CPP-DEFAULT
22

3-
func.func @member(%arg0: !emitc.opaque<"mystruct">, %arg1: i32) {
3+
func.func @member(%arg0: !emitc.opaque<"mystruct">, %arg1: i32, %arg2: index) {
44
%var0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.opaque<"mystruct">>
55
emitc.assign %arg0 : !emitc.opaque<"mystruct"> to %var0 : !emitc.lvalue<!emitc.opaque<"mystruct">>
66

@@ -12,19 +12,31 @@ func.func @member(%arg0: !emitc.opaque<"mystruct">, %arg1: i32) {
1212
%3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
1313
emitc.assign %2 : i32 to %3 : !emitc.lvalue<i32>
1414

15+
%4 = "emitc.member" (%var0) {member = "c"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.array<2xi32>
16+
%5 = emitc.subscript %4[%arg2] : (!emitc.array<2xi32>, index) -> !emitc.lvalue<i32>
17+
%6 = emitc.load %5 : <i32>
18+
emitc.assign %6 : i32 to %3 : !emitc.lvalue<i32>
19+
20+
%7 = "emitc.member" (%var0) {member = "d"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.array<2xi32>
21+
%8 = emitc.subscript %7[%arg2] : (!emitc.array<2xi32>, index) -> !emitc.lvalue<i32>
22+
emitc.assign %arg1 : i32 to %8 : !emitc.lvalue<i32>
23+
1524
return
1625
}
1726

18-
// CPP-DEFAULT: void member(mystruct [[V0:[^ ]*]], int32_t [[V1:[^ ]*]]) {
27+
// CPP-DEFAULT: void member(mystruct [[V0:[^ ]*]], int32_t [[V1:[^ ]*]], size_t [[Index:[^ ]*]]) {
1928
// CPP-DEFAULT-NEXT: mystruct [[V2:[^ ]*]];
2029
// CPP-DEFAULT-NEXT: [[V2]] = [[V0]];
2130
// CPP-DEFAULT-NEXT: [[V2]].a = [[V1]];
2231
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]] = [[V2]].b;
2332
// CPP-DEFAULT-NEXT: int32_t [[V4:[^ ]*]];
2433
// CPP-DEFAULT-NEXT: [[V4]] = [[V3]];
34+
// CPP-DEFAULT-NEXT: int32_t [[V5:[^ ]*]] = [[V2]].c[[[Index]]];
35+
// CPP-DEFAULT-NEXT: [[V4]] = [[V5]];
36+
// CPP-DEFAULT-NEXT: [[V2]].d[[[Index]]] = [[V1]];
2537

2638

27-
func.func @member_of_pointer(%arg0: !emitc.ptr<!emitc.opaque<"mystruct">>, %arg1: i32) {
39+
func.func @member_of_pointer(%arg0: !emitc.ptr<!emitc.opaque<"mystruct">>, %arg1: i32, %arg2: index) {
2840
%var0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>
2941
emitc.assign %arg0 : !emitc.ptr<!emitc.opaque<"mystruct">> to %var0 : !emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>
3042

@@ -36,14 +48,25 @@ func.func @member_of_pointer(%arg0: !emitc.ptr<!emitc.opaque<"mystruct">>, %arg1
3648
%3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
3749
emitc.assign %2 : i32 to %3 : !emitc.lvalue<i32>
3850

51+
%4 = "emitc.member_of_ptr" (%var0) {member = "c"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.array<2xi32>
52+
%5 = emitc.subscript %4[%arg2] : (!emitc.array<2xi32>, index) -> !emitc.lvalue<i32>
53+
%6 = emitc.load %5 : <i32>
54+
emitc.assign %6 : i32 to %3 : !emitc.lvalue<i32>
55+
56+
%7 = "emitc.member_of_ptr" (%var0) {member = "d"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.array<2xi32>
57+
%8 = emitc.subscript %7[%arg2] : (!emitc.array<2xi32>, index) -> !emitc.lvalue<i32>
58+
emitc.assign %arg1 : i32 to %8 : !emitc.lvalue<i32>
59+
3960
return
4061
}
4162

42-
// CPP-DEFAULT: void member_of_pointer(mystruct* [[V0:[^ ]*]], int32_t [[V1:[^ ]*]]) {
63+
// CPP-DEFAULT: void member_of_pointer(mystruct* [[V0:[^ ]*]], int32_t [[V1:[^ ]*]], size_t [[Index:[^ ]*]]) {
4364
// CPP-DEFAULT-NEXT: mystruct* [[V2:[^ ]*]];
4465
// CPP-DEFAULT-NEXT: [[V2]] = [[V0]];
4566
// CPP-DEFAULT-NEXT: [[V2]]->a = [[V1]];
4667
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]] = [[V2]]->b;
4768
// CPP-DEFAULT-NEXT: int32_t [[V4:[^ ]*]];
4869
// CPP-DEFAULT-NEXT: [[V4]] = [[V3]];
49-
70+
// CPP-DEFAULT-NEXT: int32_t [[V5:[^ ]*]] = [[V2]]->c[[[Index]]];
71+
// CPP-DEFAULT-NEXT: [[V4]] = [[V5]];
72+
// CPP-DEFAULT-NEXT: [[V2]]->d[[[Index]]] = [[V1]];

0 commit comments

Comments
 (0)