[Moore] Add `moore.uarray_cmp` op (#8416)

Add a new op to handle the comparison of unpacked arrays.
This commit is contained in:
Annu Singh 2025-04-23 01:28:32 +05:30 committed by GitHub
parent 539bba931f
commit 0f6c244214
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 73 additions and 3 deletions

View File

@ -614,6 +614,15 @@ def SExtOp : ExtOpBase<"sext"> {
// Expressions
//===----------------------------------------------------------------------===//
def UArrayCmpPredicateAttr : I64EnumAttr<
"UArrayCmpPredicate", "",
[
I64EnumAttrCase<"eq", 0>,
I64EnumAttrCase<"ne", 1>
]> {
let cppNamespace = "circt::moore";
}
def NegOp : MooreOp<"neg", [Pure, SameOperandsAndResultType]> {
let summary = "Arithmetic negation";
let description = [{
@ -889,6 +898,34 @@ def ShlOp : ShiftOpBase<"shl"> { let summary = "Logical left shift"; }
def ShrOp : ShiftOpBase<"shr"> { let summary = "Logical right shift"; }
def AShrOp : ShiftOpBase<"ashr"> { let summary = "Arithmetic right shift"; }
def UArrayCmpOp : MooreOp<"uarray_cmp", [
Pure,
Commutative,
SameTypeOperands,
]> {
let description = [{
Performs an elementwise comparison of two unpacked arrays
using the specified predicate (for example, "eq" for equality or "ne" for inequality)
and returns a single bit result.
Its first argument is an attribute that defines which type of comparison is
performed. The following comparisons are supported:
- equal (mnemonic: `"eq"`; integer value: `0`)
- not equal (mnemonic: `"ne"`; integer value: `1`)
The result is `1` if the comparison is true and `0` otherwise.
}];
let arguments = (ins
UArrayCmpPredicateAttr:$predicate,
UnpackedArrayType:$lhs,
UnpackedArrayType:$rhs
);
let results = (outs BitType:$result);
let assemblyFormat = [{
$predicate $lhs `,` $rhs attr-dict `:` type($lhs) `->` type($result)
}];
}
class LogicalEqOpBase<string mnemonic> : MooreOp<mnemonic, [
Pure,
Commutative,

View File

@ -272,7 +272,6 @@ def QueueType : MooreTypeDef<"Queue", [], "moore::UnpackedType"> {
];
}
//===----------------------------------------------------------------------===//
// Structs
//===----------------------------------------------------------------------===//

View File

@ -290,9 +290,17 @@ struct RvalueExprVisitor {
}
case BinaryOperator::Equality:
return createBinary<moore::EqOp>(lhs, rhs);
if (isa<moore::UnpackedArrayType>(lhs.getType()))
return builder.create<moore::UArrayCmpOp>(
loc, moore::UArrayCmpPredicate::eq, lhs, rhs);
else
return createBinary<moore::EqOp>(lhs, rhs);
case BinaryOperator::Inequality:
return createBinary<moore::NeOp>(lhs, rhs);
if (isa<moore::UnpackedArrayType>(lhs.getType()))
return builder.create<moore::UArrayCmpOp>(
loc, moore::UArrayCmpPredicate::ne, lhs, rhs);
else
return createBinary<moore::NeOp>(lhs, rhs);
case BinaryOperator::CaseEquality:
return createBinary<moore::CaseEqOp>(lhs, rhs);
case BinaryOperator::CaseInequality:

View File

@ -729,6 +729,10 @@ module Expressions;
bit [1:0][31:0] arrayInt;
// CHECK: %uarrayInt = moore.variable : <uarray<2 x i32>>
bit [31:0] uarrayInt [2];
// CHECK: %arr1 = moore.variable : <uarray<2 x i32>
bit [31:0] arr1 [2];
// CHECK: %arr2 = moore.variable : <uarray<2 x i32>
bit [31:0] arr2 [2];
// CHECK: %m = moore.variable : <l4>
logic [3:0] m;
@ -1147,6 +1151,24 @@ module Expressions;
// CHECK: [[TMP2:%.+]] = moore.read %e
// CHECK: moore.eq [[TMP1]], [[TMP2]] : l32 -> l1
y = d == e;
// CHECK: [[TMP0:%.+]] = moore.constant 43
// CHECK: [[TMP1:%.+]] = moore.constant 9002
// CHECK: moore.array_create [[TMP0]], [[TMP1]] : !moore.i32, !moore.i32 -> uarray<2 x i32>
arr1 = '{43, 9002};
// CHECK: [[TMP0:%.+]] = moore.constant 43
// CHECK: [[TMP1:%.+]] = moore.constant 9002
// CHECK: moore.array_create [[TMP0]], [[TMP1]] : !moore.i32, !moore.i32 -> uarray<2 x i32>
arr2 = '{43, 9002};
// CHECK: [[TMP1:%.+]] = moore.read %arr1
// CHECK: [[TMP2:%.+]] = moore.read %arr2
// CHECK: moore.uarray_cmp eq [[TMP1]], [[TMP2]] : <2 x i32> -> i1
x = arr1 == arr2;
// CHECK: [[TMP3:%.+]] = moore.read %arr1
// CHECK: [[TMP4:%.+]] = moore.read %arr2
// CHECK: moore.uarray_cmp ne [[TMP3]], [[TMP4]] : <2 x i32> -> i1
x = arr1 != arr2;
// CHECK: [[TMP1:%.+]] = moore.read %a
// CHECK: [[TMP2:%.+]] = moore.read %b
// CHECK: moore.ne [[TMP1]], [[TMP2]] : i32 -> i1

View File

@ -214,10 +214,14 @@ moore.module @Expressions(
// CHECK: moore.eq [[A]], [[B]] : i32 -> i1
moore.eq %a, %b : i32 -> i1
// CHECK: moore.uarray_cmp eq [[ARRAY1]], [[ARRAY1]] : <4 x i8> -> i1
moore.uarray_cmp eq %array1, %array1 : <4 x i8> -> i1
// CHECK: moore.ne [[A]], [[B]] : i32 -> i1
moore.ne %a, %b : i32 -> i1
// CHECK: moore.ne [[C]], [[D]] : l32 -> l1
moore.ne %c, %d : l32 -> l1
// CHECK: moore.uarray_cmp ne [[ARRAY1]], [[ARRAY1]] : <4 x i8> -> i1
moore.uarray_cmp ne %array1, %array1 : <4 x i8> -> i1
// CHECK: moore.case_eq [[A]], [[B]] : i32
moore.case_eq %a, %b : i32
// CHECK: moore.case_ne [[A]], [[B]] : i32