[Handshake] Make ControlMergeOp index result AnyType (#4929)

[Handshake] Make ControlMergeOp idx result AnyType

This commit changes the type of ControlMergeOp's second result
(representing the index of the propagated input) from an Index to an
AnyType. A verifier is implemented for the operation that checks that
this result is either an Index or IntegerType of large enough bitwidth
to support indexing the operation's operands. This aligns the
verification logic of this result with the one for the select operand of
MuxOp's, which is semantically similar.

ControlMergeOp's assembly format is changed to also print the type of
the second result, since it is no longer necessarily an Index. If the
result types are not specified explicitly during operation construction,
the second result will default to an Index. Tests are modified to
reflect the change in assembly format.
This commit is contained in:
Lucas Ramirez 2023-04-05 10:33:46 +02:00 committed by GitHub
parent 0e6d33990d
commit 469ba91a54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 132 additions and 108 deletions

View File

@ -400,19 +400,19 @@ def ControlMergeOp : Handshake_Op<"control_merge", [
(nondeterministic) control merge. Any input is propagated to the
first output and the index of the propagated input is sent to the
second output. The number of inputs corresponds to the number of
predecessor blocks. ControlMerge is a control-only
component(i.e., has no data but only bidirectional handshake).
predecessor blocks.
Example:
```
%0, %idx = control_merge %a, %b, %c : i32
%0, %idx = control_merge %a, %b, %c {attributes} : i32, index
```
}];
let arguments = (ins Variadic<AnyType> : $dataOperands);
let results = (outs AnyType : $result, Index : $index);
let hasCanonicalizer = 1;
let results = (outs AnyType : $result, AnyType : $index);
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
let hasCanonicalizer = 1;
}
def BranchOp : Handshake_Op<"br", [

View File

@ -78,6 +78,32 @@ parseSostOperation(OpAsmParser &parser,
return success();
}
/// Verifies whether an indexing value is wide enough to index into a provided
/// number of operands.
static LogicalResult verifyIndexWideEnough(Operation *op, Value indexVal,
uint64_t numOperands) {
auto indexType = indexVal.getType();
unsigned indexWidth;
// Determine the bitwidth of the indexing value
if (auto integerType = indexType.dyn_cast<IntegerType>())
indexWidth = integerType.getWidth();
else if (indexType.isIndex())
indexWidth = IndexType::kInternalStorageBitWidth;
else
return op->emitError("unsupported type for indexing operand: ")
<< indexType;
// Check whether the bitwidth can support the provided number of operands
uint64_t maxNumOperands =
indexWidth >= UINT64_WIDTH ? UINT64_MAX : (uint64_t)1 << indexWidth;
if (numOperands > maxNumOperands)
return op->emitError("bitwidth of indexing operand is ")
<< indexWidth << ", which can index into " << maxNumOperands
<< " operands, but found " << numOperands << " operands";
return success();
}
static bool isControlCheckTypeAndOperand(Type dataType, Value operand) {
// The operation is a control operation if its operand data type is a
// NoneType.
@ -413,25 +439,8 @@ void MuxOp::print(OpAsmPrinter &p) {
}
LogicalResult MuxOp::verify() {
unsigned numDataOperands = static_cast<int>(getDataOperands().size());
auto selectType = getSelectOperand().getType();
unsigned selectBits;
if (auto integerType = selectType.dyn_cast<IntegerType>())
selectBits = integerType.getWidth();
else if (selectType.isIndex())
selectBits = IndexType::kInternalStorageBitWidth;
else
return emitError("unsupported type for select operand: ") << selectType;
double maxDataOperands = std::pow(2, selectBits);
if (numDataOperands > maxDataOperands)
return emitError("select bitwidth was ")
<< selectBits << ", which can mux "
<< static_cast<int64_t>(maxDataOperands) << " operands, but found "
<< numDataOperands << " operands";
return success();
return verifyIndexWideEnough(*this, getSelectOperand(),
getDataOperands().size());
}
std::string handshake::ControlMergeOp::getResultName(unsigned int idx) {
@ -446,7 +455,7 @@ LogicalResult ControlMergeOp::inferReturnTypes(
// ControlMerge must have at least one data operand
if (operands.empty())
return failure();
// Result type is type of any data operand and index type
// Result type is type of any data operand and, by default, an index type
inferredReturnTypes.push_back(operands[0].getType());
inferredReturnTypes.push_back(IndexType::get(context));
return success();
@ -454,17 +463,19 @@ LogicalResult ControlMergeOp::inferReturnTypes(
ParseResult ControlMergeOp::parse(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::UnresolvedOperand, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
SmallVector<Type, 1> resultTypes, dataOperandsTypes;
Type resultType, indexType;
SmallVector<Type> resultTypes, dataOperandsTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (parseSostOperation(parser, allOperands, result, size, type, false))
if (parseSostOperation(parser, allOperands, result, size, resultType, false))
return failure();
// Parse type of index result
if (parser.parseComma() || parser.parseType(indexType))
return failure();
dataOperandsTypes.assign(size, type);
resultTypes.push_back(type);
resultTypes.push_back(IndexType::get(parser.getContext()));
dataOperandsTypes.assign(size, resultType);
resultTypes.push_back(resultType);
resultTypes.push_back(indexType);
result.addTypes(resultTypes);
if (parser.resolveOperands(allOperands, dataOperandsTypes, allOperandLoc,
result.operands))
@ -472,7 +483,20 @@ ParseResult ControlMergeOp::parse(OpAsmParser &parser, OperationState &result) {
return success();
}
void ControlMergeOp::print(OpAsmPrinter &p) { sostPrint(p, false); }
void ControlMergeOp::print(OpAsmPrinter &p) {
sostPrint(p, false);
// Print type of index result
p << ", " << getIndex().getType();
}
LogicalResult ControlMergeOp::verify() {
auto operands = getOperands();
if (operands.empty())
return emitOpError("operation must have at least one operand");
if (operands[0].getType() != getResult().getType())
return emitOpError("type of first result should match type of operands");
return verifyIndexWideEnough(*this, getIndex(), getNumOperands());
}
LogicalResult FuncOp::verify() {
// If this function is external there is nothing to do.

View File

@ -89,7 +89,7 @@
// CHECK: firrtl.module @test_cmerge(in %[[VAL_53:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_54:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_55:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_56:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_57:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_58:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_59:.*]]: !firrtl.clock, in %[[VAL_60:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_61:.*]], %[[VAL_62:.*]], %[[VAL_63:.*]], %[[VAL_64:.*]], %[[VAL_65:.*]], %[[VAL_66:.*]] = firrtl.instance handshake_control_merge0 @handshake_control_merge_out_ui64_2ins_2outs_ctrl(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in clock: !firrtl.clock, in reset: !firrtl.uint<1>)
handshake.func @test_cmerge(%arg0: none, %arg1: none, %arg2: none, ...) -> (none, index, none) {
%0:2 = control_merge %arg0, %arg1 : none
%0:2 = control_merge %arg0, %arg1 : none, index
return %0#0, %0#1, %arg2 : none, index, none
}
@ -111,6 +111,6 @@ handshake.func @test_cmerge(%arg0: none, %arg1: none, %arg2: none, ...) -> (none
// CHECK: %[[RESULT_DATA1:.+]] = firrtl.mux(%[[BITS1]], %[[ARG0_DATA]], %[[RESULT_DATA0]])
// CHECK: firrtl.connect %[[ARG2_DATA]], %[[RESULT_DATA1]]
handshake.func @test_cmerge_data(%arg0: index, %arg1: index, %arg2: none, ...) -> (index, index, none) {
%0:2 = control_merge %arg0, %arg1 : index
%0:2 = control_merge %arg0, %arg1 : index, index
return %0#0, %0#1, %arg2 : index, index, none
}

View File

@ -51,7 +51,7 @@
// CHECK: }
handshake.func @test_cmerge(%arg0: none, %arg1: none, %arg2: none, ...) -> (none, index, none) {
%0:2 = control_merge %arg0, %arg1 : none
%0:2 = control_merge %arg0, %arg1 : none, index
return %0#0, %0#1, %arg2 : none, index, none
}
@ -118,6 +118,6 @@ handshake.func @test_cmerge(%arg0: none, %arg1: none, %arg2: none, ...) -> (none
// CHECK: }
handshake.func @test_cmerge_data(%arg0: index, %arg1: index, %arg2: index) -> (index, index) {
%0:2 = control_merge %arg0, %arg1, %arg2 : index
%0:2 = control_merge %arg0, %arg1, %arg2 : index, index
return %0#0, %0#1 : index, index
}

View File

@ -51,13 +51,13 @@ func.func @sub(%arg0 : i32, %arg1: i32) -> i32 {
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_6]], %[[VAL_3x]] : none
// CHECK: %[[VAL_14:.*]] = merge %[[VAL_8]] : i32
// CHECK: %[[VAL_15:.*]] = merge %[[VAL_10]] : i32
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_18:.*]]:2 = instance @add(%[[VAL_14]], %[[VAL_15]], %[[VAL_16]]) : (i32, i32, none) -> (i32, none)
// CHECK: %[[VAL_19:.*]] = br %[[VAL_16]] : none
// CHECK: %[[VAL_20:.*]] = br %[[VAL_18]]#0 : i32
// CHECK: %[[VAL_21:.*]] = merge %[[VAL_9]] : i32
// CHECK: %[[VAL_22:.*]] = merge %[[VAL_11]] : i32
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = control_merge %[[VAL_13]] : none
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = control_merge %[[VAL_13]] : none, index
// CHECK: %[[VAL_25:.*]]:2 = instance @sub(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]]) : (i32, i32, none) -> (i32, none)
// CHECK: %[[VAL_26:.*]] = br %[[VAL_23]] : none
// CHECK: %[[VAL_27:.*]] = br %[[VAL_25]]#0 : i32

View File

@ -5,7 +5,7 @@
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none
// CHECK: %[[VAL_0x:.*]] = merge %[[VAL_0]] : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0x]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none, index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_2]] {value = 1 : index} : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_2]] {value = 42 : index} : index
// CHECK: %[[VAL_6:.*]] = br %[[VAL_2]] : none
@ -13,20 +13,20 @@
// CHECK: %[[VAL_8:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_14:.*]] = mux %[[VAL_10:.*]] {{\[}}%[[VAL_15:.*]], %[[VAL_7]]] : index, index
// CHECK: %[[VAL_9:.*]] = mux %[[VAL_10]] {{\[}}%[[VAL_11:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_12:.*]], %[[VAL_10]] = control_merge %[[VAL_13:.*]], %[[VAL_6]] : none
// CHECK: %[[VAL_12:.*]], %[[VAL_10]] = control_merge %[[VAL_13:.*]], %[[VAL_6]] : none, index
// CHECK: %[[VAL_16:.*]] = arith.cmpi slt, %[[VAL_14]], %[[VAL_9]] : index
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = cond_br %[[VAL_16]], %[[VAL_14]] : index
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = cond_br %[[VAL_16]], %[[VAL_9]] : index
// CHECK: %[[VAL_19:.*]], %[[VAL_20:.*]] = cond_br %[[VAL_16]], %[[VAL_12]] : none
// CHECK: %[[VAL_24:.*]] = merge %[[VAL_17]] : index
// CHECK: %[[VAL_23:.*]] = merge %[[VAL_21]] : index
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_19]] : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_19]] : none, index
// CHECK: %[[VAL_27:.*]] = constant %[[VAL_25]] {value = 1 : index} : index
// CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_23]], %[[VAL_27]] : index
// CHECK: %[[VAL_11]] = br %[[VAL_24]] : index
// CHECK: %[[VAL_13]] = br %[[VAL_25]] : none
// CHECK: %[[VAL_15]] = br %[[VAL_28]] : index
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = control_merge %[[VAL_20]] : none
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = control_merge %[[VAL_20]] : none, index
// CHECK: return %[[VAL_29]] : none
// CHECK: }
func.func @simple_loop() {
@ -59,15 +59,15 @@ func.func @simple_loop() {
// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = cond_br %[[VAL_3]], %[[VAL_4]] : i64
// CHECK: %[[VAL_7:.*]], %[[VAL_8:.*]] = cond_br %[[VAL_3]], %[[VAL_2x]] : none
// CHECK: %[[VAL_11:.*]] = merge %[[VAL_5]] : i64
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = control_merge %[[VAL_7]] : none
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = control_merge %[[VAL_7]] : none, index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_11]] : i64
// CHECK: %[[VAL_12:.*]] = br %[[VAL_9]] : none
// CHECK: %[[VAL_16:.*]] = merge %[[VAL_6]] : i64
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_8]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_8]] : none, index
// CHECK: %[[VAL_18:.*]] = br %[[VAL_16]] : i64
// CHECK: %[[VAL_17:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_20:.*]] {{\[}}%[[VAL_18]], %[[VAL_13]]] : index, i64
// CHECK: %[[VAL_19:.*]], %[[VAL_20]] = control_merge %[[VAL_17]], %[[VAL_12]] : none
// CHECK: %[[VAL_19:.*]], %[[VAL_20]] = control_merge %[[VAL_17]], %[[VAL_12]] : none, index
// CHECK: return %[[VAL_19]] : none
// CHECK: }
func.func @simpleDiamond(%arg0: i1, %arg1: i64) {

View File

@ -47,13 +47,13 @@ func.func @load_store(%1 : index) {
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_8]], %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = cond_br %[[VAL_8]], %[[VAL_11]] : none
// CHECK: %[[VAL_16:.*]] = merge %[[VAL_12]] : index
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_14]] : none, index
// CHECK: %[[VAL_19:.*]] = join %[[VAL_17]], %[[VAL_3]]#0 : none, none
// CHECK: %[[VAL_20:.*]] = constant %[[VAL_17]] {value = 1 : i32} : i32
// CHECK: %[[VAL_4]], %[[VAL_5]] = store {{\[}}%[[VAL_16]]] %[[VAL_20]], %[[VAL_17]] : index, i32
// CHECK: %[[VAL_21:.*]] = br %[[VAL_19]] : none
// CHECK: %[[VAL_22:.*]] = merge %[[VAL_13]] : index
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = control_merge %[[VAL_15]] : none
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = control_merge %[[VAL_15]] : none, index
// CHECK: %[[VAL_25:.*]] = join %[[VAL_23]], %[[VAL_3]]#1 : none, none
// CHECK: %[[VAL_26:.*]] = constant %[[VAL_23]] {value = 2 : i32} : i32
// CHECK: %[[VAL_6]], %[[VAL_7]] = store {{\[}}%[[VAL_22]]] %[[VAL_26]], %[[VAL_23]] : index, i32
@ -94,7 +94,7 @@ func.func @store_mul_blocks(%arg0 : i1, %arg1 : index) {
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_6]], %[[VAL_10]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = cond_br %[[VAL_6]], %[[VAL_11]] : i32
// CHECK: %[[VAL_16:.*]] = merge %[[VAL_14]] : i32
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_19:.*]] = constant %[[VAL_17]] {value = 1 : i32} : i32
// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_16]], %[[VAL_19]] : i32
// CHECK: %[[VAL_21:.*]] = br %[[VAL_17]] : none

View File

@ -13,11 +13,11 @@
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_3]], %[[VAL_5]] : i64
// CHECK: %[[VAL_8:.*]], %[[VAL_9:.*]] = cond_br %[[VAL_3]], %[[VAL_2x]] : none
// CHECK: %[[VAL_12:.*]] = merge %[[VAL_6]] : i64
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_8]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_8]] : none, index
// CHECK: %[[VAL_14:.*]] = br %[[VAL_12]] : i64
// CHECK: %[[VAL_13:.*]] = br %[[VAL_10]] : none
// CHECK: %[[VAL_17:.*]] = merge %[[VAL_7]] : i64
// CHECK: %[[VAL_15:.*]], %[[VAL_16:.*]] = control_merge %[[VAL_9]] : none
// CHECK: %[[VAL_15:.*]], %[[VAL_16:.*]] = control_merge %[[VAL_9]] : none, index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_17]] : i64
// CHECK: %[[VAL_18:.*]] = br %[[VAL_15]] : none
// CHECK: %[[VAL_22:.*]] = mux %[[VAL_21:.*]] {{\[}}%[[VAL_19]], %[[VAL_14]]] : index, i64
@ -47,13 +47,13 @@ func.func @simpleDiamond(%arg0: i1, %arg1: i64) {
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_4]] : i1
// CHECK: %[[VAL_9:.*]] = buffer [2] fifo %[[VAL_8]] : i1
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none, index
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_8]], %[[VAL_10]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_13]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_13]] : none, index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_17]] : none
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = control_merge %[[VAL_7]] : none
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = control_merge %[[VAL_7]] : none, index
// CHECK: %[[VAL_22:.*]] = br %[[VAL_20]] : none
// CHECK: %[[VAL_23:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_19]], %[[VAL_16]]] : i1, none
// CHECK: %[[VAL_24:.*]] = arith.index_cast %[[VAL_9]] : i1 to index
@ -93,7 +93,7 @@ func.func @nestedDiamond(%arg0: i1) {
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_3]], %[[VAL_5]] : i64
// CHECK: %[[VAL_8:.*]], %[[VAL_9:.*]] = cond_br %[[VAL_3]], %[[VAL_2x]] : none
// CHECK: %[[VAL_12:.*]] = merge %[[VAL_6]] : i64
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_8]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_8]] : none, index
// CHECK: %[[VAL_14:.*]] = br %[[VAL_12]] : i64
// CHECK: %[[VAL_13:.*]] = br %[[VAL_10]] : none
// CHECK: %[[VAL_19:.*]] = mux %[[VAL_18:.*]] {{\[}}%[[VAL_14]], %[[VAL_7]]] : index, i64
@ -123,9 +123,9 @@ func.func @triangle(%arg0: i1, %val0: i64) {
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_4]] : i1
// CHECK: %[[VAL_9:.*]] = buffer [2] fifo %[[VAL_8]] : i1
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none, index
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_8]], %[[VAL_10]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_13]], %[[VAL_16]]] : i1, none
// CHECK: %[[VAL_18:.*]] = constant %[[VAL_17]] {value = true} : i1
@ -162,11 +162,11 @@ func.func @nestedTriangle(%arg0: i1) {
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_4]] : i1
// CHECK: %[[VAL_9:.*]] = buffer [2] fifo %[[VAL_8]] : i1
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none, index
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_8]], %[[VAL_8]] : i1
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = cond_br %[[VAL_8]], %[[VAL_10]] : none
// CHECK: %[[VAL_16:.*]] = merge %[[VAL_12]] : i1
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_14]] : none, index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_16]] : i1
// CHECK: %[[VAL_20:.*]] = br %[[VAL_17]] : none
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_22:.*]] {{\[}}%[[VAL_19]], %[[VAL_13]]] : index, i1
@ -186,9 +186,9 @@ func.func @nestedTriangle(%arg0: i1) {
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = cond_br %[[VAL_28]], %[[VAL_31]] : none
// CHECK: %[[VAL_38:.*]] = merge %[[VAL_34]] : i1
// CHECK: %[[VAL_39:.*]] = buffer [2] fifo %[[VAL_38]] : i1
// CHECK: %[[VAL_40:.*]], %[[VAL_41:.*]] = control_merge %[[VAL_36]] : none
// CHECK: %[[VAL_40:.*]], %[[VAL_41:.*]] = control_merge %[[VAL_36]] : none, index
// CHECK: %[[VAL_42:.*]], %[[VAL_43:.*]] = cond_br %[[VAL_38]], %[[VAL_40]] : none
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = control_merge %[[VAL_42]] : none
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = control_merge %[[VAL_42]] : none, index
// CHECK: %[[VAL_46:.*]] = br %[[VAL_44]] : none
// CHECK: %[[VAL_47:.*]] = mux %[[VAL_39]] {{\[}}%[[VAL_43]], %[[VAL_46]]] : i1, none
// CHECK: %[[VAL_48:.*]] = constant %[[VAL_47]] {value = true} : i1
@ -230,7 +230,7 @@ func.func @multiple_blocks_needed(%arg0: i1) {
// CHECK: %[[VAL_1x:.*]] = merge %[[VAL_1]] : none
// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_7:.*]], %[[VAL_8:.*]] = control_merge %[[VAL_3]], %[[VAL_3]] : none
// CHECK: %[[VAL_7:.*]], %[[VAL_8:.*]] = control_merge %[[VAL_3]], %[[VAL_3]] : none, index
// CHECK: return %[[VAL_7]] : none
// CHECK: }
func.func @sameSuccessor(%cond: i1) {
@ -250,7 +250,7 @@ func.func @sameSuccessor(%cond: i1) {
// CHECK: %[[VAL_4:.*]] = br %[[VAL_2]] : i64
// CHECK: %[[VAL_5:.*]] = br %[[VAL_1x]] : none
// CHECK: %[[VAL_6:.*]] = br %[[VAL_3]] : i64
// CHECK: %[[VAL_7:.*]], %[[VAL_8:.*]] = control_merge %[[VAL_5]] : none
// CHECK: %[[VAL_7:.*]], %[[VAL_8:.*]] = control_merge %[[VAL_5]] : none, index
// CHECK: %[[VAL_9:.*]] = buffer [1] seq %[[VAL_10:.*]] {initValues = [0]} : i1
// CHECK: %[[VAL_11:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_7]], %[[VAL_12:.*]]] : i1, none
// CHECK: %[[VAL_16:.*]] = mux %[[VAL_8]] {{\[}}%[[VAL_6]]] : index, i64
@ -266,13 +266,13 @@ func.func @sameSuccessor(%cond: i1) {
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = cond_br %[[VAL_19]], %[[VAL_11]] : none
// CHECK: %[[VAL_29:.*]] = merge %[[VAL_21]] : i64
// CHECK: %[[VAL_28:.*]] = merge %[[VAL_27]] : i64
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_25]] : none
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_25]] : none, index
// CHECK: %[[VAL_32:.*]] = constant %[[VAL_30]] {value = 1 : i64} : i64
// CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_28]], %[[VAL_32]] : i64
// CHECK: %[[VAL_15]] = br %[[VAL_29]] : i64
// CHECK: %[[VAL_12]] = br %[[VAL_30]] : none
// CHECK: %[[VAL_18]] = br %[[VAL_33]] : i64
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_24]] : none
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_24]] : none, index
// CHECK: return %[[VAL_34]] : none
// CHECK: }
func.func @simple_loop(%arg0: i64) {
@ -301,17 +301,17 @@ func.func @simple_loop(%arg0: i64) {
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_4]] : i1
// CHECK: %[[VAL_9:.*]] = buffer [2] fifo %[[VAL_8]] : i1
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none, index
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_8]], %[[VAL_10]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_13]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_13]] : none, index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_17]] : none
// CHECK: %[[VAL_20:.*]] = merge %[[VAL_5]] : i1
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = control_merge %[[VAL_7]] : none
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = control_merge %[[VAL_7]] : none, index
// CHECK: %[[VAL_23:.*]] = br %[[VAL_20]] : i1
// CHECK: %[[VAL_24:.*]] = br %[[VAL_21]] : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_24]] : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_24]] : none, index
// CHECK: %[[VAL_27:.*]] = buffer [1] seq %[[VAL_28:.*]] {initValues = [0]} : i1
// CHECK: %[[VAL_29:.*]] = mux %[[VAL_27]] {{\[}}%[[VAL_25]], %[[VAL_30:.*]]] : i1, none
// CHECK: %[[VAL_31:.*]] = mux %[[VAL_26]] {{\[}}%[[VAL_23]]] : index, i1
@ -322,7 +322,7 @@ func.func @simple_loop(%arg0: i64) {
// CHECK: %[[VAL_28]] = merge %[[VAL_37]] : i1
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = cond_br %[[VAL_32]], %[[VAL_29]] : none
// CHECK: %[[VAL_40:.*]] = merge %[[VAL_35]] : i1
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = control_merge %[[VAL_39]] : none
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = control_merge %[[VAL_39]] : none, index
// CHECK: %[[VAL_33]] = br %[[VAL_40]] : i1
// CHECK: %[[VAL_30]] = br %[[VAL_41]] : none
// CHECK: %[[VAL_43:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_19]], %[[VAL_16]]] : i1, none
@ -366,17 +366,17 @@ func.func @blockWith3PredsAndLoop(%arg0: i1) {
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_4]] : i1
// CHECK: %[[VAL_9:.*]] = buffer [2] fifo %[[VAL_8]] : i1
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = control_merge %[[VAL_6]] : none, index
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_8]], %[[VAL_10]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_13]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_13]] : none, index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_17]] : none
// CHECK: %[[VAL_20:.*]] = merge %[[VAL_5]] : i1
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = control_merge %[[VAL_7]] : none
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = control_merge %[[VAL_7]] : none, index
// CHECK: %[[VAL_23:.*]] = br %[[VAL_20]] : i1
// CHECK: %[[VAL_24:.*]] = br %[[VAL_21]] : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_24]] : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_24]] : none, index
// CHECK: %[[VAL_27:.*]] = buffer [1] seq %[[VAL_28:.*]] {initValues = [0]} : i1
// CHECK: %[[VAL_29:.*]] = mux %[[VAL_27]] {{\[}}%[[VAL_25]], %[[VAL_30:.*]]] : i1, none
// CHECK: %[[VAL_31:.*]] = mux %[[VAL_26]] {{\[}}%[[VAL_23]]] : index, i1
@ -384,7 +384,7 @@ func.func @blockWith3PredsAndLoop(%arg0: i1) {
// CHECK: %[[VAL_34:.*]] = br %[[VAL_32]] : i1
// CHECK: %[[VAL_35:.*]] = br %[[VAL_29]] : none
// CHECK: %[[VAL_36:.*]] = merge %[[VAL_34]] : i1
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = control_merge %[[VAL_35]] : none
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = control_merge %[[VAL_35]] : none, index
// CHECK: %[[VAL_39:.*]], %[[VAL_33]] = cond_br %[[VAL_36]], %[[VAL_36]] : i1
// CHECK: %[[VAL_40:.*]] = constant %[[VAL_37]] {value = true} : i1
// CHECK: %[[VAL_41:.*]] = arith.xori %[[VAL_36]], %[[VAL_40]] : i1
@ -436,20 +436,20 @@ func.func @otherBlockOrder(%arg0: i1) {
// CHECK: %[[VAL_18:.*]] = merge %[[VAL_8]] : i64
// CHECK: %[[VAL_14:.*]] = merge %[[VAL_6]] : i1
// CHECK: %[[VAL_15:.*]] = buffer [2] fifo %[[VAL_14]] : i1
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = control_merge %[[VAL_12]] : none, index
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = cond_br %[[VAL_14]], %[[VAL_18]] : i64
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = cond_br %[[VAL_14]], %[[VAL_18]] : i64
// CHECK: %[[VAL_19:.*]], %[[VAL_20:.*]] = cond_br %[[VAL_14]], %[[VAL_16]] : none
// CHECK: %[[VAL_27:.*]] = merge %[[VAL_21]] : i64
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_19]] : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_19]] : none, index
// CHECK: %[[VAL_28:.*]] = br %[[VAL_25]] : none
// CHECK: %[[VAL_31:.*]] = merge %[[VAL_24]] : i64
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_22]] : i64
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = control_merge %[[VAL_20]] : none
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = control_merge %[[VAL_20]] : none, index
// CHECK: %[[VAL_33:.*]] = br %[[VAL_29]] : none
// CHECK: %[[VAL_36:.*]] = merge %[[VAL_11]] : i64
// CHECK: %[[VAL_37:.*]] = merge %[[VAL_9]] : i64
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_13]] : none
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_13]] : none, index
// CHECK: %[[VAL_38:.*]] = br %[[VAL_34]] : none
// CHECK: %[[VAL_39:.*]] = mux %[[VAL_15]] {{\[}}%[[VAL_33]], %[[VAL_28]]] : i1, none
// CHECK: %[[VAL_40:.*]] = arith.index_cast %[[VAL_15]] : i1 to index
@ -487,11 +487,11 @@ func.func @multiple_block_args(%arg0: i1, %arg1: i64) {
// CHECK: %[[VAL_4:.*]], %[[VAL_5:.*]] = cond_br %[[VAL_2]], %[[VAL_2]] : i1
// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_2]], %[[VAL_1x]] : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_4]] : i1
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = control_merge %[[VAL_6]] : none
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = control_merge %[[VAL_6]] : none, index
// CHECK: %[[VAL_11:.*]] = br %[[VAL_8]] : i1
// CHECK: %[[VAL_12:.*]] = br %[[VAL_9]] : none
// CHECK: %[[VAL_13:.*]] = merge %[[VAL_5]] : i1
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_7]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_7]] : none, index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_13]] : i1
// CHECK: %[[VAL_17:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_3]] {{\[}}%[[VAL_17]], %[[VAL_12]]] : i1, none
@ -506,10 +506,10 @@ func.func @multiple_block_args(%arg0: i1, %arg1: i64) {
// CHECK: %[[VAL_21]] = merge %[[VAL_30]] : i1
// CHECK: %[[VAL_31:.*]], %[[VAL_32:.*]] = cond_br %[[VAL_25]], %[[VAL_22]] : none
// CHECK: %[[VAL_33:.*]] = merge %[[VAL_28]] : i1
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_32]] : none
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_32]] : none, index
// CHECK: %[[VAL_26]] = br %[[VAL_33]] : i1
// CHECK: %[[VAL_23]] = br %[[VAL_34]] : none
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = control_merge %[[VAL_31]] : none
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = control_merge %[[VAL_31]] : none, index
// CHECK: return %[[VAL_36]] : none
// CHECK: }
func.func @mergeBlockAsLoopHeader(%arg0: i1) {

View File

@ -27,11 +27,11 @@ handshake.func @simple(%arg0: none, ...) -> none {
// -----
// CHECK: handshake.func @cmerge_with_control_used(%[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, index, none)
// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge %[[VAL_0]], %[[VAL_1]] : none
// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge %[[VAL_0]], %[[VAL_1]] : none, index
// CHECK: return %[[VAL_3]], %[[VAL_4]], %[[VAL_2]] : none, index, none
// CHECK: }
handshake.func @cmerge_with_control_used(%arg0: none, %arg1: none, %arg2: none) -> (none, index, none) {
%result, %index = control_merge %arg0, %arg1 : none
%result, %index = control_merge %arg0, %arg1 : none, index
handshake.return %result, %index, %arg2 : none, index, none
}
@ -43,7 +43,7 @@ handshake.func @cmerge_with_control_used(%arg0: none, %arg1: none, %arg2: none)
// CHECK: return %[[VAL_3]], %[[VAL_2]] : none, none
// CHECK: }
handshake.func @cmerge_with_control_sunk(%arg0: none, %arg1: none, %arg2: none) -> (none, none) {
%result, %index = control_merge %arg0, %arg1 : none
%result, %index = control_merge %arg0, %arg1 : none, index
sink %index : index
handshake.return %result, %arg2 : none, none
}
@ -55,7 +55,7 @@ handshake.func @cmerge_with_control_sunk(%arg0: none, %arg1: none, %arg2: none)
// CHECK: return %[[VAL_3]], %[[VAL_2]] : none, none
// CHECK: }
handshake.func @cmerge_with_control_ignored(%arg0: none, %arg1: none, %arg2: none) -> (none, none) {
%result, %index = control_merge %arg0, %arg1 : none
%result, %index = control_merge %arg0, %arg1 : none, index
handshake.return %result, %arg2 : none, none
}

View File

@ -10,7 +10,7 @@ handshake.func @invalid_merge_like_wrong_type(%arg0: i1, %arg1: i32, %arg2: i64)
// -----
handshake.func @invalid_mux_unsupported_select(%arg0: tensor<i1>, %arg1: i32, %arg2: i32) {
// expected-error @+1 {{unsupported type for select operand: 'tensor<i1>'}}
// expected-error @+1 {{unsupported type for indexing operand: 'tensor<i1>'}}
%0 = mux %arg0 [%arg1, %arg2] : tensor<i1>, i32
return %0 : i32
}
@ -18,7 +18,7 @@ handshake.func @invalid_mux_unsupported_select(%arg0: tensor<i1>, %arg1: i32, %a
// -----
handshake.func @invalid_mux_narrow_select(%arg0: i1, %arg1: i32, %arg2: i32, %arg3: i32) {
// expected-error @+1 {{select bitwidth was 1, which can mux 2 operands, but found 3 operands}}
// expected-error @+1 {{bitwidth of indexing operand is 1, which can index into 2 operands, but found 3 operands}}
%0 = mux %arg0 [%arg1, %arg2, %arg3] : i1, i32
return %0 : i32
}
@ -239,7 +239,7 @@ handshake.func @invalid_sost_op_zero_size(%ctrl : none) -> (none, none) {
handshake.func @invalid_sost_op_wrong_operands(%arg0 : i64, %arg1 : i32, %ctrl : none) -> (i64, none) { // expected-note {{prior use here}}
// expected-error @+1 {{use of value '%arg1' expects different type than prior uses: 'i64' vs 'i32'}}
%0, %1 = control_merge %arg0, %arg1 : i64
%0, %1 = control_merge %arg0, %arg1 : i64, index
return %0, %ctrl : i64, none
}

View File

@ -5,7 +5,7 @@ module {
// CHECK: buffer
%0 = br %arg0 : none
// CHECK: buffer
%1:2 = control_merge %0 : none
%1:2 = control_merge %0 : none, index
// CHECK: buffer
%2:3 = fork [3] %1#0 : none
// CHECK: buffer
@ -28,7 +28,7 @@ module {
%9:2 = fork [2] %8 : index
// CHECK: buffer
// CHECK: buffer
%10:2 = control_merge %23, %5 : none
%10:2 = control_merge %23, %5 : none, index
// CHECK: buffer
%11:2 = fork [2] %10#1 : index
// CHECK: buffer
@ -60,7 +60,7 @@ module {
// CHECK: buffer
%17 = merge %trueResult : index
// CHECK: buffer
%18:2 = control_merge %trueResult_0 : none
%18:2 = control_merge %trueResult_0 : none, index
// CHECK: buffer
%19:2 = fork [2] %18#0 : none
// CHECK: buffer
@ -77,7 +77,7 @@ module {
// CHECK: buffer
%24 = br %21 : index
// CHECK: buffer
%25:2 = control_merge %falseResult_1 : none
%25:2 = control_merge %falseResult_1 : none, index
// CHECK: buffer
sink %25#1 : index
return %25#0 : none

View File

@ -17,7 +17,7 @@
// CHECK: %[[VAL_12:.*]] = mux %[[VAL_13:.*]]#1 {{\[}}%[[VAL_14:.*]], %[[VAL_11]]] : index, index
// CHECK: %[[VAL_15:.*]] = buffer [2] seq %[[VAL_12]] : index
// CHECK: %[[VAL_16:.*]]:2 = fork [2] %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_19:.*]], %[[VAL_9]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_19:.*]], %[[VAL_9]] : none, index
// CHECK: %[[VAL_20:.*]] = buffer [2] seq %[[VAL_18]] : index
// CHECK: %[[VAL_21:.*]] = buffer [2] seq %[[VAL_17]] : none
// CHECK: %[[VAL_13]]:2 = fork [2] %[[VAL_20]] : index
@ -35,7 +35,7 @@
// CHECK: %[[VAL_35:.*]] = buffer [2] fifo %[[VAL_34]] : index
// CHECK: %[[VAL_36:.*]] = merge %[[VAL_28]] : index
// CHECK: %[[VAL_37:.*]] = buffer [2] fifo %[[VAL_36]] : index
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = control_merge %[[VAL_30]] : none
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = control_merge %[[VAL_30]] : none, index
// CHECK: %[[VAL_40:.*]] = buffer [2] fifo %[[VAL_39]] : index
// CHECK: %[[VAL_41:.*]] = buffer [2] fifo %[[VAL_38]] : none
// CHECK: %[[VAL_42:.*]]:2 = fork [2] %[[VAL_41]] : none
@ -45,7 +45,7 @@
// CHECK: %[[VAL_14]] = br %[[VAL_37]] : index
// CHECK: %[[VAL_19]] = br %[[VAL_42]]#1 : none
// CHECK: %[[VAL_23]] = br %[[VAL_44]] : index
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = control_merge %[[VAL_31]] : none
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = control_merge %[[VAL_31]] : none, index
// CHECK: %[[VAL_47:.*]] = buffer [2] fifo %[[VAL_46]] : index
// CHECK: %[[VAL_48:.*]] = buffer [2] fifo %[[VAL_45]] : none
// CHECK: sink %[[VAL_47]] : index
@ -54,7 +54,7 @@
module {
handshake.func @simple_loop(%arg0: none, ...) -> none {
%0 = br %arg0 : none
%1:2 = control_merge %0 : none
%1:2 = control_merge %0 : none, index
%2:3 = fork [3] %1#0 : none
sink %1#1 : index
%3 = constant %2#1 {value = 1 : index} : index
@ -64,7 +64,7 @@ module {
%7 = br %4 : index
%8 = mux %11#1 [%22, %7] : index, index
%9:2 = fork [2] %8 : index
%10:2 = control_merge %23, %5 : none
%10:2 = control_merge %23, %5 : none, index
%11:2 = fork [2] %10#1 : index
%12 = mux %9#0 [%24, %6] : index, index
%13:2 = fork [2] %12 : index
@ -77,7 +77,7 @@ module {
sink %falseResult_3 : index
%16 = merge %trueResult_2 : index
%17 = merge %trueResult : index
%18:2 = control_merge %trueResult_0 : none
%18:2 = control_merge %trueResult_0 : none, index
%19:2 = fork [2] %18#0 : none
sink %18#1 : index
%20 = constant %19#0 {value = 1 : index} : index
@ -85,7 +85,7 @@ module {
%22 = br %17 : index
%23 = br %19#1 : none
%24 = br %21 : index
%25:2 = control_merge %falseResult_1 : none
%25:2 = control_merge %falseResult_1 : none, index
sink %25#1 : index
return %25#0 : none
}

View File

@ -2,7 +2,7 @@
// CHECK-LABEL: handshake.func @gcd(
// CHECK-SAME: %[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: none, ...) -> (i32, none)
// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge %[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_2]] : none
// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge %[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_2]] : none, index
// CHECK: %[[VAL_7:.*]] = mux %[[VAL_4]] {{\[}}%[[VAL_8:.*]], %[[VAL_9:.*]], %[[VAL_1]]] : index, i32
// CHECK: %[[VAL_10:.*]] = mux %[[VAL_4]] {{\[}}%[[VAL_11:.*]], %[[VAL_12:.*]], %[[VAL_0]]] : index, i32
// CHECK: %[[VAL_13:.*]] = arith.cmpi ne, %[[VAL_10]], %[[VAL_7]] : i32
@ -18,7 +18,7 @@
// CHECK: return %[[VAL_19]], %[[VAL_15]] : i32, none
// CHECK: }
handshake.func @gcd(%arg0: i32, %arg1: i32, %arg2: none, ...) -> (i32, none) {
%result, %index = control_merge %falseResult_5, %trueResult_4, %arg2 : none
%result, %index = control_merge %falseResult_5, %trueResult_4, %arg2 : none, index
%0:2 = fork [2] %index : index
%1 = mux %0#1 [%14, %11#0, %arg1] : index, i32
%2:2 = fork [2] %1 : i32

View File

@ -29,7 +29,7 @@ handshake.func @single_block(%arg0: i32, %arg1: i32, %arg2: none, ...) -> (i32,
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = cond_br %[[VAL_6]]#0, %[[VAL_5]]#2 : none
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_9]] : none
// CHECK: %[[VAL_12:.*]] = constant %[[VAL_11]]#0 {value = 42 : i32} : i32
// CHECK: %[[VAL_13:.*]], %[[VAL_14:.*]] = control_merge %[[VAL_11]]#1, %[[VAL_10]] : none
// CHECK: %[[VAL_13:.*]], %[[VAL_14:.*]] = control_merge %[[VAL_11]]#1, %[[VAL_10]] : none, index
// CHECK: %[[VAL_15:.*]] = mux %[[VAL_14]] {{\[}}%[[VAL_12]], %[[VAL_8]]] : index, i32
// CHECK: %[[VAL_4]] = join %[[VAL_15]], %[[VAL_13]], %[[VAL_5]]#3 : i32, none, none
// CHECK: return %[[VAL_15]], %[[VAL_13]] : i32, none
@ -42,7 +42,7 @@ handshake.func @triangle(%arg0: i32, %arg1: i1, %arg2: none, ...) -> (i32, none)
%trueResult_0, %falseResult_1 = cond_br %0#0, %arg2 : none
%1:2 = fork [2] %trueResult_0 : none
%2 = constant %1#0 {value = 42 : i32} : i32
%result, %index = control_merge %1#1, %falseResult_1 : none
%result, %index = control_merge %1#1, %falseResult_1 : none, index
%3 = mux %index [%2, %falseResult] : index, i32
return %3, %result : i32, none
}