Skip to content

Commit f760caa

Browse files
marbremgehre-amd
authored andcommitted
[mlir][EmitC] Add logical operators (llvm#83123)
This adds operations for the logical operators AND, NOT and OR.
1 parent 65d0767 commit f760caa

File tree

5 files changed

+138
-1
lines changed

5 files changed

+138
-1
lines changed

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,70 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
658658
let assemblyFormat = "$value attr-dict `:` type($result)";
659659
}
660660

661+
def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", []> {
662+
let summary = "Logical and operation";
663+
let description = [{
664+
With the `logical_and` operation the logical operator && (and) can
665+
be applied.
666+
667+
Example:
668+
669+
```mlir
670+
%0 = emitc.logical_and %arg0, %arg1 : i32, i32
671+
```
672+
```c++
673+
// Code emitted for the operation above.
674+
bool v3 = v1 && v2;
675+
```
676+
}];
677+
678+
let results = (outs I1);
679+
let assemblyFormat = "operands attr-dict `:` type(operands)";
680+
}
681+
682+
def EmitC_LogicalNotOp : EmitC_Op<"logical_not", []> {
683+
let summary = "Logical not operation";
684+
let description = [{
685+
With the `logical_not` operation the logical operator ! (negation) can
686+
be applied.
687+
688+
Example:
689+
690+
```mlir
691+
%0 = emitc.logical_not %arg0 : i32
692+
```
693+
```c++
694+
// Code emitted for the operation above.
695+
bool v2 = !v1;
696+
```
697+
}];
698+
699+
let arguments = (ins AnyType);
700+
let results = (outs I1);
701+
let assemblyFormat = "operands attr-dict `:` type(operands)";
702+
}
703+
704+
def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", []> {
705+
let summary = "Logical or operation";
706+
let description = [{
707+
With the `logical_or` operation the logical operator || (inclusive or)
708+
can be applied.
709+
710+
Example:
711+
712+
```mlir
713+
%0 = emitc.logical_or %arg0, %arg1 : i32, i32
714+
```
715+
```c++
716+
// Code emitted for the operation above.
717+
bool v3 = v1 || v2;
718+
```
719+
}];
720+
721+
let results = (outs I1);
722+
let assemblyFormat = "operands attr-dict `:` type(operands)";
723+
}
724+
661725
def EmitC_MulOp : EmitC_BinaryOp<"mul", []> {
662726
let summary = "Multiplication operation";
663727
let description = [{

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,33 @@ static LogicalResult printOperation(CppEmitter &emitter,
640640
return success();
641641
}
642642

643+
static LogicalResult printOperation(CppEmitter &emitter,
644+
emitc::LogicalAndOp logicalAndOp) {
645+
Operation *operation = logicalAndOp.getOperation();
646+
return printBinaryOperation(emitter, operation, "&&");
647+
}
648+
649+
static LogicalResult printOperation(CppEmitter &emitter,
650+
emitc::LogicalNotOp logicalNotOp) {
651+
raw_ostream &os = emitter.ostream();
652+
653+
if (failed(emitter.emitAssignPrefix(*logicalNotOp.getOperation())))
654+
return failure();
655+
656+
os << "!";
657+
658+
if (failed(emitter.emitOperand(logicalNotOp.getOperand())))
659+
return failure();
660+
661+
return success();
662+
}
663+
664+
static LogicalResult printOperation(CppEmitter &emitter,
665+
emitc::LogicalOrOp logicalOrOp) {
666+
Operation *operation = logicalOrOp.getOperation();
667+
return printBinaryOperation(emitter, operation, "||");
668+
}
669+
643670
static LogicalResult printOperation(CppEmitter &emitter, emitc::ForOp forOp) {
644671

645672
raw_indented_ostream &os = emitter.ostream();
@@ -1318,7 +1345,8 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
13181345
emitc::CallOpaqueOp, emitc::CastOp, emitc::CmpOp,
13191346
emitc::ConstantOp, emitc::DeclareFuncOp, emitc::DivOp,
13201347
emitc::ExpressionOp, emitc::ForOp, emitc::FuncOp, emitc::IfOp,
1321-
emitc::IncludeOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
1348+
emitc::IncludeOp, emitc::LogicalAndOp, emitc::LogicalNotOp,
1349+
emitc::LogicalOrOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
13221350
emitc::SubOp, emitc::SubscriptOp, emitc::VariableOp,
13231351
emitc::VerbatimOp>(
13241352
[&](auto op) { return printOperation(*this, op); })

mlir/test/Dialect/EmitC/invalid_ops.mlir

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,27 @@ emitc.declare_func @bar
339339

340340
// expected-error@+1 {{'emitc.declare_func' op requires attribute 'sym_name'}}
341341
"emitc.declare_func"() : () -> ()
342+
343+
// -----
344+
345+
func.func @logical_and_resulterror(%arg0: i32, %arg1: i32) {
346+
// expected-error @+1 {{'emitc.logical_and' op result #0 must be 1-bit signless integer, but got 'i32'}}
347+
%0 = "emitc.logical_and"(%arg0, %arg1) : (i32, i32) -> i32
348+
return
349+
}
350+
351+
// -----
352+
353+
func.func @logical_not_resulterror(%arg0: i32) {
354+
// expected-error @+1 {{'emitc.logical_not' op result #0 must be 1-bit signless integer, but got 'i32'}}
355+
%0 = "emitc.logical_not"(%arg0) : (i32) -> i32
356+
return
357+
}
358+
359+
// -----
360+
361+
func.func @logical_or_resulterror(%arg0: i32, %arg1: i32) {
362+
// expected-error @+1 {{'emitc.logical_or' op result #0 must be 1-bit signless integer, but got 'i32'}}
363+
%0 = "emitc.logical_or"(%arg0, %arg1) : (i32, i32) -> i32
364+
return
365+
}

mlir/test/Dialect/EmitC/ops.mlir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ func.func @cmp(%arg0 : i32, %arg1 : f32, %arg2 : i64, %arg3 : f64, %arg4 : !emit
117117
return
118118
}
119119

120+
func.func @logical(%arg0: i32, %arg1: i32) {
121+
%0 = emitc.logical_and %arg0, %arg1 : i32, i32
122+
%1 = emitc.logical_not %arg0 : i32
123+
%2 = emitc.logical_or %arg0, %arg1 : i32, i32
124+
return
125+
}
126+
120127
func.func @test_if(%arg0: i1, %arg1: f32) {
121128
emitc.if %arg0 {
122129
%0 = emitc.call_opaque "func_const"(%arg1) : (f32) -> i32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s
2+
3+
func.func @logical(%arg0: i32, %arg1: i32) -> () {
4+
%0 = emitc.logical_and %arg0, %arg1 : i32, i32
5+
%1 = emitc.logical_not %arg0 : i32
6+
%2 = emitc.logical_or %arg0, %arg1 : i32, i32
7+
8+
return
9+
}
10+
11+
// CHECK-LABEL: void logical
12+
// CHECK-NEXT: bool [[V2:[^ ]*]] = [[V0:[^ ]*]] && [[V1:[^ ]*]];
13+
// CHECK-NEXT: bool [[V3:[^ ]*]] = ![[V0]];
14+
// CHECK-NEXT: bool [[V4:[^ ]*]] = [[V0]] || [[V1]];

0 commit comments

Comments
 (0)