[Comb] Enable cross-block folds on and/or/xor (#8607)

Now that #8517 has landed, re-enable the canonicalizers and constant
folders for `comb.and`, `comb.or`, and `comb.xor` that have operands
defined in different blocks.
This commit is contained in:
Fabian Schuiki 2025-06-26 13:29:02 -07:00 committed by GitHub
parent 4c6030fd74
commit e1fc1023d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 4 additions and 24 deletions

View File

@ -824,9 +824,6 @@ static bool canCombineOppositeBinCmpIntoConstant(OperandRange operands) {
}
OpFoldResult AndOp::fold(FoldAdaptor adaptor) {
if (hasOperandsOutsideOfBlock(getOperation()))
return {};
APInt value = APInt::getAllOnes(cast<IntegerType>(getType()).getWidth());
auto inputs = adaptor.getInputs();
@ -977,8 +974,6 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
if (size > 1 && canonicalizeIdempotentInputs(op, rewriter))
return success();
if (hasOperandsOutsideOfBlock(&*op))
return failure();
assert(size > 1 && "expected 2 or more operands, `fold` should handle this");
// Patterns for and with a constant on RHS.
@ -1101,9 +1096,6 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
}
OpFoldResult OrOp::fold(FoldAdaptor adaptor) {
if (hasOperandsOutsideOfBlock(getOperation()))
return {};
auto value = APInt::getZero(cast<IntegerType>(getType()).getWidth());
auto inputs = adaptor.getInputs();
// or(x, 10, 01) -> 11
@ -1163,8 +1155,6 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
if (size > 1 && canonicalizeIdempotentInputs(op, rewriter))
return success();
if (hasOperandsOutsideOfBlock(&*op))
return failure();
assert(size > 1 && "expected 2 or more operands");
// Patterns for and with a constant on RHS.
@ -1243,9 +1233,6 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
}
OpFoldResult XorOp::fold(FoldAdaptor adaptor) {
if (hasOperandsOutsideOfBlock(getOperation()))
return {};
auto size = getInputs().size();
auto inputs = adaptor.getInputs();
@ -1298,9 +1285,6 @@ static void canonicalizeXorIcmpTrue(XorOp op, unsigned icmpOperand,
}
LogicalResult XorOp::canonicalize(XorOp op, PatternRewriter &rewriter) {
if (hasOperandsOutsideOfBlock(&*op))
return failure();
auto inputs = op.getInputs();
auto size = inputs.size();
assert(size > 1 && "expected 2 or more operands");

View File

@ -12,8 +12,7 @@ calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%don
// CHECK: calyx.assign %eq_reg.write_en = %true : i1
// CHECK: calyx.assign %eq.left = %true : i1
// CHECK: calyx.assign %eq.right = %true : i1
// CHECK: %0 = comb.and %eq_reg.done : i1
// CHECK: calyx.group_done %0 ? %true : i1
// CHECK: calyx.group_done %eq_reg.done ? %true : i1
calyx.comb_group @Cond {
calyx.assign %eq.left = %c1_1 : i1
calyx.assign %eq.right = %c1_1 : i1
@ -60,8 +59,7 @@ calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%don
// CHECK: calyx.assign %eq_reg.write_en = %true : i1
// CHECK: calyx.assign %eq.left = %true : i1
// CHECK: calyx.assign %eq.right = %true : i1
// CHECK: %0 = comb.and %eq_reg.done : i1
// CHECK: calyx.group_done %0 ? %true : i1
// CHECK: calyx.group_done %eq_reg.done ? %true : i1
// CHECK: }
calyx.comb_group @Cond1 {
calyx.assign %eq.left = %c1_1 : i1
@ -74,8 +72,7 @@ calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%don
// CHECK: calyx.assign %eq_reg.write_en = %true : i1
// CHECK: calyx.assign %eq.left = %true : i1
// CHECK: calyx.assign %eq.right = %true : i1
// CHECK: %0 = comb.and %eq_reg.done : i1
// CHECK: calyx.group_done %0 ? %true : i1
// CHECK: calyx.group_done %eq_reg.done ? %true : i1
// CHECK: }
calyx.comb_group @Cond2 {
calyx.assign %eq.left = %c1_1 : i1

View File

@ -114,8 +114,7 @@ hw.module.generated @FIRRTLMem_1_1_1_16_10_0_1_0_0, @FIRRTLMem(in %ro_addr_0: i4
//CHECK-NEXT: }
//CHECK-NEXT: %true_1 = hw.constant true
//CHECK-NEXT: sv.always posedge %wo_clock_0 {
//CHECK-NEXT: %[[WO_EN:.+]] = comb.and %wo_en_0, %true_1 : i1
//CHECK-NEXT: sv.if %[[WO_EN]] {
//CHECK-NEXT: sv.if %wo_en_0 {
//CHECK-NEXT: %[[wslot:.+]] = sv.array_index_inout %Memory[%wo_addr_0]
//CHECK-NEXT: %[[c0_i32:.+]] = hw.constant 0 : i32
//CHECK-NEXT: sv.passign %[[wslot]], %wo_data_0