Skip to content

Commit 5f41378

Browse files
author
Simon Camphausen
committed
Disallow lvalue as argument types
1 parent a15dd75 commit 5f41378

File tree

8 files changed

+79
-36
lines changed

8 files changed

+79
-36
lines changed

mlir/lib/Dialect/EmitC/IR/EmitC.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,10 @@ void FuncOp::print(OpAsmPrinter &p) {
548548
}
549549

550550
LogicalResult FuncOp::verify() {
551+
if (llvm::any_of(getArgumentTypes(), llvm::IsaPred<LValueType>)) {
552+
return emitOpError("cannot have lvalue type as argument");
553+
}
554+
551555
if (getNumResults() > 1)
552556
return emitOpError("requires zero or exactly one result, but has ")
553557
<< getNumResults();

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,11 @@ static LogicalResult printOperation(CppEmitter &emitter,
10641064
"with multiple blocks needs variables declared at top");
10651065
}
10661066

1067+
if (llvm::any_of(functionOp.getArgumentTypes(), llvm::IsaPred<LValueType>)) {
1068+
return functionOp.emitOpError()
1069+
<< "cannot emit lvalue type as argument type";
1070+
}
1071+
10671072
if (llvm::any_of(functionOp.getResultTypes(), llvm::IsaPred<ArrayType>)) {
10681073
return functionOp.emitOpError() << "cannot emit array type as result type";
10691074
}

mlir/test/Dialect/EmitC/invalid_ops.mlir

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,19 @@ func.func @array_result() {
8888

8989
// -----
9090

91-
func.func @empty_operator(%arg : !emitc.lvalue<i32>) {
91+
func.func @empty_operator() {
92+
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
9293
// expected-error @+1 {{'emitc.apply' op applicable operator must not be empty}}
93-
%2 = emitc.apply ""(%arg) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
94+
%1 = emitc.apply ""(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
9495
return
9596
}
9697

9798
// -----
9899

99-
func.func @illegal_operator(%arg : !emitc.lvalue<i32>) {
100+
func.func @illegal_operator() {
101+
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
100102
// expected-error @+1 {{'emitc.apply' op applicable operator is illegal}}
101-
%2 = emitc.apply "+"(%arg) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
103+
%1 = emitc.apply "+"(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
102104
return
103105
}
104106

@@ -225,10 +227,13 @@ func.func @test_misplaced_yield() {
225227

226228
// -----
227229

228-
func.func @test_assign_to_non_variable(%arg1: f32, %arg2: !emitc.lvalue<f32>) {
230+
func.func @test_assign_to_block_argument(%arg0: f32) {
231+
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<f32>
232+
cf.br ^bb1(%0 : !emitc.lvalue<f32>)
233+
^bb1(%a : !emitc.lvalue<f32>):
229234
// expected-error @+1 {{'emitc.assign' op cannot assign to block argument}}
230-
emitc.assign %arg1 : f32 to %arg2 : !emitc.lvalue<f32>
231-
return
235+
emitc.assign %arg0 : f32 to %a : !emitc.lvalue<f32>
236+
func.return
232237
}
233238

234239
// -----
@@ -330,6 +335,13 @@ emitc.func @return_type_mismatch() -> i32 {
330335

331336
// -----
332337

338+
// expected-error@+1 {{'emitc.func' op cannot have lvalue type as argument}}
339+
emitc.func @argument_type_lvalue(%arg : !emitc.lvalue<i32>) {
340+
emitc.return
341+
}
342+
343+
// -----
344+
333345
// expected-error@+1 {{'emitc.func' op cannot return array type}}
334346
emitc.func @return_type_array(%arg : !emitc.array<4xi32>) -> !emitc.array<4xi32> {
335347
emitc.return %arg : !emitc.array<4xi32>

mlir/test/Dialect/EmitC/ops.mlir

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ func.func @c() {
4747
return
4848
}
4949

50-
func.func @a(%arg0: !emitc.lvalue<i32>, %arg1: !emitc.lvalue<i32>) {
51-
%1 = "emitc.apply"(%arg0) {applicableOperator = "&"} : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
52-
%2 = emitc.apply "&"(%arg1) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
50+
func.func @a() {
51+
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
52+
%1 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
53+
%2 = "emitc.apply"(%0) {applicableOperator = "&"} : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
54+
%3 = emitc.apply "&"(%1) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
5355
return
5456
}
5557

mlir/test/Dialect/EmitC/transforms.mlir

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ func.func @expression_with_dereference(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr
8585

8686

8787
// CHECK-LABEL: func.func @expression_with_address_taken(
88-
// CHECK-SAME: %[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: !emitc.ptr<i32>, %[[VAL_3:.*]]: !emitc.lvalue<i32>) -> i1 {
88+
// CHECK-SAME: %[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: !emitc.ptr<i32>) -> i1 {
89+
// CHECK: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
8990
// CHECK: %[[VAL_4:.*]] = emitc.expression : i1 {
9091
// CHECK: %[[VAL_5:.*]] = emitc.apply "&"(%[[VAL_3]]) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
9192
// CHECK: %[[VAL_6:.*]] = emitc.add %[[VAL_5]], %[[VAL_1]] : (!emitc.ptr<i32>, i32) -> !emitc.ptr<i32>
@@ -95,8 +96,9 @@ func.func @expression_with_dereference(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr
9596
// CHECK: return %[[VAL_4]] : i1
9697
// CHECK: }
9798

98-
func.func @expression_with_address_taken(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr<i32>, %arg3: !emitc.lvalue<i32>) -> i1 {
99-
%a = emitc.apply "&"(%arg3) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
99+
func.func @expression_with_address_taken(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr<i32>) -> i1 {
100+
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
101+
%a = emitc.apply "&"(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
100102
%b = emitc.add %a, %arg1 : (!emitc.ptr<i32>, i32) -> !emitc.ptr<i32>
101103
%c = emitc.cmp lt, %b, %arg2 :(!emitc.ptr<i32>, !emitc.ptr<i32>) -> i1
102104
return %c : i1

mlir/test/Target/Cpp/common-cpp.mlir

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,20 @@ func.func @opaque_types(%arg0: !emitc.opaque<"bool">, %arg1: !emitc.opaque<"char
8282
return %2 : !emitc.opaque<"status_t">
8383
}
8484

85-
// CHECK-LABEL: int32_t* apply(
86-
// CHECK-SAME: int32_t [[V1:[^ ]*]]) {
87-
func.func @apply(%arg0: !emitc.lvalue<i32>) -> !emitc.ptr<i32> {
85+
// CHECK-LABEL: int32_t* apply() {
86+
func.func @apply() -> !emitc.ptr<i32> {
87+
// CHECK-NEXT: int32_t [[V1:[^ ]*]];
88+
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
8889
// CHECK-NEXT: int32_t* [[V2:[^ ]*]] = &[[V1]];
89-
%0 = emitc.apply "&"(%arg0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
90+
%1 = emitc.apply "&"(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
9091
// CHECK-NEXT: int32_t [[V3:[^ ]*]];
9192
%2 = "emitc.variable"() {value = #emitc.opaque<"">} : () -> !emitc.lvalue<i32>
9293
// CHECK-NEXT: int32_t [[V4:[^ ]*]] = *[[V2]];
93-
%1 = emitc.apply "*"(%0) : (!emitc.ptr<i32>) -> i32
94+
%3 = emitc.apply "*"(%1) : (!emitc.ptr<i32>) -> i32
9495
// CHECK-NEXT: [[V3]] = [[V4]];
95-
emitc.assign %1 : i32 to %2 : !emitc.lvalue<i32>
96+
emitc.assign %3 : i32 to %2 : !emitc.lvalue<i32>
9697
// CHECK-NEXT: return [[V2]];
97-
return %0 : !emitc.ptr<i32>
98+
return %1 : !emitc.ptr<i32>
9899
}
99100

100101
// CHECK: void array_type(int32_t v1[3], float v2[10][20])

mlir/test/Target/Cpp/invalid.mlir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ func.func @pointer_to_array(%arg0 : !emitc.ptr<!emitc.array<4xf32>>) {
7474

7575
// -----
7676

77+
// expected-error@+1 {{cannot emit lvalue type as argument type}}
78+
func.func @lvalue_as_argument(%arg: !emitc.lvalue<i8>) {
79+
return
80+
}
81+
82+
// -----
83+
7784
// expected-error@+1 {{cannot emit array type as result type}}
7885
func.func @array_as_result(%arg: !emitc.array<4xi8>) -> (!emitc.array<4xi8>) {
7986
return %arg : !emitc.array<4xi8>

mlir/test/Target/Cpp/member.mlir

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

3-
func.func @member(%arg0: !emitc.lvalue<!emitc.opaque<"mystruct">>, %arg1: i32) {
4-
%0 = "emitc.member" (%arg0) {member = "a"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
3+
func.func @member(%arg0: !emitc.opaque<"mystruct">, %arg1: i32) {
4+
%var0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.opaque<"mystruct">>
5+
emitc.assign %arg0 : !emitc.opaque<"mystruct"> to %var0 : !emitc.lvalue<!emitc.opaque<"mystruct">>
6+
7+
%0 = "emitc.member" (%var0) {member = "a"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
58
emitc.assign %arg1 : i32 to %0 : !emitc.lvalue<i32>
69

7-
%1 = "emitc.member" (%arg0) {member = "b"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
10+
%1 = "emitc.member" (%var0) {member = "b"} : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
811
%2 = emitc.load %1 : !emitc.lvalue<i32>
912
%3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
1013
emitc.assign %2 : i32 to %3 : !emitc.lvalue<i32>
@@ -13,17 +16,22 @@ func.func @member(%arg0: !emitc.lvalue<!emitc.opaque<"mystruct">>, %arg1: i32) {
1316
}
1417

1518
// CPP-DEFAULT: void member(mystruct [[V0:[^ ]*]], int32_t [[V1:[^ ]*]]) {
16-
// CPP-DEFAULT-NEXT: [[V0]].a = [[V1]];
17-
// CPP-DEFAULT-NEXT: int32_t [[V2:[^ ]*]] = [[V0]].b;
18-
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]];
19-
// CPP-DEFAULT-NEXT: [[V3]] = [[V2]];
20-
21-
22-
func.func @member_of_pointer(%arg0: !emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>, %arg1: i32) {
23-
%0 = "emitc.member_of_ptr" (%arg0) {member = "a"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.lvalue<i32>
19+
// CPP-DEFAULT-NEXT: mystruct [[V2:[^ ]*]];
20+
// CPP-DEFAULT-NEXT: [[V2]] = [[V0]];
21+
// CPP-DEFAULT-NEXT: [[V2]].a = [[V1]];
22+
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]] = [[V2]].b;
23+
// CPP-DEFAULT-NEXT: int32_t [[V4:[^ ]*]];
24+
// CPP-DEFAULT-NEXT: [[V4]] = [[V3]];
25+
26+
27+
func.func @member_of_pointer(%arg0: !emitc.ptr<!emitc.opaque<"mystruct">>, %arg1: i32) {
28+
%var0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>
29+
emitc.assign %arg0 : !emitc.ptr<!emitc.opaque<"mystruct">> to %var0 : !emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>
30+
31+
%0 = "emitc.member_of_ptr" (%var0) {member = "a"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.lvalue<i32>
2432
emitc.assign %arg1 : i32 to %0 : !emitc.lvalue<i32>
2533

26-
%1 = "emitc.member_of_ptr" (%arg0) {member = "b"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.lvalue<i32>
34+
%1 = "emitc.member_of_ptr" (%var0) {member = "b"} : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>) -> !emitc.lvalue<i32>
2735
%2 = emitc.load %1 : !emitc.lvalue<i32>
2836
%3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
2937
emitc.assign %2 : i32 to %3 : !emitc.lvalue<i32>
@@ -32,8 +40,10 @@ func.func @member_of_pointer(%arg0: !emitc.lvalue<!emitc.ptr<!emitc.opaque<"myst
3240
}
3341

3442
// CPP-DEFAULT: void member_of_pointer(mystruct* [[V0:[^ ]*]], int32_t [[V1:[^ ]*]]) {
35-
// CPP-DEFAULT-NEXT: [[V0]]->a = [[V1]];
36-
// CPP-DEFAULT-NEXT: int32_t [[V2:[^ ]*]] = [[V0]]->b;
37-
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]];
38-
// CPP-DEFAULT-NEXT: [[V3]] = [[V2]];
43+
// CPP-DEFAULT-NEXT: mystruct* [[V2:[^ ]*]];
44+
// CPP-DEFAULT-NEXT: [[V2]] = [[V0]];
45+
// CPP-DEFAULT-NEXT: [[V2]]->a = [[V1]];
46+
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]] = [[V2]]->b;
47+
// CPP-DEFAULT-NEXT: int32_t [[V4:[^ ]*]];
48+
// CPP-DEFAULT-NEXT: [[V4]] = [[V3]];
3949

0 commit comments

Comments
 (0)