Skip to content

Commit 4e1d2d9

Browse files
jacquesguangithub-actions[bot]
authored andcommitted
Automerge: [mlir][emitc] Add increment and decrement ops (#208648)
2 parents 258e63e + 31b3a0a commit 4e1d2d9

5 files changed

Lines changed: 182 additions & 1 deletion

File tree

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

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,29 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
6565
}];
6666
}
6767

68+
// Base class for increment and decrement operations.
69+
class EmitC_IncDecOp<string mnemonic, string summaryStr>
70+
: EmitC_Op<mnemonic, [
71+
CExpressionInterface,
72+
TypesMatchWith<"input and result reference the same type",
73+
"operand", "result",
74+
"::llvm::cast<emitc::LValueType>($_self).getValueType()">
75+
]> {
76+
let summary = summaryStr;
77+
let arguments = (ins
78+
Res<EmitC_LValueType, "",
79+
[MemRead<DefaultResource, 0, FullEffect>,
80+
MemWrite<DefaultResource, 0, FullEffect>]>:$operand);
81+
let results = (outs EmitCType:$result);
82+
let assemblyFormat = "$operand attr-dict `:` type($operand)";
83+
84+
let extraClassDeclaration = [{
85+
bool hasSideEffects() {
86+
return true;
87+
}
88+
}];
89+
}
90+
6891
// Types only used in binary arithmetic operations.
6992
def IntegerIndexOrOpaqueType : Type<CPred<"emitc::isIntegerIndexOrOpaqueType($_self)">,
7093
"integer, index or opaque type supported by EmitC">;
@@ -1259,6 +1282,58 @@ def EmitC_ConditionalOp : EmitC_Op<"conditional",
12591282
}];
12601283
}
12611284

1285+
def EmitC_PreIncrementOp
1286+
: EmitC_IncDecOp<"pre_increment", "Pre-increment operation"> {
1287+
let description = [{
1288+
This operation models the C/C++ pre-increment operator on an lvalue.
1289+
1290+
Example:
1291+
1292+
```mlir
1293+
%0 = emitc.pre_increment %arg0 : !emitc.lvalue<i32>
1294+
```
1295+
}];
1296+
}
1297+
1298+
def EmitC_PostIncrementOp
1299+
: EmitC_IncDecOp<"post_increment", "Post-increment operation"> {
1300+
let description = [{
1301+
This operation models the C/C++ post-increment operator on an lvalue.
1302+
1303+
Example:
1304+
1305+
```mlir
1306+
%0 = emitc.post_increment %arg0 : !emitc.lvalue<i32>
1307+
```
1308+
}];
1309+
}
1310+
1311+
def EmitC_PreDecrementOp
1312+
: EmitC_IncDecOp<"pre_decrement", "Pre-decrement operation"> {
1313+
let description = [{
1314+
This operation models the C/C++ pre-decrement operator on an lvalue.
1315+
1316+
Example:
1317+
1318+
```mlir
1319+
%0 = emitc.pre_decrement %arg0 : !emitc.lvalue<i32>
1320+
```
1321+
}];
1322+
}
1323+
1324+
def EmitC_PostDecrementOp
1325+
: EmitC_IncDecOp<"post_decrement", "Post-decrement operation"> {
1326+
let description = [{
1327+
This operation models the C/C++ post-decrement operator on an lvalue.
1328+
1329+
Example:
1330+
1331+
```mlir
1332+
%0 = emitc.post_decrement %arg0 : !emitc.lvalue<i32>
1333+
```
1334+
}];
1335+
}
1336+
12621337
def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", []> {
12631338
let summary = "Unary minus operation";
12641339
let description = [{

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ static FailureOr<int> getOperatorPrecedence(Operation *operation) {
112112
.Case([&](emitc::MemberOfPtrOp op) { return 17; })
113113
.Case([&](emitc::MemberOp op) { return 17; })
114114
.Case([&](emitc::MulOp op) { return 13; })
115+
.Case([&](emitc::PostDecrementOp op) { return 16; })
116+
.Case([&](emitc::PostIncrementOp op) { return 16; })
117+
.Case([&](emitc::PreDecrementOp op) { return 15; })
118+
.Case([&](emitc::PreIncrementOp op) { return 15; })
115119
.Case([&](emitc::RemOp op) { return 13; })
116120
.Case([&](emitc::SubOp op) { return 12; })
117121
.Case([&](emitc::SubscriptOp op) { return 17; })
@@ -646,6 +650,22 @@ static LogicalResult printUnaryOperation(CppEmitter &emitter,
646650
return success();
647651
}
648652

653+
static LogicalResult printPostfixUnaryOperation(CppEmitter &emitter,
654+
Operation *operation,
655+
StringRef unaryOperator) {
656+
raw_ostream &os = emitter.ostream();
657+
658+
if (failed(emitter.emitAssignPrefix(*operation)))
659+
return failure();
660+
661+
if (failed(emitter.emitOperand(operation->getOperand(0))))
662+
return failure();
663+
664+
os << unaryOperator;
665+
666+
return success();
667+
}
668+
649669
static LogicalResult printOperation(CppEmitter &emitter, emitc::AddOp addOp) {
650670
Operation *operation = addOp.getOperation();
651671

@@ -1038,6 +1058,30 @@ static LogicalResult printOperation(CppEmitter &emitter,
10381058
return printBinaryOperation(emitter, operation, "^");
10391059
}
10401060

1061+
static LogicalResult printOperation(CppEmitter &emitter,
1062+
emitc::PreIncrementOp preIncrementOp) {
1063+
Operation *operation = preIncrementOp.getOperation();
1064+
return printUnaryOperation(emitter, operation, "++");
1065+
}
1066+
1067+
static LogicalResult printOperation(CppEmitter &emitter,
1068+
emitc::PostIncrementOp postIncrementOp) {
1069+
Operation *operation = postIncrementOp.getOperation();
1070+
return printPostfixUnaryOperation(emitter, operation, "++");
1071+
}
1072+
1073+
static LogicalResult printOperation(CppEmitter &emitter,
1074+
emitc::PreDecrementOp preDecrementOp) {
1075+
Operation *operation = preDecrementOp.getOperation();
1076+
return printUnaryOperation(emitter, operation, "--");
1077+
}
1078+
1079+
static LogicalResult printOperation(CppEmitter &emitter,
1080+
emitc::PostDecrementOp postDecrementOp) {
1081+
Operation *operation = postDecrementOp.getOperation();
1082+
return printPostfixUnaryOperation(emitter, operation, "--");
1083+
}
1084+
10411085
static LogicalResult printOperation(CppEmitter &emitter,
10421086
emitc::UnaryPlusOp unaryPlusOp) {
10431087
Operation *operation = unaryPlusOp.getOperation();
@@ -1896,7 +1940,9 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
18961940
emitc::IncludeOp, emitc::LiteralOp, emitc::LoadOp,
18971941
emitc::LogicalAndOp, emitc::LogicalNotOp, emitc::LogicalOrOp,
18981942
emitc::MemberCallOpaqueOp, emitc::MemberOfPtrOp,
1899-
emitc::MemberOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
1943+
emitc::MemberOp, emitc::MulOp, emitc::PostDecrementOp,
1944+
emitc::PostIncrementOp, emitc::PreDecrementOp,
1945+
emitc::PreIncrementOp, emitc::RemOp, emitc::ReturnOp,
19001946
emitc::SubscriptOp, emitc::SubOp, emitc::SwitchOp,
19011947
emitc::UnaryMinusOp, emitc::UnaryPlusOp, emitc::VariableOp,
19021948
emitc::VerbatimOp>(

mlir/test/Dialect/EmitC/invalid_ops.mlir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,3 +981,19 @@ func.func @dereference(%arg0: !emitc.ptr<i32>) {
981981
%1 = "emitc.dereference"(%arg0) : (!emitc.ptr<i32>) -> !emitc.lvalue<i8>
982982
return
983983
}
984+
985+
// -----
986+
987+
func.func @pre_increment_unmatch_type(%arg0: !emitc.lvalue<i32>) {
988+
// expected-error @+1 {{failed to verify that input and result reference the same type}}
989+
%1 = "emitc.pre_increment"(%arg0) : (!emitc.lvalue<i32>) -> i8
990+
return
991+
}
992+
993+
// -----
994+
995+
func.func @post_decrement_unmatch_type(%arg0: !emitc.lvalue<i32>) {
996+
// expected-error @+1 {{failed to verify that input and result reference the same type}}
997+
%1 = "emitc.post_decrement"(%arg0) : (!emitc.lvalue<i32>) -> i8
998+
return
999+
}

mlir/test/Dialect/EmitC/ops.mlir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ func.func @unary(%arg0: i32) {
148148
return
149149
}
150150

151+
func.func @inc_dec(%arg0: !emitc.ptr<i32>) {
152+
%v = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue<i32>
153+
%0 = emitc.pre_increment %v : !emitc.lvalue<i32>
154+
%1 = emitc.post_increment %v : !emitc.lvalue<i32>
155+
%2 = emitc.pre_decrement %v : !emitc.lvalue<i32>
156+
%3 = emitc.post_decrement %v : !emitc.lvalue<i32>
157+
return
158+
}
159+
151160
func.func @test_if(%arg0: i1, %arg1: f32) {
152161
emitc.if %arg0 {
153162
%0 = emitc.call_opaque "func_const"(%arg1) : (f32) -> i32

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,41 @@ func.func @dereference(%arg0: !emitc.ptr<i32>) {
107107
return
108108
}
109109

110+
// CHECK-LABEL: void inc_dec() {
111+
func.func @inc_dec() {
112+
// CHECK-NEXT: int32_t [[V1:[^ ]*]] = 0;
113+
%v = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue<i32>
114+
// CHECK-NEXT: int32_t [[V2:[^ ]*]] = ++[[V1]];
115+
%0 = emitc.pre_increment %v : !emitc.lvalue<i32>
116+
// CHECK-NEXT: int32_t [[V3:[^ ]*]] = [[V1]]++;
117+
%1 = emitc.post_increment %v : !emitc.lvalue<i32>
118+
// CHECK-NEXT: int32_t [[V4:[^ ]*]] = --[[V1]];
119+
%2 = emitc.pre_decrement %v : !emitc.lvalue<i32>
120+
// CHECK-NEXT: int32_t [[V5:[^ ]*]] = [[V1]]--;
121+
%3 = emitc.post_decrement %v : !emitc.lvalue<i32>
122+
return
123+
}
124+
125+
// CHECK-LABEL: int32_t inc_dec_expression() {
126+
func.func @inc_dec_expression() -> i32 {
127+
// CHECK-NEXT: int32_t [[V1:[^ ]*]] = 0;
128+
%v = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue<i32>
129+
%inc = emitc.expression %v : (!emitc.lvalue<i32>) -> i32 {
130+
%0 = emitc.post_increment %v : !emitc.lvalue<i32>
131+
emitc.yield %0 : i32
132+
}
133+
// CHECK-NEXT: int32_t [[V2:[^ ]*]] = [[V1]]++;
134+
%dec = emitc.expression %v : (!emitc.lvalue<i32>) -> i32 {
135+
%0 = emitc.post_decrement %v : !emitc.lvalue<i32>
136+
emitc.yield %0 : i32
137+
}
138+
// CHECK-NEXT: int32_t [[V3:[^ ]*]] = [[V1]]--;
139+
%r = emitc.add %inc, %dec : (i32, i32) -> i32
140+
// CHECK-NEXT: int32_t [[V4:[^ ]*]] = [[V2]] + [[V3]];
141+
// CHECK-NEXT: return [[V4]];
142+
return %r : i32
143+
}
144+
110145
// CHECK: void array_type(int32_t v1[3], float v2[10][20])
111146
func.func @array_type(%arg0: !emitc.array<3xi32>, %arg1: !emitc.array<10x20xf32>) {
112147
return

0 commit comments

Comments
 (0)