Skip to content

Commit 324ab58

Browse files
cmarcelobcardosolopes
authored andcommitted
[CIR] Add cir::UnaryOp operation
For now covering increment/decrement.
1 parent 06bd457 commit 324ab58

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,53 @@ def ScopeOp : CIR_Op<"scope", [DeclareOpInterfaceMethods<RegionBranchOpInterface
547547
];
548548
}
549549

550+
//===----------------------------------------------------------------------===//
551+
// UnaryOp
552+
//===----------------------------------------------------------------------===//
553+
554+
def UnaryOpKind_Inc : I32EnumAttrCase<"Inc", 1, "inc">;
555+
def UnaryOpKind_Dec : I32EnumAttrCase<"Dec", 2, "dec">;
556+
557+
def UnaryOpKind : I32EnumAttr<
558+
"UnaryOpKind",
559+
"unary operation kind",
560+
[UnaryOpKind_Inc,
561+
UnaryOpKind_Dec]> {
562+
let cppNamespace = "::mlir::cir";
563+
}
564+
565+
// FIXME: NoSideEffect won't work when we add overloading.
566+
def UnaryOp : CIR_Op<"unary",
567+
[NoSideEffect,
568+
SameOperandsAndResultType]> {
569+
let summary = "Unary operations";
570+
let description = [{
571+
`cir.unary` performs the unary operation according to
572+
the specified opcode kind: [inc, dec].
573+
574+
Note for inc and dec: the operation corresponds only to the
575+
addition/subtraction, its input is expect to come from a load
576+
and the result to be used by a corresponding store.
577+
578+
It requires one input operand and has one result, both types
579+
should be the same.
580+
581+
```mlir
582+
%7 = cir.unary(inc, %1) : i32 -> i32
583+
%8 = cir.unary(dec, %2) : i32 -> i32
584+
```
585+
}];
586+
587+
let results = (outs AnyType:$result);
588+
let arguments = (ins Arg<UnaryOpKind, "unary op kind">:$kind, Arg<AnyType>:$input);
589+
590+
let assemblyFormat = [{
591+
`(` $kind `,` $input `)` `:` type($input) `,` type($result) attr-dict
592+
}];
593+
594+
let hasVerifier = 1;
595+
}
596+
550597
//===----------------------------------------------------------------------===//
551598
// BinOp
552599
//===----------------------------------------------------------------------===//

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,33 @@ FunctionType CallOp::getCalleeType() {
12741274
return FunctionType::get(getContext(), getOperandTypes(), getResultTypes());
12751275
}
12761276

1277+
//===----------------------------------------------------------------------===//
1278+
// UnaryOp
1279+
//===----------------------------------------------------------------------===//
1280+
1281+
LogicalResult UnaryOp::verify() {
1282+
switch (getKind()) {
1283+
case cir::UnaryOpKind::Inc:
1284+
LLVM_FALLTHROUGH;
1285+
case cir::UnaryOpKind::Dec: {
1286+
// TODO: Consider looking at the memory interface instead of LoadOp/StoreOp.
1287+
auto loadOp = getInput().getDefiningOp<cir::LoadOp>();
1288+
if (!loadOp)
1289+
return emitOpError() << "requires input to be defined by a memory load";
1290+
1291+
for (const auto user : getResult().getUsers()) {
1292+
auto storeOp = dyn_cast<cir::StoreOp>(user);
1293+
if (storeOp && storeOp.getAddr() == loadOp.getAddr())
1294+
return success();
1295+
}
1296+
return emitOpError() << "requires result to be used by a memory store "
1297+
"to the same address as the input memory load";
1298+
}
1299+
}
1300+
1301+
llvm_unreachable("Unknown UnaryOp kind?");
1302+
}
1303+
12771304
//===----------------------------------------------------------------------===//
12781305
// CIR defined traits
12791306
//===----------------------------------------------------------------------===//

clang/test/CIR/IR/invalid.cir

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,26 @@ module {
198198
module {
199199
cir.global "public" internal @v = 3 : i32 // expected-error {{public visibility not allowed with 'internal' linkage}}
200200
}
201+
202+
// -----
203+
204+
cir.func @unary0() {
205+
%0 = cir.alloca i32, cir.ptr <i32>, ["a", cinit] {alignment = 4 : i64}
206+
%1 = cir.cst(2 : i32) : i32
207+
208+
%3 = cir.unary(inc, %1) : i32, i32 // expected-error {{'cir.unary' op requires input to be defined by a memory load}}
209+
cir.store %3, %0 : i32, cir.ptr <i32>
210+
cir.return
211+
}
212+
213+
// -----
214+
215+
cir.func @unary1() {
216+
%0 = cir.alloca i32, cir.ptr <i32>, ["a", cinit] {alignment = 4 : i64}
217+
%1 = cir.cst(2 : i32) : i32
218+
cir.store %1, %0 : i32, cir.ptr <i32>
219+
220+
%2 = cir.load %0 : cir.ptr <i32>, i32
221+
%3 = cir.unary(dec, %2) : i32, i32 // // expected-error {{'cir.unary' op requires result to be used by a memory store to the same address as the input memory load}}
222+
cir.return
223+
}

0 commit comments

Comments
 (0)