diff --git a/integration_test/circt-synth/comb-lowering-lec.mlir b/integration_test/circt-synth/comb-lowering-lec.mlir index 9db9667c7be9..1b3f0944aac8 100644 --- a/integration_test/circt-synth/comb-lowering-lec.mlir +++ b/integration_test/circt-synth/comb-lowering-lec.mlir @@ -14,6 +14,13 @@ hw.module @bit_logical(in %arg0: i32, in %arg1: i32, in %arg2: i32, in %arg3: i3 hw.output %0, %1, %2, %3 : i32, i32, i32, i32 } +// RUN: circt-lec %t.mlir %s -c1=parity -c2=parity --shared-libs=%libz3 | FileCheck %s --check-prefix=COMB_PARITY +// COMB_PARITY: c1 == c2 +hw.module @parity(in %arg0: i4, out out: i1) { + %0 = comb.parity %arg0 : i4 + hw.output %0 : i1 +} + // RUN: circt-lec %t.mlir %s -c1=add -c2=add --shared-libs=%libz3 | FileCheck %s --check-prefix=COMB_ADD // COMB_ADD: c1 == c2 hw.module @add(in %arg0: i4, in %arg1: i4, in %arg2: i4, out add: i4) { diff --git a/lib/Conversion/CombToAIG/CombToAIG.cpp b/lib/Conversion/CombToAIG/CombToAIG.cpp index f7613baa5aac..986d56ad5018 100644 --- a/lib/Conversion/CombToAIG/CombToAIG.cpp +++ b/lib/Conversion/CombToAIG/CombToAIG.cpp @@ -328,6 +328,19 @@ struct CombMulOpConversion : OpConversionPattern { } }; +struct CombParityOpConversion : OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(ParityOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + // Parity is the XOR of all bits. + rewriter.replaceOpWithNewOp( + op, extractBits(rewriter, adaptor.getInput()), true); + return success(); + } +}; + } // namespace //===----------------------------------------------------------------------===// @@ -347,7 +360,7 @@ static void populateCombToAIGConversionPatterns(RewritePatternSet &patterns) { patterns.add< // Bitwise Logical Ops CombAndOpConversion, CombOrOpConversion, CombXorOpConversion, - CombMuxOpConversion, + CombMuxOpConversion, CombParityOpConversion, // Arithmetic Ops CombAddOpConversion, CombSubOpConversion, CombMulOpConversion, // Variadic ops that must be lowered to binary operations diff --git a/test/Conversion/CombToAIG/comb-to-aig-arith.mlir b/test/Conversion/CombToAIG/comb-to-aig-arith.mlir index 00514f0a3d06..faa1a13db6b0 100644 --- a/test/Conversion/CombToAIG/comb-to-aig-arith.mlir +++ b/test/Conversion/CombToAIG/comb-to-aig-arith.mlir @@ -2,6 +2,18 @@ // RUN: circt-opt %s --pass-pipeline="builtin.module(hw.module(convert-comb-to-aig{additional-legal-ops=comb.xor,comb.or,comb.and,comb.mux,comb.add}))" | FileCheck %s --check-prefix=ALLOW_ADD +// CHECK-LABEL: @parity +hw.module @parity(in %arg0: i4, out out: i1) { + // CHECK-NEXT: %[[ext0:.+]] = comb.extract %arg0 from 0 : (i4) -> i1 + // CHECK-NEXT: %[[ext1:.+]] = comb.extract %arg0 from 1 : (i4) -> i1 + // CHECK-NEXT: %[[ext2:.+]] = comb.extract %arg0 from 2 : (i4) -> i1 + // CHECK-NEXT: %[[ext3:.+]] = comb.extract %arg0 from 3 : (i4) -> i1 + // CHECK-NEXT: %[[xor:.+]] = comb.xor bin %[[ext0]], %[[ext1]], %[[ext2]], %[[ext3]] : i1 + // CHECK-NEXT: hw.output %[[xor]] : i1 + %0 = comb.parity %arg0 : i4 + hw.output %0 : i1 +} + // CHECK-LABEL: @add hw.module @add(in %lhs: i2, in %rhs: i2, out out: i2) { // CHECK: %[[lhs0:.*]] = comb.extract %lhs from 0 : (i2) -> i1