[Handshake] Major overhaul of the Handshake IR (#2206)

This (fairly monolithic) commit introduces a major overhaul of the Handshake IR syntax. The goal is to reduce verbosity by implementing custom parsers/printers. In doing so, we fold various attributes into being parts of the op syntax. This commits includes changes prior proposed by @stephenneuendorffer. Some work is still needed reducing the verbosity of `handshake.memory` operations, but I've decided to keep this commit as-is. While a major change, this is a mostly syntactical change, and underlying tests remain (largely) unmodified from a functional point of view.

Changes:
- the `handshake` dialect is now the default dialect within `handshake.func` operations, removing the need to prefix every single operation with `handshake.`
- Factors out "isControl" logic to an interface implemented by all handshake operations.
- Most ops now have "size, dataType" and "control" attributes as part of their arguments. This, alongside a shared operation syntax, is leveraged in the parsers. You'll notice that a SOST abbreviation is present in `HandshakeOps.cpp`. SOST being Sized Operation with Single Type.
- The `control` attribute is inferred from the "dataType" of the operation. This means that we no longer have "control = true" littered al over the IR. `control` is assumed whenever `dataType.isa<NoneType>()`.
- Examples added for all handshake ops in the TableGen file.

New syntaxes:
```mlir
%1:2 = fork [2] %0 : i32
%0 = merge %a, %b, %c : i32
%0 = mux %select [%data0, %data1, %data2] {attributes}: index, i32
%0, %idx = control_merge %a, %b, %c : i32
%1 = br %0 : i32
%true, %false = cond_br %cond, %data : i32
sink %data : i32
%0 = constant %ctrl {value = 42 : i32} : i32
%dataToSucc, %addr1ToMem, %addr2ToMem = load [%addr1, %addr2] %dataFromMem, %ctrl : i8, i16, index
%dataToMem, %addrToMem = store [%addr1, %addr2] %dataFromPred , %ctrl : i8, i16, index
%0 = join %a, %b, %c : i32
```
This commit is contained in:
Morten Borup Petersen 2021-11-19 08:48:25 +00:00 committed by GitHub
parent 54723918c1
commit f0e4a641f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 3271 additions and 2870 deletions

View File

@ -29,7 +29,8 @@ def Handshake_Dialect : Dialect {
class Handshake_Op<string mnemonic, list<OpTrait> traits = []>
: Op<Handshake_Dialect, mnemonic,
traits #[HasParent<"handshake::FuncOp">,
DeclareOpInterfaceMethods<NamedIOInterface>]> {
DeclareOpInterfaceMethods<NamedIOInterface>,
DeclareOpInterfaceMethods<ControlInterface>]> {
}
include "circt/Dialect/Handshake/HandshakeOps.td"

View File

@ -19,15 +19,15 @@ include "circt/Dialect/Handshake/Handshake.td"
def HasOneOperand : Constraint<CPred<"$_self.size() == 1">, "has one operand">;
def HasOneResult : Constraint<CPred<"$_self.size() == 1">, "has one result">;
def EliminateSimpleMergesPattern : Pat<(MergeOp $a), (replaceWithValue $a),
[(HasOneOperand:$a)]>;
def EliminateSimpleMergesPattern : Pat<(MergeOp $dataType, $size, $arg), (replaceWithValue $arg),
[(HasOneOperand:$arg)]>;
def EliminateSimpleBranchesPattern
: Pat<(BranchOp $a, $attr), (replaceWithValue $a)>;
: Pat<(BranchOp $dataType, $a), (replaceWithValue $a)>;
def EliminateSimpleForksPattern : Pat<(ForkOp
: $op $a, $attr),
(replaceWithValue $a), [(HasOneResult
: $op $dataType, $size, $arg),
(replaceWithValue $arg), [(HasOneResult
: $op)]>;
def EliminateSunkConstantsPattern

View File

@ -129,6 +129,25 @@ def NamedIOInterface : OpInterface<"NamedIOInterface"> {
];
}
def ControlInterface : OpInterface<"ControlInterface"> {
let description =
[{"Provides information on whether this operation is a control operation."}];
let methods = [
InterfaceMethod<
"Returns true if this operation is a control operation.",
"bool",
"isControl",
(ins),
"",
[{
auto ctrlAttr = $_op->template getAttrOfType<BoolAttr>("control");
if(!ctrlAttr)
return false;
return ctrlAttr.getValue();
}]>];
}
def HasClock : NativeOpTrait<"HasClock">;
#endif // HANDSHAKE_OP_INTERFACES

View File

@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//
include "mlir/IR/OpAsmInterface.td"
// This is almost exactly like a standard FuncOp, except that it has some
// extra verification conditions. In particular, each Value must
// only have a single use. Also, it defines a Dominance-Free Scope
@ -17,11 +19,12 @@ def FuncOp : Op<Handshake_Dialect, "func", [
IsolatedFromAbove,
FunctionLike,
Symbol,
RegionKindInterface
RegionKindInterface,
OpAsmOpInterface
]> {
let summary = "Handshake dialect function.";
let description = [{
The "handshake.func" operation represents a handshaked function.
The func operation represents a handshaked function.
This is almost exactly like a standard FuncOp, except that it has
some extra verification conditions. In particular, each Value must
only have a single use.
@ -97,6 +100,14 @@ def FuncOp : Op<Handshake_Dialect, "func", [
"' attribute of function type");
return success();
}
//===------------------------------------------------------------------===//
// OpAsmOpInterface Methods
//===------------------------------------------------------------------===//
static ::llvm::StringRef getDefaultDialect() {
return "handshake";
}
}];
let verifier = [{ return ::verify$cppClass(*this); }];
@ -123,7 +134,7 @@ def InstanceOp : Handshake_Op<"instance", [CallOpInterface]> {
let arguments = (ins FlatSymbolRefAttr:$module, Variadic<AnyType>:$operands);
let results = (outs Variadic<AnyType>);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<
(ins "FuncOp":$module, CArg<"ValueRange", "{}">:$operands), [{
$_state.addOperands(operands);
@ -181,7 +192,7 @@ def InstanceOp : Handshake_Op<"instance", [CallOpInterface]> {
def ReturnOp : Handshake_Op<"return", [Terminator]> {
let summary = "Handshake dialect return.";
let description = [{
The "handshake.return" operation represents a handshaked
The return operation represents a handshaked
function. This is almost exactly like a standard ReturnOp, except
that it exists in a handshake.func. It has the same operands as
standard ReturnOp which it replaces and an additional control -
@ -191,39 +202,43 @@ def ReturnOp : Handshake_Op<"return", [Terminator]> {
let arguments = (ins Variadic<AnyType> : $operands, NoneType : $control);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "ArrayRef<Value>":$operands)>];
let printer = "return ::print$cppClass(p, *this);";
let verifier = "return ::verify(*this);";
let parser = "return ::parse$cppClass(parser, result);";
let assemblyFormat = [{ operands attr-dict `:` type(operands) }];
}
def BufferOp : Handshake_Op<"buffer", [NoSideEffect, HasClock]> {
def BufferOp : Handshake_Op<"buffer", [NoSideEffect, HasClock,
AllTypesMatch<["operand", "result"]>]> {
let summary = "buffer operation";
let description = [{
The "handshake.buffer" operation represents a buffer operation. $slots
The buffer operation represents a buffer operation. $slots
must be an unsigned integer larger than 0. $sequantial=True indicates a
nontransparent buffer, while $sequantial=False indicates a transparent
buffer.
}];
let arguments = (ins AnyType, BoolAttr:$sequential, BoolAttr:$control,
Confined<I32Attr, [IntMinValue<1>]>:$slots);
let results = (outs AnyType);
let arguments = (ins
TypeAttr:$dataType,
Confined<I32Attr, [IntMinValue<1>]>:$size,
AnyType:$operand,
BoolAttr:$sequential);
let results = (outs AnyType:$result);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Type":$dataType, "int":$size,
"Value":$operand, "bool":$sequential)>];
let extraClassDeclaration = [{
bool isSequential() {
return (*this)->getAttrOfType<BoolAttr>("sequential").getValue();
}
bool isControl() {
return (*this)->getAttrOfType<BoolAttr>("control").getValue();
}
APInt getNumSlots() {
return (*this)->getAttrOfType<IntegerAttr>("slots").getValue();
int getNumSlots() {
return (*this)->getAttrOfType<IntegerAttr>("size").getValue().getZExtValue();
}
}];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def ForkOp : Handshake_Op<"fork", [
@ -233,40 +248,51 @@ def ForkOp : Handshake_Op<"fork", [
let summary = "fork operation";
let description = [{
The "handshake.fork" operation represents a fork operation. A
The fork operation represents a fork operation. A
single input is replicated to N outputs and distributed to each
output as soon as the corresponding successor is available.
Example:
```mlir
%1:2 = fork [2] %0 : i32
```
}];
let arguments = (ins AnyType, BoolAttr : $control);
let results = (outs Variadic<AnyType>);
let arguments = (ins
TypeAttr:$dataType,
Confined<I32Attr, [IntMinValue<1>]>:$size,
AnyType : $operand);
let results = (outs Variadic<AnyType> : $result);
let hasCanonicalizer = 1;
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$operand, "int":$outputs)>];
let extraClassDeclaration = [{
bool isControl() { return (*this)->getAttrOfType<BoolAttr>("control").getValue(); }
}];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def LazyForkOp : Handshake_Op<"lazy_fork", [NoSideEffect]> {
let summary = "lazy fork operation";
let description = [{
The "handshake.lfork" operation represents a lazy fork operation.
The lazy_fork operation represents a lazy fork operation.
A single input is replicated to N outputs and distributed to each
output when all successors are available.
Example:
```mlir
%1:2 = lazy_fork [2] %0 : i32
```
}];
let arguments = (ins AnyType, BoolAttr : $control);
let results = (outs Variadic<AnyType>);
let arguments = (ins
TypeAttr:$dataType,
Confined<I32Attr, [IntMinValue<1>]>:$size,
AnyType : $operand);
let results = (outs Variadic<AnyType> : $result);
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$operand, "int":$outputs)>];
let extraClassDeclaration = [{
bool isControl() { return (*this)->getAttrOfType<BoolAttr>("control").getValue(); }
}];
}
def MergeOp : Handshake_Op<"merge", [
@ -275,27 +301,38 @@ def MergeOp : Handshake_Op<"merge", [
]> {
let summary = "merge operation";
let description = [{
The "handshake.merge" operation represents a (nondeterministic)
The merge operation represents a (nondeterministic)
merge operation. Any input is propagated to the single output. The
number of inputs corresponds to the number of predecessor
blocks.
Example:
```
%0 = merge %a, %b, %c : i32
```
}];
let arguments = (ins Variadic<AnyType>:$dataOperands);
let results = (outs AnyType);
let arguments = (ins
TypeAttr:$dataType,
Confined<I32Attr, [IntMinValue<1>]>:$size,
Variadic<AnyType>:$dataOperands);
let results = (outs AnyType:$result);
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
let hasCanonicalizer = 1;
let builders = [OpBuilder<(ins "Value":$operand, "int":$inputs)>];
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "ValueRange":$operands)>];
}
def MuxOp : Handshake_Op<"mux", [
NoSideEffect, MergeLikeOpInterface,
DeclareOpInterfaceMethods<ExecutableOpInterface>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getOperandName"]>
DeclareOpInterfaceMethods<NamedIOInterface, ["getOperandName"]>
]> {
let summary = "mux operation";
let description = [{
The "handshake.mux" operation represents a(deterministic)
The mux operation represents a(deterministic)
merge operation.
Operands: select, data0, data1, data2, ...
@ -303,12 +340,22 @@ def MuxOp : Handshake_Op<"mux", [
block and it represents the index of the data operand that the mux
should propagate to its single output. The number of data inputs
corresponds to the number of predecessor blocks.
}];
let arguments = (ins AnyType : $selectOperand,
Variadic<AnyType> : $dataOperands);
let results = (outs AnyType);
Example:
```mlir
%0 = mux %select [%data0, %data1, %data2] {attributes}: index, i32
```
}];
let arguments = (ins
TypeAttr:$dataType,
Confined<I32Attr, [IntMinValue<1>]>:$size,
AnyType : $selectOperand,
Variadic<AnyType> : $dataOperands);
let results = (outs AnyType : $result);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$operand, "int":$inputs)>];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
let verifier = "return ::verify(*this);";
}
@ -319,84 +366,95 @@ def ControlMergeOp : Handshake_Op<"control_merge", [
]> {
let summary = "control merge operation";
let description = [{
The "handshake.control_merge" operation represents a
The control_merge operation represents a
(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).
Example:
```
%0, %idx = control_merge %a, %b, %c : i32
```
}];
let arguments = (ins Variadic<AnyType>:$dataOperands, BoolAttr : $control);
let results = (outs Variadic<AnyType>);
let arguments = (ins
TypeAttr:$dataType,
Confined<I32Attr, [IntMinValue<1>]>:$size,
Variadic<AnyType> : $dataOperands);
let results = (outs AnyType : $result, Index : $index);
let hasCanonicalizer = 1;
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$operand, "int":$inputs)>];
let extraClassDeclaration = [{
bool isControl() {
return (*this)->getAttrOfType<BoolAttr>("control").getValue();
}
}];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def BranchOp : Handshake_Op<"branch", [
def BranchOp : Handshake_Op<"br", [
NoSideEffect, DeclareOpInterfaceMethods<ExecutableOpInterface>,
DeclareOpInterfaceMethods<GeneralOpInterface>
]> {
DeclareOpInterfaceMethods<GeneralOpInterface>,
AllTypesMatch<["dataOperand", "dataResult"]>
]> {
let summary = "branch operation";
let description = [{
The "handshake.branch" operation represents an unconditional
The branch operation represents an unconditional
branch. The single data input is propagated to the single
successor. The input must be triggered by some predecessor to
avoid continous triggering of a successor block.
Example:
```mlir
%1 = br %0 : i32
```
}];
let arguments = (ins AnyType : $dataOperand,
BoolAttr : $control);
let arguments = (ins
TypeAttr:$dataType,
AnyType : $dataOperand);
let results = (outs AnyType : $dataResult);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$dataOperand)>];
let hasCanonicalizer = 1;
let extraClassDeclaration = [{
bool isControl() {
return (*this)->getAttrOfType<BoolAttr>("control").getValue();
}
}];
let parser = "return ::parse$cppClass(parser, result);";
let printer = "return ::print$cppClass(p, *this);";
}
def ConditionalBranchOp : Handshake_Op<"conditional_branch", [
def ConditionalBranchOp : Handshake_Op<"cond_br", [
NoSideEffect, DeclareOpInterfaceMethods<ExecutableOpInterface>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getOperandName"]>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getResultName"]>
DeclareOpInterfaceMethods<NamedIOInterface, ["getResultName"]>,
TypesMatchWith<"data operand type matches true branch result type",
"dataOperand", "trueResult", "$_self">,
TypesMatchWith<"data operand type matches false branch result type",
"dataOperand", "falseResult", "$_self">
]> {
let summary = "conditional branch operation";
let description = [{
The "handshake.cbranch" operation represents a conditional
The cbranch operation represents a conditional
branch. The data input is propagated to one of the two outputs
based on the condition input.
Example:
```mlir
%true, %false = conditional_branch %cond, %data : i32
```
}];
let arguments = (ins I1 : $conditionOperand,
AnyType : $dataOperand,
BoolAttr : $control);
AnyType : $dataOperand);
let results = (outs AnyType : $trueResult,
AnyType : $falseResult);
let builders = [OpBuilder<(ins "Value":$condOperand, "Value":$dataOperand)>];
let skipDefaultBuilders = 1;
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
let extraClassDeclaration = [{
// These are the indices into the dests list.
enum { trueIndex = 0, falseIndex = 1 };
Value getFalseResult() { return getResult(falseIndex); }
Value getTrueResult() { return getResult(trueIndex); }
Value getDataOperand() { return getOperand(1); }
bool isControl() { return (*this)->getAttrOfType<BoolAttr>("control").getValue(); }
}];
}
@ -404,35 +462,44 @@ def SinkOp
: Handshake_Op<"sink", [DeclareOpInterfaceMethods<ExecutableOpInterface>]> {
let summary = "sink operation";
let description = [{
The "handshake.sink" operation discards any data that arrives at its
The sink operation discards any data that arrives at its
input.The sink has no successors and it can continuously consume data.
Example:
```mlir
sink %data : i32
```
}];
let arguments = (ins AnyType);
let arguments = (ins AnyType:$operand);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$operand)>];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def SourceOp : Handshake_Op<"source", [NoSideEffect]> {
let summary = "source operation";
let description = [{
The "handshake.source" operation represents continuous data
The source operation represents continuous data
source. The source continously sets a 'valid' signal which the
successor can consume at any point in time.
}];
let results = (outs AnyType);
let results = (outs AnyType:$result);
let assemblyFormat = [{ operands attr-dict `:` type($result)}];
}
def NeverOp : Handshake_Op<"never", [NoSideEffect]> {
let summary = "never operation";
let description = [{
The "handshake.never" operation represents disconnected data
The never operation represents disconnected data
source. The source never sets any 'valid' signal which will
never trigger the successor at any point in time.
}];
let results = (outs AnyType);
let results = (outs AnyType:$result);
let assemblyFormat = [{ operands attr-dict `:` type($result)}];
}
def ConstantOp : Handshake_Op<"constant", [
@ -442,36 +509,43 @@ def ConstantOp : Handshake_Op<"constant", [
]> {
let summary = "constant operation";
let description = [{
The "handshake.const" has a constant value. When triggered by its
The const has a constant value. When triggered by its
single `ctrl` input, it sends the constant value to its single
successor.
Example:
```mlir
%0 = constant %ctrl {value = 42 : i32} : i32
```
}];
let arguments = (ins AnyAttr:$value, AnyType:$ctrl);
let results = (outs AnyType);
let arguments = (ins AnyAttr:$value, NoneType:$ctrl);
let results = (outs AnyType : $result);
// let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Attribute":$value, "Value":$ctrl)>];
let skipDefaultBuilders = 1;
let hasCanonicalizer = 1;
let extraClassDeclaration = [{
Attribute getValue() { return (*this)->getAttr("value"); }
}];
let assemblyFormat = [{ $ctrl attr-dict `:` type($result)}];
}
def EndOp
: Handshake_Op<"end", [DeclareOpInterfaceMethods<ExecutableOpInterface>]> {
let summary = "end operation";
let description = [{
The "handshake.end" propagates the result of the appropriate
The end propagates the result of the appropriate
return operation from one of its inputs to its single output after
all memory accesses have completed. Currently not used(data
returned through ReturnOp).
}];
let arguments = (ins AnyType : $control, Variadic<AnyType>);
let arguments = (ins AnyType : $control, Variadic<AnyType> : $operands);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$operand)>];
let assemblyFormat = [{ operands attr-dict `:` type($control) `,` type($operands)}];
}
def StartOp : Handshake_Op<"start", [
@ -484,10 +558,11 @@ def StartOp : Handshake_Op<"start", [
}];
let arguments = (ins BoolAttr : $control);
let results = (outs NoneType);
let results = (outs NoneType : $result);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins)>];
let assemblyFormat = [{ operands attr-dict `:` type($result)}];
}
def TerminatorOp : Handshake_Op<"terminator", [Terminator]> {
@ -522,32 +597,19 @@ def MemoryOp : Handshake_Op<"memory", [
load addresses (lddata1, lddata2, ...), followed by all none outputs,
ordered as operands (stnone1, stnone2,...ldnone1, ldnone2,...)
}];
let arguments = (ins Variadic<AnyType>,
I32Attr : $ld_count,
I32Attr : $st_count,
I32Attr : $id,
MemRefTypeAttr : $type);
let results = (outs Variadic<AnyType>);
let arguments = (ins Variadic<AnyType> : $inputs,
I32Attr : $ldCount,
I32Attr : $stCount,
I32Attr : $id,
MemRefTypeAttr : $memRefType);
let results = (outs Variadic<AnyType> : $outputs);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(
ins "ArrayRef<Value>":$operands, "int":$outputs, "int":$control_outputs, "bool":$lsq,
"int":$id, "Value":$memref)>
];
let extraClassDeclaration = [{
APInt getLdCount() {
return (*this)->getAttrOfType<IntegerAttr>("ld_count").getValue();
}
APInt getStCount() {
return (*this)->getAttrOfType<IntegerAttr>("st_count").getValue();
}
unsigned getID() {
return (*this)->getAttrOfType<IntegerAttr>("id").getValue().getZExtValue();
}
MemRefType getMemRefType() {
return (*this)->getAttrOfType<TypeAttr>("type").getValue().cast<MemRefType>();
}
}];
let assemblyFormat = "`[` `ld` `=` $ldCount `,` `st` `=` $stCount `]` `(` $inputs `)` attr-dict `:` $memRefType `,` functional-type($inputs, $outputs)";
let verifier = "return ::verify$cppClass(*this);";
}
@ -569,8 +631,8 @@ def ExternalMemoryOp : Handshake_Op<"extmemory", [
```mlir
handshake.func @main(%i: index, %v: i32, %mem : memref<10xi32>, %ctrl: none) -> none {
%stCtrl = "handshake.extmemory"[ld = 0, st = 1](%mem : memref<10xi32>)(%vout, %addr) {id = 0 : i32} : (i32, index) -> (none)
%vout, %addr = "handshake.store"(%v, %i, %ctrl) : (i32, index, none) -> (i32, index)
%stCtrl = extmemory[ld = 0, st = 1](%mem : memref<10xi32>)(%vout, %addr) {id = 0 : i32} : (i32, index) -> (none)
%vout, %addr = store(%v, %i, %ctrl) : (i32, index, none) -> (i32, index)
...
}
```
@ -588,16 +650,13 @@ def ExternalMemoryOp : Handshake_Op<"extmemory", [
"int":$id)>
];
let assemblyFormat = "`[` `ld` `=` $ldCount `,` `st` `=` $stCount `]` `(` $memref `:` type($memref) `)` `(` $inputs `)` attr-dict `:` functional-type($inputs, $outputs)";
let extraClassDeclaration = [{
MemRefType getMemRefType() {
return (*this)->getOperand(0).getType().cast<MemRefType>();
}
}];
}
def LoadOp
: Handshake_Op<"load", [DeclareOpInterfaceMethods<ExecutableOpInterface>]> {
def LoadOp : Handshake_Op<"load", [
DeclareOpInterfaceMethods<ExecutableOpInterface>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getOperandName"]>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getResultName"]>
]> {
let summary = "load operation";
let description = [{
Load memory port, sends load requests to MemoryOp. From dataflow
@ -609,17 +668,26 @@ def LoadOp
Operands: address indices (from predecessor), data (from MemoryOp), control-only input.
Results: data (to successor), address indices (to MemoryOp).
Example:
```mlir
%dataToSucc, %addr1ToMem, %addr2ToMem = load [%addr1, %addr2] %dataFromMem, %ctrl : i8, i16, index
```
}];
let arguments = (ins Variadic<AnyType>, AnyType, NoneType);
let results = (outs AnyType, Variadic<AnyType>:$addressResults);
let arguments = (ins Variadic<AnyType>:$addresses, AnyType:$data, NoneType:$ctrl);
let results = (outs AnyType:$dataResult, Variadic<AnyType>:$addressResults);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "Value":$memref, "ArrayRef<Value>":$indices)>];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def StoreOp : Handshake_Op<"store", [
DeclareOpInterfaceMethods<ExecutableOpInterface>,
DeclareOpInterfaceMethods<GeneralOpInterface>
DeclareOpInterfaceMethods<GeneralOpInterface>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getOperandName"]>,
DeclareOpInterfaceMethods<NamedIOInterface, ["getResultName"]>
]> {
let summary = "store operation";
let description = [{
@ -631,13 +699,21 @@ def StoreOp : Handshake_Op<"store", [
Operands: address indices, data, control-only input.
Results: data and address indices (sent to MemoryOp).
Types: data type followed by address type.
Example:
```mlir
%dataToMem, %addrToMem = store [%addr1, %addr2] %dataFromPred , %ctrl : i8, i16, index
```
}];
let arguments = (ins AnyType, Variadic<AnyType>, NoneType);
let results = (outs AnyType, Variadic<AnyType>);
let arguments = (ins Variadic<AnyType>:$addresses, AnyType:$data, NoneType:$ctrl);
let results = (outs AnyType:$dataResult, Variadic<AnyType>:$addressResult);
let builders =
[OpBuilder<(ins "Value":$valueToStore, "ArrayRef<Value>":$indices)>];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def JoinOp : Handshake_Op<"join", [
@ -648,12 +724,19 @@ def JoinOp : Handshake_Op<"join", [
let description = [{
A control-only synchronizer. Produces a valid output when all
inputs become available.
Example:
```mlir
%0 = join %a, %b, %c : i32
```
}];
let arguments = (ins Variadic<NoneType>, BoolAttr : $control);
let results = (outs NoneType);
let arguments = (ins Variadic<NoneType> : $data);
let results = (outs NoneType : $result);
let skipDefaultBuilders = 1;
let builders = [OpBuilder<(ins "ArrayRef<Value>":$operands)>];
let printer = "return ::print$cppClass(p, *this);";
let parser = "return ::parse$cppClass(parser, result);";
}
def I4 : I<4>;

View File

@ -288,8 +288,7 @@ using DiscriminatingTypes = std::pair<SmallVector<Type>, SmallVector<Type>>;
static DiscriminatingTypes getHandshakeDiscriminatingTypes(Operation *op) {
return TypeSwitch<Operation *, DiscriminatingTypes>(op)
.Case<MemoryOp>([&](auto memOp) {
return DiscriminatingTypes{{},
{memOp.getMemRefType().getElementType()}};
return DiscriminatingTypes{{}, {memOp.memRefType().getElementType()}};
})
.Default([&](auto) {
// By default, all in- and output types which is not a control type
@ -387,7 +386,7 @@ static std::string getSubModuleName(Operation *oldOp) {
// Add buffer information.
if (auto bufferOp = dyn_cast<handshake::BufferOp>(oldOp)) {
subModuleName += "_" + std::to_string(bufferOp.slots()) + "slots";
subModuleName += "_" + std::to_string(bufferOp.getNumSlots()) + "slots";
if (bufferOp.isSequential())
subModuleName += "_seq";
}
@ -1650,7 +1649,7 @@ bool HandshakeBuilder::visitHandshake(ForkOp op) {
auto clock = portList[portNum - 2][0];
auto reset = portList[portNum - 1][0];
return buildForkLogic(input, outputs, clock, reset, op.control());
return buildForkLogic(input, outputs, clock, reset, op.isControl());
}
/// Please refer to test_constant.mlir test case.
@ -1883,8 +1882,8 @@ bool HandshakeBuilder::visitHandshake(BufferOp op) {
// For now, we only support sequential buffers.
if (op.sequential())
return buildSeqBufferLogic(op.slots(), &input, &output, clock, reset,
op.control());
return buildSeqBufferLogic(op.getNumSlots(), &input, &output, clock, reset,
op.isControl());
else
return false;
}
@ -1941,7 +1940,7 @@ bool HandshakeBuilder::visitHandshake(ExternalMemoryOp op) {
bool HandshakeBuilder::visitHandshake(MemoryOp op) {
// Get the memory type and element type.
MemRefType type = op.type();
MemRefType type = op.memRefType();
Type elementType = type.getElementType();
if (!elementType.isSignlessInteger()) {
op.emitError("only memrefs of signless ints are supported");
@ -1967,8 +1966,8 @@ bool HandshakeBuilder::visitHandshake(MemoryOp op) {
};
// Collect the port info for each port.
uint64_t numLoads = op.getLdCount().getLimitedValue();
uint64_t numStores = op.getStCount().getLimitedValue();
uint64_t numLoads = op.ldCount();
uint64_t numStores = op.stCount();
SmallVector<std::pair<Identifier, MemOp::PortKind>, 8> ports;
for (size_t i = 0; i < numLoads; ++i) {
auto portName = loadIdentifier(i);
@ -2187,14 +2186,14 @@ bool HandshakeBuilder::visitHandshake(MemoryOp op) {
}
bool HandshakeBuilder::visitHandshake(handshake::StoreOp op) {
// Input data accepted from the predecessor.
ValueVector inputData = portList[0];
Value inputDataData = inputData[2];
// Input address accepted from the predecessor.
ValueVector inputAddr = portList[1];
ValueVector inputAddr = portList[0];
Value inputAddrData = inputAddr[2];
// Input data accepted from the predecessor.
ValueVector inputData = portList[1];
Value inputDataData = inputData[2];
// Control channel.
ValueVector control = portList[2];

View File

@ -242,10 +242,14 @@ Operation *insertMerge(Block *block, Value val,
}
}
// If there are no block predecessors (i.e., entry block), function argument
// is set as single operand
if (numPredecessors <= 1)
return rewriter.create<handshake::MergeOp>(block->front().getLoc(), val, 1);
// If there are no block predecessors (i.e., entry block)
if (numPredecessors <= 1) {
SmallVector<Value> mergeOperands;
mergeOperands.append(2, val); // 2 dummy values used here due to hard-coded
// logic of reconnectMergeOps.
return rewriter.create<handshake::MergeOp>(block->front().getLoc(),
mergeOperands);
}
return rewriter.create<handshake::MuxOp>(block->front().getLoc(), val,
numPredecessors);
@ -770,9 +774,10 @@ MemRefToMemoryAccessOp replaceMemoryOps(handshake::FuncOp f,
"Address operands of affine memref access cannot be reduced.");
if (isa<mlir::AffineReadOpInterface>(op)) {
newOp = rewriter.create<handshake::LoadOp>(
auto loadOp = rewriter.create<handshake::LoadOp>(
op.getLoc(), access.memref, *operands);
op.getResult(0).replaceAllUsesWith(newOp->getResult(0));
newOp = loadOp;
op.getResult(0).replaceAllUsesWith(loadOp.dataResult());
} else {
newOp = rewriter.create<handshake::StoreOp>(
op.getLoc(), op.getOperand(0), *operands);
@ -1556,10 +1561,10 @@ struct HandshakeInsertBufferPass
auto value = operand.get();
builder.setInsertionPointAfter(op);
auto bufferOp = builder.create<handshake::BufferOp>(
op->getLoc(), value.getType(), value, /*sequential=*/true,
/*control=*/value.getType().isa<NoneType>(),
/*slots=*/numSlots);
auto bufferOp =
builder.create<handshake::BufferOp>(op->getLoc(), value.getType(),
/*slots=*/numSlots, value,
/*sequential=*/true);
value.replaceUsesWithIf(
bufferOp,
function_ref<bool(OpOperand &)>([](OpOperand &operand) -> bool {
@ -1583,10 +1588,9 @@ struct HandshakeInsertBufferPass
if (callback(definingOp, usingOp)) {
builder.setInsertionPoint(usingOp);
auto buffer = builder.create<handshake::BufferOp>(
oldValue.getLoc(), oldValue.getType(), oldValue,
/*sequential=*/true,
/*control=*/oldValue.getType().isa<NoneType>(),
/*slots=*/numSlots);
oldValue.getLoc(), oldValue.getType(),
/*slots=*/numSlots, oldValue,
/*sequential=*/true);
use.getOwner()->setOperand(use.getOperandNumber(), buffer);
}

View File

@ -97,6 +97,66 @@ void updateTime(ArrayRef<mlir::Value> ins, ArrayRef<mlir::Value> outs,
timeMap[out] = time;
}
namespace sost {
// Sized Operation with Single Type (SOST).
// These are operation on the format:
// opname operands optAttrDict : dataType
// containing a 'size' (=operands.size()) and 'dataType' attribute.
// if 'explicitSize' is set, the operation is parsed as follows:
// opname [$size] operands opAttrDict : dataType
// If the datatype of the operation is "None", the operation is also added a
// {control = true} attribute. if 'alwaysControl' is set, the control attribute
// is always set.
void addAttributes(OperationState &result, int size, Type dataType,
bool alwaysControl = false) {
result.addAttribute(
"size",
IntegerAttr::get(IntegerType::get(dataType.getContext(), 32), size));
result.addAttribute("dataType", TypeAttr::get(dataType));
if (dataType.isa<NoneType>() || alwaysControl)
result.addAttribute("control", BoolAttr::get(dataType.getContext(), true));
}
static ParseResult parseIntInSquareBrackets(OpAsmParser &parser, int &v) {
if (parser.parseLSquare() || parser.parseInteger(v) || parser.parseRSquare())
return failure();
return success();
}
static ParseResult
parseOperation(OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::OperandType> &operands,
OperationState &result, int &size, Type &type, bool explicitSize,
bool alwaysControl = false) {
if (explicitSize)
if (parseIntInSquareBrackets(parser, size))
return failure();
if (parser.parseOperandList(operands) ||
parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() ||
parser.parseType(type))
return failure();
if (!explicitSize)
size = operands.size();
sost::addAttributes(result, size, type, alwaysControl);
return success();
}
static void printOp(OpAsmPrinter &p, Operation *op, bool explicitSize) {
if (explicitSize) {
int size = op->getAttrOfType<IntegerAttr>("size").getValue().getZExtValue();
p << " [" << size << "]";
}
Type type = op->getAttrOfType<TypeAttr>("dataType").getValue();
p << " " << op->getOperands();
p.printOptionalAttrDict((op)->getAttrs(), {"size", "dataType", "control"});
p << " : " << type;
}
} // namespace sost
bool tryToExecute(Operation *op,
llvm::DenseMap<mlir::Value, llvm::Any> &valueMap,
llvm::DenseMap<mlir::Value, double> &timeMap,
@ -121,7 +181,6 @@ bool tryToExecute(Operation *op,
void ForkOp::build(OpBuilder &builder, OperationState &result, Value operand,
int outputs) {
auto type = operand.getType();
// Fork has results as many as there are successor ops
@ -129,11 +188,30 @@ void ForkOp::build(OpBuilder &builder, OperationState &result, Value operand,
// Single operand
result.addOperands(operand);
sost::addAttributes(result, outputs, type);
}
// Fork is control-only if it has NoneType. This includes the no-data output
// of a ControlMerge or a StartOp, as well as control values from MemoryOps.
bool isControl = operand.getType().isa<NoneType>() ? true : false;
result.addAttribute("control", builder.getBoolAttr(isControl));
static ParseResult parseForkOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
SmallVector<Type, 1> resultTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type,
/*explicitSize=*/true))
return failure();
resultTypes.assign(size, type);
result.addTypes(resultTypes);
if (parser.resolveOperands(allOperands, operandTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
static void printForkOp(OpAsmPrinter &p, ForkOp op) {
sost::printOp(p, op, true);
}
namespace {
@ -192,7 +270,6 @@ bool handshake::ForkOp::tryExecute(
void LazyForkOp::build(OpBuilder &builder, OperationState &result,
Value operand, int outputs) {
auto type = operand.getType();
// Fork has results as many as there are successor ops
@ -208,24 +285,49 @@ void LazyForkOp::build(OpBuilder &builder, OperationState &result,
operand == op->getResult(0))
? true
: false;
result.addAttribute("control", builder.getBoolAttr(isControl));
sost::addAttributes(result, outputs, type, isControl);
}
void MergeOp::build(OpBuilder &builder, OperationState &result, Value operand,
int inputs) {
static ParseResult parseLazyForkOp(OpAsmParser &parser,
OperationState &result) {
return parseForkOp(parser, result);
}
auto type = operand.getType();
static void printLazyForkOp(OpAsmPrinter &p, LazyForkOp op) {
sost::printOp(p, op, true);
}
void MergeOp::build(OpBuilder &builder, OperationState &result,
ValueRange operands) {
assert(operands.size() != 0 &&
"Expected at least one operand to this merge op.");
auto type = operands.front().getType();
result.types.push_back(type);
// Operand to keep defining value (used when connecting merges)
// Removed afterwards
result.addOperands(operand);
// Operands from predecessor blocks
for (int i = 0, e = inputs; i < e; ++i)
result.addOperands(operand);
result.addOperands(operands);
sost::addAttributes(result, operands.size(), type);
}
static ParseResult parseMergeOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
SmallVector<Type, 1> resultTypes, dataOperandsTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type, false))
return failure();
dataOperandsTypes.assign(size, type);
resultTypes.push_back(type);
result.addTypes(resultTypes);
if (parser.resolveOperands(allOperands, dataOperandsTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
void printMergeOp(OpAsmPrinter &p, MergeOp op) { sost::printOp(p, op, false); }
void MergeOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
results.insert<circt::handshake::EliminateSimpleMergesPattern>(context);
@ -261,7 +363,6 @@ bool handshake::MergeOp::tryExecute(
void MuxOp::build(OpBuilder &builder, OperationState &result, Value operand,
int inputs) {
auto type = operand.getType();
result.types.push_back(type);
@ -271,12 +372,52 @@ void MuxOp::build(OpBuilder &builder, OperationState &result, Value operand,
// Operands from predecessor blocks
for (int i = 0, e = inputs; i < e; ++i)
result.addOperands(operand);
sost::addAttributes(result, inputs, type);
}
std::string handshake::MuxOp::getOperandName(unsigned int idx) {
return idx == 0 ? "select" : defaultOperandName(idx - 1);
}
static ParseResult parseMuxOp(OpAsmParser &parser, OperationState &result) {
OpAsmParser::OperandType selectOperand;
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type selectType, dataType;
SmallVector<Type, 1> dataOperandsTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
if (parser.parseOperand(selectOperand) || parser.parseLSquare() ||
parser.parseOperandList(allOperands) || parser.parseRSquare() ||
parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() ||
parser.parseType(selectType) || parser.parseComma() ||
parser.parseType(dataType))
return failure();
int size = allOperands.size();
sost::addAttributes(result, size, dataType);
dataOperandsTypes.assign(size, dataType);
result.addTypes(dataType);
allOperands.insert(allOperands.begin(), selectOperand);
if (parser.resolveOperands(
allOperands,
llvm::concat<const Type>(ArrayRef<Type>(selectType),
ArrayRef<Type>(dataOperandsTypes)),
allOperandLoc, result.operands))
return failure();
return success();
}
static void printMuxOp(OpAsmPrinter &p, MuxOp op) {
Type dataType = op->getAttrOfType<TypeAttr>("dataType").getValue();
Type selectType = op.selectOperand().getType();
auto ops = op.getOperands();
p << ' ' << ops.front();
p << " [";
p.printOperands(ops.drop_front());
p << "]";
p.printOptionalAttrDict((op)->getAttrs(), {"dataType", "size", "control"});
p << " : " << selectType << ", " << dataType;
}
bool handshake::MuxOp::tryExecute(
llvm::DenseMap<mlir::Value, llvm::Any> &valueMap,
llvm::DenseMap<unsigned, unsigned> &memoryMap,
@ -338,7 +479,6 @@ std::string handshake::ControlMergeOp::getResultName(unsigned int idx) {
void ControlMergeOp::build(OpBuilder &builder, OperationState &result,
Value operand, int inputs) {
auto type = operand.getType();
result.types.push_back(type);
// Second result gives the input index to the muxes
@ -353,7 +493,33 @@ void ControlMergeOp::build(OpBuilder &builder, OperationState &result,
for (int i = 0, e = inputs; i < e; ++i)
result.addOperands(operand);
result.addAttribute("control", builder.getBoolAttr(true));
sost::addAttributes(result, inputs, type);
}
static ParseResult parseControlMergeOp(OpAsmParser &parser,
OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
SmallVector<Type, 1> resultTypes, dataOperandsTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type,
/*explicitSize=*/false))
return failure();
dataOperandsTypes.assign(size, type);
resultTypes.push_back(type);
resultTypes.push_back(IndexType::get(parser.getContext()));
result.addTypes(resultTypes);
if (parser.resolveOperands(allOperands, dataOperandsTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
void printControlMergeOp(OpAsmPrinter &p, ControlMergeOp op) {
sost::printOp(p, op, false);
}
static ParseResult verifyFuncOp(handshake::FuncOp op) {
@ -446,7 +612,6 @@ static SmallVector<Attribute> getFuncOpNames(Builder &builder, TypeRange types,
void handshake::FuncOp::build(OpBuilder &builder, OperationState &state,
StringRef name, FunctionType type,
ArrayRef<NamedAttribute> attrs) {
state.addAttribute(SymbolTable::getSymbolAttrName(),
builder.getStringAttr(name));
state.addAttribute(getTypeAttrName(), TypeAttr::get(type));
@ -573,8 +738,7 @@ LogicalResult EliminateSimpleControlMergesPattern::matchAndRewrite(
return failure();
}
auto merge = rewriter.create<MergeOp>(op.getLoc(), dataResult.getType(),
op.dataOperands());
auto merge = rewriter.create<MergeOp>(op.getLoc(), op.dataOperands());
for (auto &use : dataResult.getUses()) {
auto *user = use.getOwner();
@ -643,7 +807,7 @@ void handshake::BranchOp::build(OpBuilder &builder, OperationState &result,
dataOperand == op->getResult(0))
? true
: false;
result.addAttribute("control", builder.getBoolAttr(isControl));
sost::addAttributes(result, 1, type, isControl);
}
void handshake::BranchOp::getCanonicalizationPatterns(
@ -665,6 +829,60 @@ bool handshake::BranchOp::tryExecute(
return tryToExecute(getOperation(), valueMap, timeMap, scheduleList, 0);
}
static ParseResult parseBranchOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
SmallVector<Type, 1> dataOperandsTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type,
/*explicitSize=*/false))
return failure();
dataOperandsTypes.assign(size, type);
result.addTypes({type});
if (parser.resolveOperands(allOperands, dataOperandsTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
static void printBranchOp(OpAsmPrinter &p, BranchOp op) {
sost::printOp(p, op, false);
}
static ParseResult parseConditionalBranchOp(OpAsmParser &parser,
OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type dataType;
SmallVector<Type> operandTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
if (parser.parseOperandList(allOperands) ||
parser.parseOptionalAttrDict(result.attributes) ||
parser.parseColonType(dataType))
return failure();
if (allOperands.size() != 2)
return parser.emitError(parser.getCurrentLocation(),
"Expected exactly 2 operands");
result.addTypes({dataType, dataType});
operandTypes.push_back(IntegerType::get(parser.getContext(), 1));
operandTypes.push_back(dataType);
if (parser.resolveOperands(allOperands, operandTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
static void printConditionalBranchOp(OpAsmPrinter &p, ConditionalBranchOp op) {
Type type = op.dataOperand().getType();
p << " " << op->getOperands();
p.printOptionalAttrDict((op)->getAttrs(), {"size", "dataType", "control"});
p << " : " << type;
}
std::string handshake::ConditionalBranchOp::getOperandName(unsigned int idx) {
assert(idx == 0 || idx == 1);
return idx == 0 ? "cond" : "data";
@ -691,7 +909,8 @@ void handshake::ConditionalBranchOp::build(OpBuilder &builder,
dataOperand == op->getResult(0))
? true
: false;
result.addAttribute("control", builder.getBoolAttr(isControl));
if (isControl)
result.addAttribute("control", builder.getBoolAttr(true));
}
bool handshake::ConditionalBranchOp::tryExecute(
@ -760,6 +979,26 @@ void handshake::ReturnOp::build(OpBuilder &builder, OperationState &result,
void SinkOp::build(OpBuilder &builder, OperationState &result, Value operand) {
result.addOperands(operand);
sost::addAttributes(result, 1, operand.getType());
}
static ParseResult parseSinkOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type, false))
return failure();
if (parser.resolveOperands(allOperands, operandTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
static void printSinkOp(OpAsmPrinter &p, SinkOp op) {
sost::printOp(p, op, false);
}
bool handshake::SinkOp::tryExecute(
@ -811,8 +1050,36 @@ void handshake::TerminatorOp::build(OpBuilder &builder, OperationState &result,
ArrayRef<Block *> successors) {
// Add all the successor blocks of the block which contains this terminator
result.addSuccessors(successors);
// for (auto &succ : successors)
// result.addSuccessor(succ, {});
}
void handshake::BufferOp::build(OpBuilder &builder, OperationState &result,
Type innerType, int size, Value operand,
bool sequential) {
result.addOperands(operand);
sost::addAttributes(result, size, innerType);
result.addTypes({innerType});
result.addAttribute("sequential",
BoolAttr::get(builder.getContext(), sequential));
}
static ParseResult parseBufferOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type, true))
return failure();
result.addTypes({type});
if (parser.resolveOperands(allOperands, operandTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
static void printBufferOp(OpAsmPrinter &p, BufferOp op) {
sost::printOp(p, op, true);
}
static std::string getMemoryOperandName(unsigned nStores, unsigned idx) {
@ -829,7 +1096,7 @@ static std::string getMemoryOperandName(unsigned nStores, unsigned idx) {
}
std::string handshake::MemoryOp::getOperandName(unsigned int idx) {
return getMemoryOperandName(getStCount().getZExtValue(), idx);
return getMemoryOperandName(stCount(), idx);
}
static std::string getMemoryResultName(unsigned nLoads, unsigned nStores,
@ -845,12 +1112,11 @@ static std::string getMemoryResultName(unsigned nLoads, unsigned nStores,
}
std::string handshake::MemoryOp::getResultName(unsigned int idx) {
return getMemoryResultName(getLdCount().getZExtValue(),
getStCount().getZExtValue(), idx);
return getMemoryResultName(ldCount(), stCount(), idx);
}
static LogicalResult verifyMemoryOp(handshake::MemoryOp op) {
auto memrefType = op.getMemRefType();
auto memrefType = op.memRefType();
if (memrefType.getNumDynamicDims() != 0)
return op.emitOpError()
@ -858,6 +1124,66 @@ static LogicalResult verifyMemoryOp(handshake::MemoryOp op) {
if (memrefType.getShape().size() != 1)
return op.emitOpError() << "memref must have only a single dimension.";
unsigned stCount = op.stCount();
unsigned ldCount = op.ldCount();
int addressCount = memrefType.getShape().size();
auto inputType = op.inputs().getType();
auto outputType = op.outputs().getType();
Type dataType = memrefType.getElementType();
unsigned numOperands = static_cast<int>(op.inputs().size());
unsigned numResults = static_cast<int>(op.outputs().size());
if (numOperands != (1 + addressCount) * stCount + addressCount * ldCount)
return op.emitOpError("number of operands ")
<< numOperands << " does not match number expected of "
<< 2 * stCount + ldCount << " with " << addressCount
<< " address inputs per port";
if (numResults != stCount + 2 * ldCount)
return op.emitOpError("number of results ")
<< numResults << " does not match number expected of "
<< stCount + 2 * ldCount << " with " << addressCount
<< " address inputs per port";
Type addressType = stCount > 0 ? inputType[1] : inputType[0];
for (unsigned i = 0; i < stCount; i++) {
if (inputType[2 * i] != dataType)
return op.emitOpError("data type for store port ")
<< i << ":" << inputType[2 * i] << " doesn't match memory type "
<< dataType;
if (inputType[2 * i + 1] != addressType)
return op.emitOpError("address type for store port ")
<< i << ":" << inputType[2 * i + 1]
<< " doesn't match address type " << addressType;
}
for (unsigned i = 0; i < ldCount; i++) {
Type ldAddressType = inputType[2 * stCount + i];
if (ldAddressType != addressType)
return op.emitOpError("address type for load port ")
<< i << ":" << ldAddressType << " doesn't match address type "
<< addressType;
}
for (unsigned i = 0; i < ldCount; i++) {
if (outputType[i] != dataType)
return op.emitOpError("data type for load port ")
<< i << ":" << outputType[i] << " doesn't match memory type "
<< dataType;
}
for (unsigned i = 0; i < stCount; i++) {
Type syncType = outputType[ldCount + i];
if (!syncType.isa<NoneType>())
return op.emitOpError("data type for sync port for store port ")
<< i << ":" << syncType << " is not 'none'";
}
for (unsigned i = 0; i < ldCount; i++) {
Type syncType = outputType[ldCount + stCount + i];
if (!syncType.isa<NoneType>())
return op.emitOpError("data type for sync port for load port ")
<< i << ":" << syncType << " is not 'none'";
}
return success();
}
@ -918,22 +1244,17 @@ void MemoryOp::build(OpBuilder &builder, OperationState &result,
// Control outputs
result.types.append(control_outputs, builder.getNoneType());
// Indicates whether a memory is an LSQ
result.addAttribute("lsq", builder.getBoolAttr(lsq));
// Memref info
result.addAttribute("type", TypeAttr::get(memrefType));
result.addAttribute("memRefType", TypeAttr::get(memrefType));
// Memory ID (individual ID for each MemoryOp)
Type i32Type = builder.getIntegerType(32);
result.addAttribute("id", builder.getIntegerAttr(i32Type, id));
if (!lsq) {
result.addAttribute("ld_count", builder.getIntegerAttr(i32Type, outputs));
result.addAttribute("ldCount", builder.getIntegerAttr(i32Type, outputs));
result.addAttribute(
"st_count", builder.getIntegerAttr(i32Type, control_outputs - outputs));
"stCount", builder.getIntegerAttr(i32Type, control_outputs - outputs));
}
}
@ -941,11 +1262,10 @@ bool handshake::MemoryOp::allocateMemory(
llvm::DenseMap<unsigned, unsigned> &memoryMap,
std::vector<std::vector<llvm::Any>> &store,
std::vector<double> &storeTimes) {
unsigned id = getID();
if (memoryMap.count(id))
if (memoryMap.count(id()))
return false;
auto type = getMemRefType();
auto type = memRefType();
std::vector<llvm::Any> in;
ArrayRef<int64_t> shape = type.getShape();
@ -976,7 +1296,7 @@ bool handshake::MemoryOp::allocateMemory(
}
}
memoryMap[id] = ptr;
memoryMap[id()] = ptr;
return true;
}
@ -989,13 +1309,12 @@ bool handshake::MemoryOp::tryExecute(
auto op = getOperation();
int opIndex = 0;
bool notReady = false;
unsigned id = getID(); // The ID of this memory.
unsigned buffer = memoryMap[id];
unsigned buffer = memoryMap[id()];
for (unsigned i = 0; i < getStCount().getZExtValue(); i++) {
for (unsigned i = 0; i < stCount(); i++) {
mlir::Value data = op->getOperand(opIndex++);
mlir::Value address = op->getOperand(opIndex++);
mlir::Value nonceOut = op->getResult(getLdCount().getZExtValue() + i);
mlir::Value nonceOut = op->getResult(ldCount() + i);
if ((!valueMap.count(data) || !valueMap.count(address))) {
notReady = true;
continue;
@ -1022,11 +1341,10 @@ bool handshake::MemoryOp::tryExecute(
valueMap.erase(address);
}
for (unsigned i = 0; i < getLdCount().getZExtValue(); i++) {
for (unsigned i = 0; i < ldCount(); i++) {
mlir::Value address = op->getOperand(opIndex++);
mlir::Value dataOut = op->getResult(i);
mlir::Value nonceOut = op->getResult(getLdCount().getZExtValue() +
getStCount().getZExtValue() + i);
mlir::Value nonceOut = op->getResult(ldCount() + stCount() + i);
if (!valueMap.count(address)) {
notReady = true;
continue;
@ -1052,6 +1370,27 @@ bool handshake::MemoryOp::tryExecute(
return (notReady) ? false : true;
}
std::string handshake::LoadOp::getOperandName(unsigned int idx) {
unsigned nAddresses = addresses().size();
std::string opName;
if (idx < nAddresses)
opName = "addrIn" + std::to_string(idx);
else if (idx == nAddresses)
opName = "dataFromMem";
else
opName = "ctrl";
return opName;
}
std::string handshake::LoadOp::getResultName(unsigned int idx) {
std::string resName;
if (idx == 0)
resName = "dataOut";
else
resName = "addrOut" + std::to_string(idx - 1);
return resName;
}
void handshake::LoadOp::build(OpBuilder &builder, OperationState &result,
Value memref, ArrayRef<Value> indices) {
// Address indices
@ -1068,6 +1407,49 @@ void handshake::LoadOp::build(OpBuilder &builder, OperationState &result,
result.types.append(indices.size(), builder.getIndexType());
}
static ParseResult parseMemoryAccessOp(OpAsmParser &parser,
OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> addressOperands, remainingOperands,
allOperands;
SmallVector<Type, 1> parsedTypes, allTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
if (parser.parseLSquare() || parser.parseOperandList(addressOperands) ||
parser.parseRSquare() || parser.parseOperandList(remainingOperands) ||
parser.parseColon() || parser.parseTypeList(parsedTypes))
return failure();
// The last type will be the data type of the operation; the prior will be the
// address types.
Type dataType = parsedTypes.back();
auto parsedTypesRef = llvm::makeArrayRef(parsedTypes);
result.addTypes(dataType);
result.addTypes(parsedTypesRef.drop_back());
allOperands.append(addressOperands);
allOperands.append(remainingOperands);
allTypes.append(parsedTypes);
allTypes.push_back(NoneType::get(result.getContext()));
if (parser.resolveOperands(allOperands, allTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
template <typename MemOp>
static void printMemoryAccessOp(OpAsmPrinter &p, MemOp op) {
p << " [";
p << op.addresses();
p << "] " << op.data() << ", " << op.ctrl() << " : ";
llvm::interleaveComma(op.addresses(), p, [&](Value v) { p << v.getType(); });
p << ", " << op.data().getType();
}
static ParseResult parseLoadOp(OpAsmParser &parser, OperationState &result) {
return parseMemoryAccessOp(parser, result);
}
void printLoadOp(OpAsmPrinter &p, LoadOp op) { printMemoryAccessOp(p, op); }
bool handshake::LoadOp::tryExecute(
llvm::DenseMap<mlir::Value, llvm::Any> &valueMap,
llvm::DenseMap<unsigned, unsigned> &memoryMap,
@ -1111,14 +1493,36 @@ bool handshake::LoadOp::tryExecute(
return true;
}
std::string handshake::StoreOp::getOperandName(unsigned int idx) {
unsigned nAddresses = addresses().size();
std::string opName;
if (idx < nAddresses)
opName = "addrIn" + std::to_string(idx);
else if (idx == nAddresses)
opName = "dataIn";
else
opName = "ctrl";
return opName;
}
std::string handshake::StoreOp::getResultName(unsigned int idx) {
std::string resName;
if (idx == 0)
resName = "dataToMem";
else
resName = "addrOut" + std::to_string(idx - 1);
return resName;
}
void handshake::StoreOp::build(OpBuilder &builder, OperationState &result,
Value valueToStore, ArrayRef<Value> indices) {
// Data
result.addOperands(valueToStore);
// Address indices
result.addOperands(indices);
// Data
result.addOperands(valueToStore);
// Data output (from store to LSQ)
result.types.push_back(valueToStore.getType());
@ -1129,8 +1533,16 @@ void handshake::StoreOp::build(OpBuilder &builder, OperationState &result,
void handshake::StoreOp::execute(std::vector<llvm::Any> &ins,
std::vector<llvm::Any> &outs) {
// Forward the address and data to the memory op.
outs[0] = ins[0];
outs[1] = ins[1];
outs[0] = ins[1];
outs[1] = ins[0];
}
static ParseResult parseStoreOp(OpAsmParser &parser, OperationState &result) {
return parseMemoryAccessOp(parser, result);
}
static void printStoreOp(OpAsmPrinter &p, StoreOp &op) {
return printMemoryAccessOp(p, op);
}
bool handshake::StoreOp::tryExecute(
@ -1148,10 +1560,29 @@ void JoinOp::build(OpBuilder &builder, OperationState &result,
result.types.push_back(type);
result.addOperands(operands);
result.addAttribute("control", builder.getBoolAttr(true));
sost::addAttributes(result, operands.size(), type);
}
static ParseResult parseJoinOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 4> allOperands;
Type type;
ArrayRef<Type> operandTypes(type);
SmallVector<Type, 1> dataOperandsTypes;
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
int size;
if (sost::parseOperation(parser, allOperands, result, size, type, false))
return failure();
dataOperandsTypes.assign(size, type);
result.addTypes({type});
if (parser.resolveOperands(allOperands, dataOperandsTypes, allOperandLoc,
result.operands))
return failure();
return success();
}
void printJoinOp(OpAsmPrinter &p, JoinOp op) { sost::printOp(p, op, false); }
void handshake::JoinOp::execute(std::vector<llvm::Any> &ins,
std::vector<llvm::Any> &outs) {
outs[0] = ins[0];
@ -1181,25 +1612,6 @@ static LogicalResult verifyInstanceOp(handshake::InstanceOp op) {
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
// Code below is largely duplicated from Standard/Ops.cpp
static ParseResult parseReturnOp(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::OperandType, 2> opInfo;
SmallVector<Type, 2> types;
llvm::SMLoc loc = parser.getCurrentLocation();
return failure(parser.parseOperandList(opInfo) ||
(!opInfo.empty() && parser.parseColonTypeList(types)) ||
parser.resolveOperands(opInfo, types, loc, result.operands));
}
static void printReturnOp(OpAsmPrinter &p, handshake::ReturnOp op) {
if (op.getNumOperands() != 0) {
p << ' ';
p.printOperands(op.getOperands());
p << " : ";
interleaveComma(op.getOperandTypes(), p);
}
}
static LogicalResult verify(handshake::ReturnOp op) {
auto *parent = op->getParentOp();
auto function = dyn_cast<handshake::FuncOp>(parent);

View File

@ -5,17 +5,17 @@
module {
handshake.func @bar(%ctrl : none) -> (none) {
%0 = handshake.instance @baz(%ctrl) : (none) -> (none)
handshake.return %0: none
return %0: none
}
handshake.func @foo(%ctrl : none) -> (none) {
%0 = handshake.instance @bar(%ctrl) : (none) -> (none)
handshake.return %0: none
return %0: none
}
handshake.func @baz(%ctrl : none) -> (none) {
%0 = handshake.instance @foo(%ctrl) : (none) -> (none)
handshake.return %0: none
return %0: none
}
}
@ -26,15 +26,15 @@ module {
module {
handshake.func @bar(%ctrl : none) -> (none) {
%0 = handshake.instance @baz(%ctrl) : (none) -> (none)
handshake.return %0: none
return %0: none
}
handshake.func @foo(%ctrl : none) -> (none) {
%0 = handshake.instance @baz(%ctrl) : (none) -> (none)
handshake.return %0: none
return %0: none
}
handshake.func @baz(%ctrl : none) -> (none) {
handshake.return %ctrl: none
return %ctrl: none
}
}

View File

@ -28,5 +28,5 @@
// CHECK: }
handshake.func @simple_addi(%arg0: index, %arg1: index, %arg2: none, ...) -> (index, none) {
%0 = arith.addi %arg0, %arg1 : index
handshake.return %0, %arg2 : index, none
return %0, %arg2 : index, none
}

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -lower-handshake-to-firrtl %s | FileCheck %s
// CHECK: firrtl.module @handshake_branch_in_ui64_out_ui64(in %[[VAL_0:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_1:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) {
// CHECK: firrtl.module @handshake_br_in_ui64_out_ui64(in %[[VAL_0:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_1:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) {
// CHECK: %[[VAL_2:.*]] = firrtl.subfield %[[VAL_0]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_3:.*]] = firrtl.subfield %[[VAL_0]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_4:.*]] = firrtl.subfield %[[VAL_0]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<64>
@ -12,8 +12,8 @@
// CHECK: firrtl.connect %[[VAL_7]], %[[VAL_4]] : !firrtl.uint<64>, !firrtl.uint<64>
// CHECK: }
// CHECK: firrtl.module @test_branch(in %[[VAL_8:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_9:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_10:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_11:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_12:.*]]: !firrtl.clock, in %[[VAL_13:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = firrtl.instance handshake_branch0 @handshake_branch_in_ui64_out_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = firrtl.instance handshake_br0 @handshake_br_in_ui64_out_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
handshake.func @test_branch(%arg0: index, %arg1: none, ...) -> (index, none) {
%0 = "handshake.branch"(%arg0) {control = false}: (index) -> index
handshake.return %0, %arg1 : index, none
%0 = br %arg0 : index
return %0, %arg1 : index, none
}

View File

@ -83,8 +83,8 @@
// CHECK: firrtl.connect %[[VAL_63]], %[[VAL_61]] : !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>
// CHECK: }
handshake.func @test_buffer(%arg0: none, %arg1: none, ...) -> (none, none) {
%0 = "handshake.buffer"(%arg0) {control = true, sequential = true, slots = 3 : i32} : (none) -> none
handshake.return %0, %arg1 : none, none
%0 = buffer [3] %arg0 {sequential = true} : none
return %0, %arg1 : none, none
}
// -----
@ -126,6 +126,6 @@ handshake.func @test_buffer(%arg0: none, %arg1: none, ...) -> (none, none) {
// CHECK: firrtl.connect %[[VAL_67]], %[[VAL_65]] : !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>
// CHECK: }
handshake.func @test_buffer_data(%arg0: index, %arg1: none, ...) -> (index, none) {
%0 = "handshake.buffer"(%arg0) {control = false, sequential = true, slots = 2 : i32} : (index) -> index
handshake.return %0, %arg1 : index, none
%0 = buffer [2] %arg0 {sequential = true} : index
return %0, %arg1 : index, none
}

View File

@ -89,8 +89,8 @@
// 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 = "handshake.control_merge"(%arg0, %arg1) {control = true} : (none, none) -> (none, index)
handshake.return %0#0, %0#1, %arg2 : none, index, none
%0:2 = control_merge %arg0, %arg1 : none
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 = "handshake.control_merge"(%arg0, %arg1) {control = false} : (index, index) -> (index, index)
handshake.return %0#0, %0#1, %arg2 : index, index, none
%0:2 = control_merge %arg0, %arg1 : index
return %0#0, %0#1, %arg2 : index, index, none
}

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -lower-handshake-to-firrtl %s | FileCheck %s
// CHECK-LABEL: firrtl.module @handshake_conditional_branch_in_ui1_ui64_out_ui64_ui64(
// CHECK-LABEL: firrtl.module @handshake_cond_br_in_ui1_ui64_out_ui64_ui64(
// CHECK-SAME: in %[[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>, in %[[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) {
// CHECK: %0 = firrtl.subfield %[[ARG0]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>) -> !firrtl.uint<1>
// CHECK: %1 = firrtl.subfield %[[ARG0]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>) -> !firrtl.uint<1>
@ -29,8 +29,8 @@
// CHECK: }
// CHECK: firrtl.module @test_conditional_branch(in %[[VAL_22:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>, in %[[VAL_23:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_24:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_25:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_26:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_27:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_28:.*]]: !firrtl.clock, in %[[VAL_29:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]], %[[VAL_32:.*]], %[[VAL_33:.*]] = firrtl.instance handshake_conditional_branch0 @handshake_conditional_branch_in_ui1_ui64_out_ui64_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]], %[[VAL_32:.*]], %[[VAL_33:.*]] = firrtl.instance handshake_cond_br0 @handshake_cond_br_in_ui1_ui64_out_ui64_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
handshake.func @test_conditional_branch(%arg0: i1, %arg1: index, %arg2: none, ...) -> (index, index, none) {
%0:2 = "handshake.conditional_branch"(%arg0, %arg1) {control = false}: (i1, index) -> (index, index)
handshake.return %0#0, %0#1, %arg2 : index, index, none
%0:2 = cond_br %arg0, %arg1 : index
return %0#0, %0#1, %arg2 : index, index, none
}

View File

@ -31,10 +31,10 @@
// CHECK: %[[VAL_117:.*]], %[[VAL_118:.*]] = firrtl.instance handshake_constant2 @handshake_constant_c42_out_ui32(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>)
// CHECK: %[[VAL_119:.*]], %[[VAL_120:.*]] = firrtl.instance handshake_constant3 @"handshake_constant_c-11_out_si32"(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: sint<32>>)
handshake.func @test_constant(%arg0: none, ...) -> (index, i64, ui32, si32, none) {
%0:5 = "handshake.fork"(%arg0) {control = true} : (none) -> (none, none, none, none, none)
%1 = "handshake.constant"(%0#0) {value = 42 : index}: (none) -> index
%2 = "handshake.constant"(%0#1) {value = 42 : i64}: (none) -> i64
%3 = "handshake.constant"(%0#2) {value = 42 : ui32}: (none) -> ui32
%4 = "handshake.constant"(%0#3) {value = -11 : si32}: (none) -> si32
handshake.return %1, %2, %3, %4, %0#4 : index, i64, ui32, si32, none
%0:5 = fork [5] %arg0 : none
%1 = constant %0#0 {value = 42 : index} : index
%2 = constant %0#1 {value = 42 : i64} : i64
%3 = constant %0#2 {value = 42 : ui32} : ui32
%4 = constant %0#3 {value = -11 : si32} : si32
return %1, %2, %3, %4, %0#4 : index, i64, ui32, si32, none
}

View File

@ -62,10 +62,10 @@
handshake.func @main(%arg0: index, %arg1: index, %v: i32, %mem : memref<10xi32>, %argCtrl: none) -> none {
%ldData, %stCtrl, %ldCtrl = handshake.extmemory[ld=1, st=1](%mem : memref<10xi32>)(%storeData, %storeAddr, %loadAddr) {id = 0 : i32} : (i32, index, index) -> (i32, none, none)
%fCtrl:2 = "handshake.fork"(%argCtrl) {control = true} : (none) -> (none, none)
%loadData, %loadAddr = "handshake.load"(%arg0, %ldData, %fCtrl#0) : (index, i32, none) -> (i32, index)
%storeData, %storeAddr = "handshake.store"(%v, %arg1, %fCtrl#1) : (i32, index, none) -> (i32, index)
"handshake.sink"(%loadData) : (i32) -> ()
%finCtrl = "handshake.join"(%stCtrl, %ldCtrl) {control = true} : (none, none) -> none
handshake.return %finCtrl : none
%fCtrl:2 = fork [2] %argCtrl : none
%loadData, %loadAddr = load [%arg0] %ldData, %fCtrl#0 : index, i32
%storeData, %storeAddr = store [%arg1] %v, %fCtrl#1 : index, i32
sink %loadData : i32
%finCtrl = join %stCtrl, %ldCtrl : none
return %finCtrl : none
}

View File

@ -63,8 +63,8 @@
// CHECK: firrtl.module @test_fork(in %[[VAL_34:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_35:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_36:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_37:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_38:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_39:.*]]: !firrtl.clock, in %[[VAL_40:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]], %[[VAL_43:.*]], %[[VAL_44:.*]], %[[VAL_45:.*]] = firrtl.instance handshake_fork0 @handshake_fork_1ins_2outs_ctrl(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in clock: !firrtl.clock, in reset: !firrtl.uint<1>)
handshake.func @test_fork(%arg0: none, %arg1: none, ...) -> (none, none, none) {
%0:2 = "handshake.fork"(%arg0) {control = true} : (none) -> (none, none)
handshake.return %0#0, %0#1, %arg1 : none, none, none
%0:2 = fork [2] %arg0 : none
return %0#0, %0#1, %arg1 : none, none, none
}
// -----
@ -81,6 +81,6 @@ handshake.func @test_fork(%arg0: none, %arg1: none, ...) -> (none, none, none) {
// CHECK: firrtl.module @test_fork_data(in %[[VAL_37:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_38:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_39:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_40:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_41:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_42:.*]]: !firrtl.clock, in %[[VAL_43:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]], %[[VAL_46:.*]], %[[VAL_47:.*]], %[[VAL_48:.*]] = firrtl.instance handshake_fork0 @handshake_fork_in_ui64_out_ui64_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in clock: !firrtl.clock, in reset: !firrtl.uint<1>)
handshake.func @test_fork_data(%arg0: index, %arg1: none, ...) -> (index, index, none) {
%0:2 = "handshake.fork"(%arg0) {control = false} : (index) -> (index, index)
handshake.return %0#0, %0#1, %arg1 : index, index, none
%0:2 = fork [2] %arg0 : index
return %0#0, %0#1, %arg1 : index, index, none
}

View File

@ -22,7 +22,7 @@
// CHECK: }
handshake.func @test_index_cast(%arg0: index, %arg1: none, ...) -> (i8, none) {
%0 = arith.index_cast %arg0 : index to i8
handshake.return %0, %arg1 : i8, none
return %0, %arg1 : i8, none
}
// -----
@ -66,5 +66,5 @@ handshake.func @test_index_cast(%arg0: index, %arg1: none, ...) -> (i8, none) {
handshake.func @test_index_cast2(%arg0: i8, %arg1 : i9, %arg2: none, ...) -> (index, index, none) {
%0 = arith.index_cast %arg0 : i8 to index
%1 = arith.index_cast %arg1 : i9 to index
handshake.return %0, %1, %arg2 : index, index, none
return %0, %1, %arg2 : index, index, none
}

View File

@ -39,18 +39,18 @@
module {
handshake.func @baz(%a: i32, %ctrl : none) -> (i32, none) {
%0 = arith.addi %a, %a : i32
handshake.return %0, %ctrl : i32, none
return %0, %ctrl : i32, none
}
handshake.func @bar(%a: i32, %ctrl : none) -> (i32, none) {
%c:2 = handshake.instance @baz(%a, %ctrl) : (i32, none) -> (i32, none)
"handshake.sink"(%c#1) {control = true} : (none) -> ()
handshake.return %c#0, %ctrl : i32, none
%c, %ctrlOut = handshake.instance @baz(%a, %ctrl) : (i32, none) -> (i32, none)
sink %ctrlOut : none
return %c, %ctrl : i32, none
}
handshake.func @foo(%a: i32, %ctrl : none) -> (i32, none) {
%b:2 = handshake.instance @bar(%a, %ctrl) : (i32, none) -> (i32, none)
"handshake.sink"(%b#1) {control = true} : (none) -> ()
handshake.return %b#0, %ctrl : i32, none
sink %b#1 : none
return %b#0, %ctrl : i32, none
}
}

View File

@ -17,6 +17,6 @@
// CHECK: firrtl.module @test_join(in %[[VAL_11:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_12:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_13:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_14:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_15:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_16:.*]]: !firrtl.clock, in %[[VAL_17:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]], %[[VAL_20:.*]] = firrtl.instance handshake_join0 @handshake_join_2ins_1outs_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>>)
handshake.func @test_join(%arg0: none, %arg1: none, %arg2: none, ...) -> (none, none) {
%0 = "handshake.join"(%arg0, %arg1) {control = true}: (none, none) -> none
handshake.return %0, %arg2 : none, none
%0 = join %arg0, %arg1 : none
return %0, %arg2 : none, none
}

View File

@ -28,6 +28,6 @@
// CHECK: }
// CHECK: }
handshake.func @test_lazy_fork(%arg0: index, %arg1: none, ...) -> (index, index, none) {
%0:2 = "handshake.lazy_fork"(%arg0) {control = false} : (index) -> (index, index)
handshake.return %0#0, %0#1, %arg1 : index, index, none
%0:2 = lazy_fork [2] %arg0 : index
return %0#0, %0#1, %arg1 : index, index, none
}

View File

@ -1,43 +1,38 @@
// RUN: circt-opt -lower-handshake-to-firrtl -split-input-file -verify-diagnostics %s
// CHECK-LABEL: firrtl.module @handshake_load_3ins_2outs_ui8(
// CHECK-SAME: %arg0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<64>>, %arg1: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<8>>, %arg2: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>>, %arg3: !firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<8>>>, %arg4: !firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<64>>>) {
// CHECK: %[[IADDR_VALID:.+]] = firrtl.subfield %[[ARG0]]("valid") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[IADDR_READY:.+]] = firrtl.subfield %[[ARG0]]("ready") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[IADDR_DATA:.+]] = firrtl.subfield %[[ARG0]]("data") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<64>>) -> !firrtl.uint<64>
// CHECK: %[[MDATA_VALID:.+]] = firrtl.subfield %[[ARG1]]("valid") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[MDATA_READY:.+]] = firrtl.subfield %[[ARG1]]("ready") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[MDATA_DATA:.+]] = firrtl.subfield %[[ARG1]]("data") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, data: uint<8>>) -> !firrtl.uint<8>
// CHECK: %[[CTRL_VALID:.+]] = firrtl.subfield %[[ARG2]]("valid") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>>) -> !firrtl.uint<1>
// CHECK: %[[CTRL_READY:.+]] = firrtl.subfield %[[ARG2]]("ready") : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>>) -> !firrtl.uint<1>
// CHECK: %[[ODATA_VALID:.+]] = firrtl.subfield %[[ARG3]]("valid") : (!firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<8>>>) -> !firrtl.uint<1>
// CHECK: %[[ODATA_READY:.+]] = firrtl.subfield %[[ARG3]]("ready") : (!firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<8>>>) -> !firrtl.uint<1>
// CHECK: %[[ODATA_DATA:.+]] = firrtl.subfield %[[ARG3]]("data") : (!firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<8>>>) -> !firrtl.uint<8>
// CHECK: %[[MADDR_VALID:.+]] = firrtl.subfield %[[ARG4]]("valid") : (!firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<64>>>) -> !firrtl.uint<1>
// CHECK: %[[MADDR_READY:.+]] = firrtl.subfield %[[ARG4]]("ready") : (!firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<64>>>) -> !firrtl.uint<1>
// CHECK: %[[MADDR_DATA:.+]] = firrtl.subfield %[[ARG4]]("data") : (!firrtl.bundle<valid flip: uint<1>>, ready: uint<1>, data: flip<uint<64>>>) -> !firrtl.uint<64>
// CHECK: firrtl.connect %[[MADDR_DATA:.+]], %[[IADDR_DATA:.+]] : !firrtl.uint<64>, !firrtl.uint<64>
// CHECK: firrtl.connect %[[ODATA_DATA:.+]], %[[MDATA_DATA:.+]] : !firrtl.uint<8>, !firrtl.uint<8>
// CHECK: %14 = firrtl.and %[[IADDR_VALID:.+]], %[[CTRL_VALID:.+]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: firrtl.connect %[[MADDR_VALID:.+]], %14 : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: %15 = firrtl.and %14, %[[MADDR_READY:.+]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: firrtl.connect %[[IADDR_READY:.+]], %15 : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[CTRL_READY:.+]], %15 : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[ODATA_VALID:.+]], %[[MDATA_VALID:.+]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[MDATA_READY:.+]], %[[ODATA_READY:.+]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: }
// CHECK: firrtl.module @handshake_load_in_ui64_ui8_out_ui8_ui64(in %[[VAL_87:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_88:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in %[[VAL_89:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_90:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out %[[VAL_91:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) {
// CHECK: %[[VAL_92:.*]] = firrtl.subfield %[[VAL_87]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_93:.*]] = firrtl.subfield %[[VAL_87]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_94:.*]] = firrtl.subfield %[[VAL_87]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<64>
// CHECK: %[[VAL_95:.*]] = firrtl.subfield %[[VAL_88]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_96:.*]] = firrtl.subfield %[[VAL_88]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_97:.*]] = firrtl.subfield %[[VAL_88]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<8>
// CHECK: %[[VAL_98:.*]] = firrtl.subfield %[[VAL_89]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_99:.*]] = firrtl.subfield %[[VAL_89]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_100:.*]] = firrtl.subfield %[[VAL_90]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_101:.*]] = firrtl.subfield %[[VAL_90]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_102:.*]] = firrtl.subfield %[[VAL_90]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<8>
// CHECK: %[[VAL_103:.*]] = firrtl.subfield %[[VAL_91]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_104:.*]] = firrtl.subfield %[[VAL_91]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_105:.*]] = firrtl.subfield %[[VAL_91]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<64>
// CHECK: firrtl.connect %[[VAL_105]], %[[VAL_94]] : !firrtl.uint<64>, !firrtl.uint<64>
// CHECK: firrtl.connect %[[VAL_102]], %[[VAL_97]] : !firrtl.uint<8>, !firrtl.uint<8>
// CHECK: %[[VAL_106:.*]] = firrtl.and %[[VAL_92]], %[[VAL_98]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_103]], %[[VAL_106]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: %[[VAL_107:.*]] = firrtl.and %[[VAL_106]], %[[VAL_104]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_93]], %[[VAL_107]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_99]], %[[VAL_107]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_100]], %[[VAL_95]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_96]], %[[VAL_101]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: }
// CHECK: firrtl.module @main(in %[[VAL_111:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_112:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_113:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_114:.*]]: !firrtl.clock, in %[[VAL_115:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_129:.*]], %[[VAL_130:.*]], %[[VAL_131:.*]], %[[VAL_132:.*]], %[[VAL_133:.*]] = firrtl.instance handshake_load0 @handshake_load_in_ui64_ui8_out_ui8_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out [[ARG4:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
// CHECK: %[[VAL_116:.*]], %[[VAL_117:.*]], %[[VAL_118:.*]], %[[VAL_119:.*]], %[[VAL_120:.*]] = firrtl.instance handshake_memory0 @handshake_memory_out_ui8_id0(in ldAddr0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out lddata0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out ldDone0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in clock: !firrtl.clock, in reset: !firrtl.uint<1>)
handshake.func @main(%arg0: index, %arg1: none, ...) -> none {
%0:2 = "handshake.memory"(%addressResults) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 0 : i32, type = memref<10xi8>} : (index) -> (i8, none)
%1:2 = "handshake.fork"(%arg1) {control = true} : (none) -> (none, none)
%2 = "handshake.join"(%1#1, %0#1) {control = true} : (none, none) -> none
%3, %addressResults = "handshake.load"(%arg0, %0#0, %1#0) : (index, i8, none) -> (i8, index)
"handshake.sink"(%3) : (i8) -> ()
handshake.return %2 : none
%0:2 = memory [ld = 1, st= 0] (%addressResults) {id = 0 : i32, lsq = false} : memref<10xi8>, (index) -> (i8, none)
%1:2 = fork [2] %arg1 : none
%2 = join %1#1, %0#1 : none
%3, %addressResults = load [%arg0] %0#0, %1#0 : index, i8
sink %3 : i8
return %2 : none
}

View File

@ -98,6 +98,6 @@
// CHECK: firrtl.module @main(in %[[VAL_69:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in %[[VAL_70:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_71:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_72:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out %[[VAL_73:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_74:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_75:.*]]: !firrtl.clock, in %[[VAL_76:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]], %[[VAL_79:.*]], %[[VAL_80:.*]], %[[VAL_81:.*]], %[[VAL_82:.*]], %[[VAL_83:.*]], %[[VAL_84:.*]] = firrtl.instance handshake_memory0 @handshake_memory_out_ui8_id0(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out [[ARG4:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG5:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in clock: !firrtl.clock, in reset: !firrtl.uint<1>)
handshake.func @main(%arg0: i8, %arg1: index, %arg2: index, ...) -> (i8, none, none) {
%0:3 = "handshake.memory"(%arg0, %arg1, %arg2) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xi8>} : (i8, index, index) -> (i8, none, none)
handshake.return %0#0, %0#1, %0#2: i8, none, none
%0:3 = memory [ld = 1, st = 1] (%arg0, %arg1, %arg2) {id = 0 : i32, lsq = false} : memref<10xi8>, (i8, index, index) -> (i8, none, none)
return %0#0, %0#1, %0#2: i8, none, none
}

View File

@ -53,6 +53,6 @@
// CHECK: firrtl.module @test_merge(in %[[VAL_29:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_30:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_31:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_32:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_33:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_34:.*]]: !firrtl.clock, in %[[VAL_35:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]], %[[VAL_38:.*]] = firrtl.instance handshake_merge0 @handshake_merge_in_ui64_ui64_out_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
handshake.func @test_merge(%arg0: index, %arg1: index, %arg2: none, ...) -> (index, none) {
%0 = "handshake.merge"(%arg0, %arg1) : (index, index) -> index
handshake.return %0, %arg2 : index, none
%0 = merge %arg0, %arg1 : index
return %0, %arg2 : index, none
}

View File

@ -36,8 +36,8 @@
// CHECK: firrtl.module @test_mux(in %[[VAL_29:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_30:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_31:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_32:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_33:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_34:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_35:.*]]: !firrtl.clock, in %[[VAL_36:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]], %[[VAL_39:.*]], %[[VAL_40:.*]] = firrtl.instance handshake_mux0 @handshake_mux_in_ui64_ui64_ui64_out_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
handshake.func @test_mux(%arg0: index, %arg1: index, %arg2: index, %arg3: none, ...) -> (index, none) {
%0 = "handshake.mux"(%arg0, %arg1, %arg2): (index, index, index) -> index
handshake.return %0, %arg3 : index, none
%0 = mux %arg0 [%arg1, %arg2] : index, index
return %0, %arg3 : index, none
}
// -----
@ -53,8 +53,8 @@ handshake.func @test_mux(%arg0: index, %arg1: index, %arg2: index, %arg3: none,
// CHECK: %[[MUX2:.+]] = firrtl.mux({{.+}}, %[[DATA3]], %[[MUX1]])
// CHECK: firrtl.connect %[[RESULT]], %[[MUX2]]
handshake.func @test_mux_3way(%arg0: index, %arg1: index, %arg2: index, %arg3: index, %arg4: none, ...) -> (index, none) {
%0 = "handshake.mux"(%arg0, %arg1, %arg2, %arg3): (index, index, index, index) -> index
handshake.return %0, %arg4 : index, none
%0 = mux %arg0 [%arg1, %arg2, %arg3] : index, index
return %0, %arg4 : index, none
}
// -----
@ -80,8 +80,8 @@ handshake.func @test_mux_3way(%arg0: index, %arg1: index, %arg2: index, %arg3: i
// CHECK: %[[MUX7:.+]] = firrtl.mux({{.+}}, %[[MUX6]], %[[MUX5]])
// CHECK: firrtl.connect %[[RESULT]], %[[MUX7]]
handshake.func @test_mux_8way(%arg0: index, %arg1: index, %arg2: index, %arg3: index, %arg4: index, %arg5: index, %arg6: index, %arg7: index, %arg8: index, %arg9: none, ...) -> (index, none) {
%0 = "handshake.mux"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8): (index, index, index, index, index, index, index, index, index) -> index
handshake.return %0, %arg9 : index, none
%0 = mux %arg0 [%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8] : index, index
return %0, %arg9 : index, none
}
// -----
@ -101,8 +101,8 @@ handshake.func @test_mux_8way(%arg0: index, %arg1: index, %arg2: index, %arg3: i
// CHECK: %[[MUX4:.+]] = firrtl.mux({{.+}}, %[[DATA5]], %[[MUX3]])
// CHECK: firrtl.connect %[[RESULT]], %[[MUX4]]
handshake.func @test_mux_5way(%arg0: index, %arg1: index, %arg2: index, %arg3: index, %arg4: index, %arg5: index, %arg6: none, ...) -> (index, none) {
%0 = "handshake.mux"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5): (index, index, index, index, index, index) -> index
handshake.return %0, %arg6 : index, none
%0 = mux %arg0 [%arg1, %arg2, %arg3, %arg4, %arg5] : index, index
return %0, %arg6 : index, none
}
// -----
@ -124,6 +124,6 @@ handshake.func @test_mux_5way(%arg0: index, %arg1: index, %arg2: index, %arg3: i
// CHECK: %[[MUX5:.+]] = firrtl.mux({{.+}}, %[[MUX3]], %[[MUX4]])
// CHECK: firrtl.connect %[[RESULT]], %[[MUX5]]
handshake.func @test_mux_6way(%arg0: index, %arg1: index, %arg2: index, %arg3: index, %arg4: index, %arg5: index, %arg6: index, %arg7: none, ...) -> (index, none) {
%0 = "handshake.mux"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6): (index, index, index, index, index, index, index) -> index
handshake.return %0, %arg7 : index, none
%0 = mux %arg0 [%arg1, %arg2, %arg3, %arg4, %arg5, %arg6] : index, index
return %0, %arg7 : index, none
}

View File

@ -10,7 +10,7 @@
// CHECK: in %reset: !firrtl.uint<1>) {
handshake.func @main(%a: index, %b: index, %inCtrl: none, ...) -> (index, none) {
%0 = arith.addi %a, %b : index
handshake.return %0, %inCtrl : index, none
return %0, %inCtrl : index, none
}
// -----
@ -25,7 +25,7 @@ handshake.func @main(%a: index, %b: index, %inCtrl: none, ...) -> (index, none)
// CHECK: in %reset: !firrtl.uint<1>) {
handshake.func @main(%a: index, %b: index, %inCtrl: none, ...) -> (index, none) attributes {argNames = ["aTest", "bTest", "cTest"], resNames = ["outTest", "coutTest"]} {
%0 = arith.addi %a, %b : index
handshake.return %0, %inCtrl : index, none
return %0, %inCtrl : index, none
}
@ -40,8 +40,8 @@ handshake.func @main(%a: index, %b: index, %inCtrl: none, ...) -> (index, none)
// CHECK-LABEL: firrtl.module @test_mux(
// CHECK: %handshake_mux0_select, %handshake_mux0_in0, %handshake_mux0_in1, %handshake_mux0_out0 = firrtl.instance handshake_mux0 @handshake_mux_in_ui64_ui64_ui64_out_ui64(in select: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in in0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in in1: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out out0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
handshake.func @test_mux(%arg0: index, %arg1: index, %arg2: index, %arg3: none, ...) -> (index, none) {
%0 = "handshake.mux"(%arg0, %arg1, %arg2): (index, index, index) -> index
handshake.return %0, %arg3 : index, none
%0 = mux %arg0 [%arg1, %arg2] : index, index
return %0, %arg3 : index, none
}
// -----
@ -50,8 +50,8 @@ handshake.func @test_mux(%arg0: index, %arg1: index, %arg2: index, %arg3: none,
// sure that we generate meaningful names for them.
// CHECK-LABEL: firrtl.module @main(
// CHECK: in %arg0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>,
// CHECK: in %arg1: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>,
// CHECK: in %ldAddr: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>,
// CHECK: in %stAddr: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>,
// CHECK: in %v: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>,
// CHECK: in %mem: !firrtl.bundle<
// CHECK: stData0 flip: bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>,
@ -66,12 +66,12 @@ handshake.func @test_mux(%arg0: index, %arg1: index, %arg2: index, %arg3: none,
// CHECK: in %reset: !firrtl.uint<1>) {
// CHECK: %handshake_extmemory0_extmem, %handshake_extmemory0_stData0, %handshake_extmemory0_stAddr0, %handshake_extmemory0_ldAddr0, %handshake_extmemory0_lddata0, %handshake_extmemory0_stDone0, %handshake_extmemory0_ldDone0 = firrtl.instance handshake_extmemory0 @handshake_extmemory_in_ui32_ui64_ui64_out_ui32(in extmem: !firrtl.bundle<stData0 flip: bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>, stAddr0 flip: bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, ldAddr0 flip: bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, lddata0: bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>, stDone0: bundle<valid: uint<1>, ready flip: uint<1>>, ldDone0: bundle<valid: uint<1>, ready flip: uint<1>>>, in stData0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>, in stAddr0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in ldAddr0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out lddata0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>, out stDone0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out ldDone0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>)
handshake.func @main(%arg0: index, %arg1: index, %v: i32, %mem : memref<10xi32>, %argCtrl: none) -> none {
handshake.func @main(%ldAddr: index, %stAddr: index, %v: i32, %mem : memref<10xi32>, %argCtrl: none) -> none {
%ldData, %stCtrl, %ldCtrl = handshake.extmemory[ld=1, st=1](%mem : memref<10xi32>)(%storeData, %storeAddr, %loadAddr) {id = 0 : i32} : (i32, index, index) -> (i32, none, none)
%fCtrl:2 = "handshake.fork"(%argCtrl) {control = true} : (none) -> (none, none)
%loadData, %loadAddr = "handshake.load"(%arg0, %ldData, %fCtrl#0) : (index, i32, none) -> (i32, index)
%storeData, %storeAddr = "handshake.store"(%v, %arg1, %fCtrl#1) : (i32, index, none) -> (i32, index)
"handshake.sink"(%loadData) : (i32) -> ()
%finCtrl = "handshake.join"(%stCtrl, %ldCtrl) {control = true} : (none, none) -> none
handshake.return %finCtrl : none
%fCtrl:2 = fork [2] %argCtrl : none
%loadData, %loadAddr = load [%ldAddr] %ldData, %fCtrl#0 : index, i32
%storeData, %storeAddr = store [%stAddr] %v, %fCtrl#1 : index, i32
sink %loadData : i32
%finCtrl = join %stCtrl, %ldCtrl : none
return %finCtrl : none
}

View File

@ -14,6 +14,6 @@
// CHECK: }
// CHECK: }
handshake.func @test_sink(%arg0: index, %arg1: none, ...) -> (none) {
"handshake.sink"(%arg0) : (index) -> ()
handshake.return %arg1 : none
sink %arg0 : index
return %arg1 : none
}

View File

@ -1,45 +1,38 @@
// RUN: circt-opt -lower-handshake-to-firrtl -split-input-file %s | FileCheck %s
// CHECK: firrtl.module @handshake_store_in_ui8_ui64_out_ui8_ui64(in %[[VAL_0:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in %[[VAL_1:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_2:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_3:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out %[[VAL_4:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) {
// CHECK: %[[IN_DATA_VALID:.+]] = firrtl.subfield %[[VAL_0]](0)
// CHECK: %[[IN_DATA_READY:.+]] = firrtl.subfield %[[VAL_0]](1)
// CHECK: %[[IN_DATA_DATA:.+]] = firrtl.subfield %[[VAL_0]](2)
// CHECK: %[[IN_ADDR_VALID:.+]] = firrtl.subfield %[[VAL_1]](0)
// CHECK: %[[IN_ADDR_READY:.+]] = firrtl.subfield %[[VAL_1]](1)
// CHECK: %[[IN_ADDR_DATA:.+]] = firrtl.subfield %[[VAL_1]](2)
// CHECK: %[[IN_CONTROL_VALID:.+]] = firrtl.subfield %[[VAL_2]](0)
// CHECK: %[[IN_CONTROL_READY:.+]] = firrtl.subfield %[[VAL_2]](1)
// CHECK: %[[OUT_DATA_VALID:.+]] = firrtl.subfield %[[VAL_3]](0)
// CHECK: %[[OUT_DATA_READY:.+]] = firrtl.subfield %[[VAL_3]](1)
// CHECK: %[[OUT_DATA_DATA:.+]] = firrtl.subfield %[[VAL_3]](2)
// CHECK: %[[OUT_ADDR_VALID:.+]] = firrtl.subfield %[[VAL_4]](0)
// CHECK: %[[OUT_ADDR_READY:.+]] = firrtl.subfield %[[VAL_4]](1)
// CHECK: %[[OUT_ADDR_DATA:.+]] = firrtl.subfield %[[VAL_4]](2)
// CHECK: %[[ALL_VALID_WIRE:inputsValid]] = firrtl.wire : !firrtl.uint<1>
// CHECK: %[[ALL_READY:.+]] = firrtl.and %[[OUT_DATA_READY]], %[[OUT_ADDR_READY]]
// CHECK: %[[ALL_VALID0:.+]] = firrtl.and %[[IN_ADDR_VALID]], %[[IN_DATA_VALID]]
// CHECK: %[[ALL_VALID:.+]] = firrtl.and %[[IN_CONTROL_VALID]], %[[ALL_VALID0]]
// CHECK: firrtl.connect %[[ALL_VALID_WIRE]], %[[ALL_VALID]]
// CHECK: %[[ALL_DONE:.+]] = firrtl.and %[[ALL_READY]], %[[ALL_VALID]]
// CHECK: firrtl.connect %[[IN_DATA_READY]], %[[ALL_DONE]]
// CHECK: firrtl.connect %[[IN_ADDR_READY]], %[[ALL_DONE]]
// CHECK: firrtl.connect %[[IN_CONTROL_READY]], %[[ALL_DONE]]
// CHECK: firrtl.connect %[[OUT_ADDR_DATA]], %[[IN_ADDR_DATA]]
// CHECK: firrtl.connect %[[OUT_DATA_DATA]], %[[IN_DATA_DATA]]
// CHECK: firrtl.connect %[[OUT_DATA_VALID]], %[[ALL_VALID_WIRE]]
// CHECK: firrtl.connect %[[OUT_ADDR_VALID]], %[[ALL_VALID_WIRE]]
// CHECK: firrtl.module @handshake_store_in_ui64_ui8_out_ui8_ui64(in %[[VAL_0:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_1:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in %[[VAL_2:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_3:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out %[[VAL_4:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) {
// CHECK: %[[VAL_5:.*]] = firrtl.subfield %[[VAL_0]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_6:.*]] = firrtl.subfield %[[VAL_0]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_7:.*]] = firrtl.subfield %[[VAL_0]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<64>
// CHECK: %[[VAL_8:.*]] = firrtl.subfield %[[VAL_1]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_9:.*]] = firrtl.subfield %[[VAL_1]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_10:.*]] = firrtl.subfield %[[VAL_1]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<8>
// CHECK: %[[VAL_11:.*]] = firrtl.subfield %[[VAL_2]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_12:.*]] = firrtl.subfield %[[VAL_2]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_13:.*]] = firrtl.subfield %[[VAL_3]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_14:.*]] = firrtl.subfield %[[VAL_3]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_15:.*]] = firrtl.subfield %[[VAL_3]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>) -> !firrtl.uint<8>
// CHECK: %[[VAL_16:.*]] = firrtl.subfield %[[VAL_4]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_17:.*]] = firrtl.subfield %[[VAL_4]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<1>
// CHECK: %[[VAL_18:.*]] = firrtl.subfield %[[VAL_4]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>) -> !firrtl.uint<64>
// CHECK: %[[VAL_19:.*]] = firrtl.wire : !firrtl.uint<1>
// CHECK: %[[VAL_20:.*]] = firrtl.and %[[VAL_14]], %[[VAL_17]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: %[[VAL_21:.*]] = firrtl.and %[[VAL_5]], %[[VAL_8]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: %[[VAL_22:.*]] = firrtl.and %[[VAL_11]], %[[VAL_21]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_19]], %[[VAL_22]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: %[[VAL_23:.*]] = firrtl.and %[[VAL_20]], %[[VAL_22]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_9]], %[[VAL_23]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_6]], %[[VAL_23]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_12]], %[[VAL_23]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_18]], %[[VAL_7]] : !firrtl.uint<64>, !firrtl.uint<64>
// CHECK: firrtl.connect %[[VAL_15]], %[[VAL_10]] : !firrtl.uint<8>, !firrtl.uint<8>
// CHECK: firrtl.connect %[[VAL_13]], %[[VAL_19]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: firrtl.connect %[[VAL_16]], %[[VAL_19]] : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: }
// CHECK: firrtl.module @main(in %[[VAL_24:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in %[[VAL_25:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in %[[VAL_26:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_27:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out %[[VAL_28:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, out %[[VAL_29:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_30:.*]]: !firrtl.clock, in %[[VAL_31:.*]]: !firrtl.uint<1>) {
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]], %[[VAL_34:.*]], %[[VAL_35:.*]], %[[VAL_36:.*]] = firrtl.instance handshake_store0 @handshake_store_in_ui8_ui64_out_ui8_ui64(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG3:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out [[ARG4:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]], %[[VAL_34:.*]], %[[VAL_35:.*]], %[[VAL_36:.*]] = firrtl.instance handshake_store0 @handshake_store_in_ui64_ui8_out_ui8_ui64(in addrIn0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>, in dataIn: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, in ctrl: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out dataToMem: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<8>>, out addrOut0: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<64>>)
handshake.func @main(%arg0: i8, %arg1: index, %arg2: none, ...) -> (i8, index, none) {
%0:2 = "handshake.store"(%arg0, %arg1, %arg2) : (i8, index, none) -> (i8, index)
handshake.return %0#0, %0#1, %arg2 : i8, index, none
%0:2 = store [%arg1] %arg0, %arg2 : index, i8
return %0#0, %0#1, %arg2 : i8, index, none
}

View File

@ -4,65 +4,124 @@
// Simple affine.for with an empty loop body.
// CHECK-LABEL: handshake.func @empty_body(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_5:.*]] = br %[[VAL_1]]#3 : none
// CHECK: %[[VAL_6:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_3]] : index
// CHECK: %[[VAL_8:.*]] = br %[[VAL_4]] : index
// CHECK: %[[VAL_9:.*]] = mux %[[VAL_10:.*]]#2 {{\[}}%[[VAL_7]], %[[VAL_11:.*]]] : index, index
// CHECK: %[[VAL_12:.*]]:2 = fork [2] %[[VAL_9]] : index
// CHECK: %[[VAL_13:.*]] = mux %[[VAL_10]]#1 {{\[}}%[[VAL_8]], %[[VAL_14:.*]]] : index, index
// CHECK: %[[VAL_15:.*]], %[[VAL_16:.*]] = control_merge %[[VAL_5]], %[[VAL_17:.*]] : none
// CHECK: %[[VAL_10]]:3 = fork [3] %[[VAL_16]] : index
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_10]]#0 {{\[}}%[[VAL_6]], %[[VAL_19:.*]]] : index, index
// CHECK: %[[VAL_20:.*]]:2 = fork [2] %[[VAL_18]] : index
// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_20]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_22:.*]]:4 = fork [4] %[[VAL_21]] : i1
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = cond_br %[[VAL_22]]#3, %[[VAL_12]]#0 : index
// CHECK: sink %[[VAL_24]] : index
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = cond_br %[[VAL_22]]#2, %[[VAL_13]] : index
// CHECK: sink %[[VAL_26]] : index
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = cond_br %[[VAL_22]]#1, %[[VAL_15]] : none
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = cond_br %[[VAL_22]]#0, %[[VAL_20]]#0 : index
// CHECK: sink %[[VAL_30]] : index
// CHECK: %[[VAL_31:.*]] = merge %[[VAL_29]] : index
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_25]] : index
// CHECK: %[[VAL_33:.*]] = merge %[[VAL_23]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_27]] : none
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_36:.*]] = br %[[VAL_31]] : index
// CHECK: %[[VAL_37:.*]] = br %[[VAL_32]] : index
// CHECK: %[[VAL_38:.*]] = br %[[VAL_33]] : index
// CHECK: %[[VAL_39:.*]] = br %[[VAL_34]] : none
// CHECK: %[[VAL_40:.*]] = merge %[[VAL_36]] : index
// CHECK: %[[VAL_41:.*]] = merge %[[VAL_37]] : index
// CHECK: %[[VAL_42:.*]]:2 = fork [2] %[[VAL_41]] : index
// CHECK: %[[VAL_43:.*]] = merge %[[VAL_38]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = control_merge %[[VAL_39]] : none
// CHECK: sink %[[VAL_45]] : index
// CHECK: %[[VAL_46:.*]] = arith.addi %[[VAL_40]], %[[VAL_42]]#1 : index
// CHECK: %[[VAL_14]] = br %[[VAL_42]]#0 : index
// CHECK: %[[VAL_11]] = br %[[VAL_43]] : index
// CHECK: %[[VAL_17]] = br %[[VAL_44]] : none
// CHECK: %[[VAL_19]] = br %[[VAL_46]] : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge %[[VAL_28]] : none
// CHECK: sink %[[VAL_48]] : index
// CHECK: return %[[VAL_47]] : none
// CHECK: }
func @empty_body () -> () {
affine.for %i = 0 to 10 { }
return
}
// CHECK: handshake.func @empty_body(%arg0: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %0:4 = "handshake.fork"(%arg0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %1 = "handshake.constant"(%0#2) {value = 0 : index} : (none) -> index
// CHECK: %2 = "handshake.constant"(%0#1) {value = 10 : index} : (none) -> index
// CHECK: %3 = "handshake.constant"(%0#0) {value = 1 : index} : (none) -> index
// CHECK: %4 = "handshake.branch"(%0#3) {control = true} : (none) -> none
// CHECK: %5 = "handshake.branch"(%1) {control = false} : (index) -> index
// CHECK: %6 = "handshake.branch"(%2) {control = false} : (index) -> index
// CHECK: %7 = "handshake.branch"(%3) {control = false} : (index) -> index
// CHECK: %8 = "handshake.mux"(%12#2, %6, %32) : (index, index, index) -> index
// CHECK: %9:2 = "handshake.fork"(%8) {control = false} : (index) -> (index, index)
// CHECK: %10 = "handshake.mux"(%12#1, %7, %31) : (index, index, index) -> index
// CHECK: %11:2 = "handshake.control_merge"(%4, %33) {control = true} : (none, none) -> (none, index)
// CHECK: %12:3 = "handshake.fork"(%11#1) {control = false} : (index) -> (index, index, index)
// CHECK: %13 = "handshake.mux"(%12#0, %5, %34) : (index, index, index) -> index
// CHECK: %14:2 = "handshake.fork"(%13) {control = false} : (index) -> (index, index)
// CHECK: %15 = arith.cmpi slt, %14#1, %9#1 : index
// CHECK: %16:4 = "handshake.fork"(%15) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %trueResult, %falseResult = "handshake.conditional_branch"(%16#3, %9#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%falseResult) : (index) -> ()
// CHECK: %trueResult_0, %falseResult_1 = "handshake.conditional_branch"(%16#2, %10) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%falseResult_1) : (index) -> ()
// CHECK: %trueResult_2, %falseResult_3 = "handshake.conditional_branch"(%16#1, %11#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %trueResult_4, %falseResult_5 = "handshake.conditional_branch"(%16#0, %14#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%falseResult_5) : (index) -> ()
// CHECK: %17 = "handshake.merge"(%trueResult_4) : (index) -> index
// CHECK: %18 = "handshake.merge"(%trueResult_0) : (index) -> index
// CHECK: %19 = "handshake.merge"(%trueResult) : (index) -> index
// CHECK: %20:2 = "handshake.control_merge"(%trueResult_2) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%20#1) : (index) -> ()
// CHECK: %21 = "handshake.branch"(%17) {control = false} : (index) -> index
// CHECK: %22 = "handshake.branch"(%18) {control = false} : (index) -> index
// CHECK: %23 = "handshake.branch"(%19) {control = false} : (index) -> index
// CHECK: %24 = "handshake.branch"(%20#0) {control = true} : (none) -> none
// CHECK: %25 = "handshake.merge"(%21) : (index) -> index
// CHECK: %26 = "handshake.merge"(%22) : (index) -> index
// CHECK: %27:2 = "handshake.fork"(%26) {control = false} : (index) -> (index, index)
// CHECK: %28 = "handshake.merge"(%23) : (index) -> index
// CHECK: %29:2 = "handshake.control_merge"(%24) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%29#1) : (index) -> ()
// CHECK: %30 = arith.addi %25, %27#1 : index
// CHECK: %31 = "handshake.branch"(%27#0) {control = false} : (index) -> index
// CHECK: %32 = "handshake.branch"(%28) {control = false} : (index) -> index
// CHECK: %33 = "handshake.branch"(%29#0) {control = true} : (none) -> none
// CHECK: %34 = "handshake.branch"(%30) {control = false} : (index) -> index
// CHECK: %35:2 = "handshake.control_merge"(%falseResult_3) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%35#1) : (index) -> ()
// CHECK: handshake.return %35#0 : none
// CHECK: }
// -----
// Simple load store pair in the loop body.
// CHECK-LABEL: handshake.func @load_store(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_5:.*]]:2 = fork [2] %[[VAL_1]]#2 : none
// CHECK: %[[VAL_6:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_6]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_6]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_6]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_10:.*]] = br %[[VAL_6]]#3 : none
// CHECK: %[[VAL_11:.*]] = br %[[VAL_7]] : index
// CHECK: %[[VAL_12:.*]] = br %[[VAL_8]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_9]] : index
// CHECK: %[[VAL_14:.*]] = mux %[[VAL_15:.*]]#2 {{\[}}%[[VAL_12]], %[[VAL_16:.*]]] : index, index
// CHECK: %[[VAL_17:.*]]:2 = fork [2] %[[VAL_14]] : index
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_15]]#1 {{\[}}%[[VAL_13]], %[[VAL_19:.*]]] : index, index
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = control_merge %[[VAL_10]], %[[VAL_22:.*]] : none
// CHECK: %[[VAL_15]]:3 = fork [3] %[[VAL_21]] : index
// CHECK: %[[VAL_23:.*]] = mux %[[VAL_15]]#0 {{\[}}%[[VAL_11]], %[[VAL_24:.*]]] : index, index
// CHECK: %[[VAL_25:.*]]:2 = fork [2] %[[VAL_23]] : index
// CHECK: %[[VAL_26:.*]] = arith.cmpi slt, %[[VAL_25]]#1, %[[VAL_17]]#1 : index
// CHECK: %[[VAL_27:.*]]:4 = fork [4] %[[VAL_26]] : i1
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = cond_br %[[VAL_27]]#3, %[[VAL_17]]#0 : index
// CHECK: sink %[[VAL_29]] : index
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = cond_br %[[VAL_27]]#2, %[[VAL_18]] : index
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = cond_br %[[VAL_27]]#1, %[[VAL_20]] : none
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = cond_br %[[VAL_27]]#0, %[[VAL_25]]#0 : index
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_36:.*]] = merge %[[VAL_34]] : index
// CHECK: %[[VAL_37:.*]]:3 = fork [3] %[[VAL_36]] : index
// CHECK: %[[VAL_38:.*]] = merge %[[VAL_30]] : index
// CHECK: %[[VAL_39:.*]] = merge %[[VAL_28]] : index
// CHECK: %[[VAL_40:.*]], %[[VAL_41:.*]] = control_merge %[[VAL_32]] : none
// CHECK: %[[VAL_42:.*]]:3 = fork [3] %[[VAL_40]] : none
// CHECK: %[[VAL_43:.*]] = join %[[VAL_42]]#2, %[[VAL_5]]#1, %[[VAL_1]]#1 : none
// CHECK: sink %[[VAL_41]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_37]]#2] %[[VAL_1]]#0, %[[VAL_42]]#1 : index, f32
// CHECK: %[[VAL_45:.*]] = join %[[VAL_42]]#0, %[[VAL_5]]#0 : none
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_37]]#1] %[[VAL_44]], %[[VAL_45]] : index, f32
// CHECK: %[[VAL_46:.*]] = br %[[VAL_37]]#0 : index
// CHECK: %[[VAL_47:.*]] = br %[[VAL_38]] : index
// CHECK: %[[VAL_48:.*]] = br %[[VAL_39]] : index
// CHECK: %[[VAL_49:.*]] = br %[[VAL_43]] : none
// CHECK: %[[VAL_50:.*]] = merge %[[VAL_46]] : index
// CHECK: %[[VAL_51:.*]] = merge %[[VAL_47]] : index
// CHECK: %[[VAL_52:.*]]:2 = fork [2] %[[VAL_51]] : index
// CHECK: %[[VAL_53:.*]] = merge %[[VAL_48]] : index
// CHECK: %[[VAL_54:.*]], %[[VAL_55:.*]] = control_merge %[[VAL_49]] : none
// CHECK: sink %[[VAL_55]] : index
// CHECK: %[[VAL_56:.*]] = arith.addi %[[VAL_50]], %[[VAL_52]]#1 : index
// CHECK: %[[VAL_19]] = br %[[VAL_52]]#0 : index
// CHECK: %[[VAL_16]] = br %[[VAL_53]] : index
// CHECK: %[[VAL_22]] = br %[[VAL_54]] : none
// CHECK: %[[VAL_24]] = br %[[VAL_56]] : index
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = control_merge %[[VAL_33]] : none
// CHECK: sink %[[VAL_58]] : index
// CHECK: return %[[VAL_57]] : none
// CHECK: }
func @load_store () -> () {
%A = memref.alloc() : memref<10xf32>
affine.for %i = 0 to 10 {
@ -72,63 +131,6 @@ func @load_store () -> () {
return
}
// CHECK: handshake.func @load_store(%arg0: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %0:3 = "handshake.memory"(%28#0, %28#1, %addressResults) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK: %1:2 = "handshake.fork"(%0#2) {control = true} : (none) -> (none, none)
// CHECK: %2:4 = "handshake.fork"(%arg0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %3 = "handshake.constant"(%2#2) {value = 0 : index} : (none) -> index
// CHECK: %4 = "handshake.constant"(%2#1) {value = 10 : index} : (none) -> index
// CHECK: %5 = "handshake.constant"(%2#0) {value = 1 : index} : (none) -> index
// CHECK: %6 = "handshake.branch"(%2#3) {control = true} : (none) -> none
// CHECK: %7 = "handshake.branch"(%3) {control = false} : (index) -> index
// CHECK: %8 = "handshake.branch"(%4) {control = false} : (index) -> index
// CHECK: %9 = "handshake.branch"(%5) {control = false} : (index) -> index
// CHECK: %10 = "handshake.mux"(%14#2, %8, %40) : (index, index, index) -> index
// CHECK: %11:2 = "handshake.fork"(%10) {control = false} : (index) -> (index, index)
// CHECK: %12 = "handshake.mux"(%14#1, %9, %39) : (index, index, index) -> index
// CHECK: %13:2 = "handshake.control_merge"(%6, %41) {control = true} : (none, none) -> (none, index)
// CHECK: %14:3 = "handshake.fork"(%13#1) {control = false} : (index) -> (index, index, index)
// CHECK: %15 = "handshake.mux"(%14#0, %7, %42) : (index, index, index) -> index
// CHECK: %16:2 = "handshake.fork"(%15) {control = false} : (index) -> (index, index)
// CHECK: %17 = arith.cmpi slt, %16#1, %11#1 : index
// CHECK: %18:4 = "handshake.fork"(%17) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %trueResult, %falseResult = "handshake.conditional_branch"(%18#3, %11#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%falseResult) : (index) -> ()
// CHECK: %trueResult_0, %falseResult_1 = "handshake.conditional_branch"(%18#2, %12) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%falseResult_1) : (index) -> ()
// CHECK: %trueResult_2, %falseResult_3 = "handshake.conditional_branch"(%18#1, %13#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %trueResult_4, %falseResult_5 = "handshake.conditional_branch"(%18#0, %16#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%falseResult_5) : (index) -> ()
// CHECK: %19 = "handshake.merge"(%trueResult_4) : (index) -> index
// CHECK: %20:3 = "handshake.fork"(%19) {control = false} : (index) -> (index, index, index)
// CHECK: %21 = "handshake.merge"(%trueResult_0) : (index) -> index
// CHECK: %22 = "handshake.merge"(%trueResult) : (index) -> index
// CHECK: %23:2 = "handshake.control_merge"(%trueResult_2) {control = true} : (none) -> (none, index)
// CHECK: %24:3 = "handshake.fork"(%23#0) {control = true} : (none) -> (none, none, none)
// CHECK: %25 = "handshake.join"(%24#2, %1#1, %0#1) {control = true} : (none, none, none) -> none
// CHECK: "handshake.sink"(%23#1) : (index) -> ()
// CHECK: %26, %addressResults = "handshake.load"(%20#2, %0#0, %24#1) : (index, f32, none) -> (f32, index)
// CHECK: %27 = "handshake.join"(%24#0, %1#0) {control = true} : (none, none) -> none
// CHECK: %28:2 = "handshake.store"(%26, %20#1, %27) : (f32, index, none) -> (f32, index)
// CHECK: %29 = "handshake.branch"(%20#0) {control = false} : (index) -> index
// CHECK: %30 = "handshake.branch"(%21) {control = false} : (index) -> index
// CHECK: %31 = "handshake.branch"(%22) {control = false} : (index) -> index
// CHECK: %32 = "handshake.branch"(%25) {control = true} : (none) -> none
// CHECK: %33 = "handshake.merge"(%29) : (index) -> index
// CHECK: %34 = "handshake.merge"(%30) : (index) -> index
// CHECK: %35:2 = "handshake.fork"(%34) {control = false} : (index) -> (index, index)
// CHECK: %36 = "handshake.merge"(%31) : (index) -> index
// CHECK: %37:2 = "handshake.control_merge"(%32) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%37#1) : (index) -> ()
// CHECK: %38 = arith.addi %33, %35#1 : index
// CHECK: %39 = "handshake.branch"(%35#0) {control = false} : (index) -> index
// CHECK: %40 = "handshake.branch"(%36) {control = false} : (index) -> index
// CHECK: %41 = "handshake.branch"(%37#0) {control = true} : (none) -> none
// CHECK: %42 = "handshake.branch"(%38) {control = false} : (index) -> index
// CHECK: %43:2 = "handshake.control_merge"(%falseResult_3) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%43#1) : (index) -> ()
// CHECK: handshake.return %43#0 : none
// CHECK: }
// TODO: affine expr in loop bounds
// TODO: nested loops

View File

@ -4,6 +4,20 @@
// Simple load-store pair that has WAR dependence using constant address.
// CHECK-LABEL: handshake.func @load_store(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_5:.*]]:2 = fork [2] %[[VAL_1]]#2 : none
// CHECK: %[[VAL_6:.*]]:3 = fork [3] %[[VAL_0]] : none
// CHECK: %[[VAL_7:.*]]:2 = fork [2] %[[VAL_6]]#2 : none
// CHECK: %[[VAL_8:.*]] = join %[[VAL_7]]#1, %[[VAL_5]]#1, %[[VAL_1]]#1 : none
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_7]]#0 {value = 0 : index} : index
// CHECK: %[[VAL_10:.*]]:2 = fork [2] %[[VAL_9]] : index
// CHECK: %[[VAL_11:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_10]]#0] %[[VAL_1]]#0, %[[VAL_6]]#1 : index, f32
// CHECK: %[[VAL_12:.*]] = join %[[VAL_6]]#0, %[[VAL_5]]#0 : none
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_10]]#1] %[[VAL_11]], %[[VAL_12]] : index, f32
// CHECK: return %[[VAL_8]] : none
// CHECK: }
func @load_store () -> () {
%c0 = arith.constant 0 : index
%A = memref.alloc() : memref<10xf32>
@ -12,24 +26,29 @@ func @load_store () -> () {
return
}
// CHECK: handshake.func @load_store(%[[ARG0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL0:.*]]:3 = "handshake.memory"(%[[VAL9:.*]]#0, %[[VAL9]]#1, %[[ADDR:.*]]) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL1:.*]]:2 = "handshake.fork"(%[[VAL0]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL2:.*]]:3 = "handshake.fork"(%[[ARG0]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL3:.*]]:2 = "handshake.fork"(%[[VAL2]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL4:.*]] = "handshake.join"(%[[VAL3]]#1, %[[VAL1]]#1, %[[VAL0]]#1) {control = true} : (none, none, none) -> none
// CHECK: %[[VAL5:.*]] = "handshake.constant"(%[[VAL3]]#0) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL6:.*]]:2 = "handshake.fork"(%[[VAL5]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL7:.*]], %[[ADDR]] = "handshake.load"(%[[VAL6]]#0, %[[VAL0]]#0, %[[VAL2]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL8:.*]] = "handshake.join"(%[[VAL2]]#0, %[[VAL1]]#0) {control = true} : (none, none) -> none
// CHECK: %[[VAL9]]:2 = "handshake.store"(%[[VAL7]], %[[VAL6]]#1, %[[VAL8]]) : (f32, index, none) -> (f32, index)
// CHECK: handshake.return %[[VAL4]] : none
// CHECK: }
// -----
// Simple load-store pair that has WAR dependence with addresses in affine expressions.
// CHECK-LABEL: handshake.func @affine_map_addr(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_5:.*]]:2 = fork [2] %[[VAL_1]]#2 : none
// CHECK: %[[VAL_6:.*]]:3 = fork [3] %[[VAL_0]] : none
// CHECK: %[[VAL_7:.*]]:4 = fork [4] %[[VAL_6]]#2 : none
// CHECK: %[[VAL_8:.*]] = join %[[VAL_7]]#3, %[[VAL_5]]#1, %[[VAL_1]]#1 : none
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_7]]#2 {value = 5 : index} : index
// CHECK: %[[VAL_10:.*]]:2 = fork [2] %[[VAL_9]] : index
// CHECK: %[[VAL_11:.*]] = constant %[[VAL_7]]#1 {value = 1 : index} : index
// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_10]]#0, %[[VAL_11]] : index
// CHECK: %[[VAL_13:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_12]]] %[[VAL_1]]#0, %[[VAL_6]]#1 : index, f32
// CHECK: %[[VAL_14:.*]] = constant %[[VAL_7]]#0 {value = -1 : index} : index
// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_10]]#1, %[[VAL_14]] : index
// CHECK: %[[VAL_16:.*]] = join %[[VAL_6]]#0, %[[VAL_5]]#0 : none
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_15]]] %[[VAL_13]], %[[VAL_16]] : index, f32
// CHECK: return %[[VAL_8]] : none
// CHECK: }
func @affine_map_addr () -> () {
%c5 = arith.constant 5 : index
%A = memref.alloc() : memref<10xf32>
@ -38,20 +57,3 @@ func @affine_map_addr () -> () {
return
}
// CHECK: handshake.func @affine_map_addr(%[[ARG0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK-NEXT: %[[VAL0:.*]]:3 = "handshake.memory"(%[[VAL13:.*]]#0, %[[VAL13]]#1, %[[ADDR:.*]]) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK-NEXT: %[[VAL1:.*]]:2 = "handshake.fork"(%[[VAL0]]#2) {control = true} : (none) -> (none, none)
// CHECK-NEXT: %[[VAL2:.*]]:3 = "handshake.fork"(%[[ARG0]]) {control = true} : (none) -> (none, none, none)
// CHECK-NEXT: %[[VAL3:.*]]:4 = "handshake.fork"(%[[VAL2]]#2) {control = true} : (none) -> (none, none, none, none)
// CHECK-NEXT: %[[VAL4:.*]] = "handshake.join"(%[[VAL3]]#3, %[[VAL1]]#1, %[[VAL0]]#1) {control = true} : (none, none, none) -> none
// CHECK-NEXT: %[[VAL5:.*]] = "handshake.constant"(%[[VAL3]]#2) {value = 5 : index} : (none) -> index
// CHECK-NEXT: %[[VAL6:.*]]:2 = "handshake.fork"(%[[VAL5]]) {control = false} : (index) -> (index, index)
// CHECK-NEXT: %[[VAL7:.*]] = "handshake.constant"(%[[VAL3]]#1) {value = 1 : index} : (none) -> index
// CHECK-NEXT: %[[VAL8:.*]] = arith.addi %[[VAL6]]#0, %[[VAL7]] : index
// CHECK-NEXT: %[[VAL9:.*]], %[[ADDR]] = "handshake.load"(%[[VAL8]], %[[VAL0]]#0, %[[VAL2]]#1) : (index, f32, none) -> (f32, index)
// CHECK-NEXT: %[[VAL10:.*]] = "handshake.constant"(%[[VAL3]]#0) {value = -1 : index} : (none) -> index
// CHECK-NEXT: %[[VAL11:.*]] = arith.addi %[[VAL6]]#1, %[[VAL10]] : index
// CHECK-NEXT: %[[VAL12:.*]] = "handshake.join"(%[[VAL2]]#0, %[[VAL1]]#0) {control = true} : (none, none) -> none
// CHECK-NEXT: %[[VAL13]]:2 = "handshake.store"(%[[VAL9]], %[[VAL11]], %[[VAL12]]) : (f32, index, none) -> (f32, index)
// CHECK-NEXT: handshake.return %[[VAL4]] : none
// CHECK-NEXT: }

View File

@ -1,48 +1,44 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @simple_loop() {
// CHECK: module {
// CHECK-LABEL: handshake.func @simple_loop(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = "handshake.branch"(%[[VAL_0]]) {control = true} : (none) -> none
// CHECK: %[[VAL_2:.*]]:2 = "handshake.control_merge"(%[[VAL_1]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_2]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_2]]#1) : (index) -> ()
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_3]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.mux"(%[[VAL_10:.*]]#1, %[[VAL_11:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_14:.*]], %[[VAL_6]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_10]]:2 = "handshake.fork"(%[[VAL_13]]#1) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.mux"(%[[VAL_10]]#0, %[[VAL_16:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_15]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_17]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_19:.*]]:3 = "handshake.fork"(%[[VAL_18]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#2, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_21]]) : (index) -> ()
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#1, %[[VAL_13]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#0, %[[VAL_17]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_27:.*]] = "handshake.merge"(%[[VAL_20]]) : (index) -> index
// CHECK: %[[VAL_28:.*]]:2 = "handshake.control_merge"(%[[VAL_22]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_29:.*]]:2 = "handshake.fork"(%[[VAL_28]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_28]]#1) : (index) -> ()
// CHECK: %[[VAL_30:.*]] = "handshake.constant"(%[[VAL_29]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_31:.*]] = arith.addi %[[VAL_26]], %[[VAL_30]] : index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_27]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_29]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_31]]) {control = false} : (index) -> index
// CHECK: %[[VAL_32:.*]]:2 = "handshake.control_merge"(%[[VAL_23]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_32]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_32]]#0 : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:3 = fork [3] %[[VAL_2]] : none
// CHECK: sink %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#1 {value = 1 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_4]]#0 {value = 42 : index} : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_4]]#2 : none
// CHECK: %[[VAL_8:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_6]] : index
// CHECK: %[[VAL_10:.*]] = mux %[[VAL_11:.*]]#1 {{\[}}%[[VAL_12:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_13:.*]]:2 = fork [2] %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_16:.*]], %[[VAL_7]] : none
// CHECK: %[[VAL_11]]:2 = fork [2] %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]] = mux %[[VAL_11]]#0 {{\[}}%[[VAL_18:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_19:.*]]:2 = fork [2] %[[VAL_17]] : index
// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_19]]#1, %[[VAL_13]]#1 : index
// CHECK: %[[VAL_21:.*]]:3 = fork [3] %[[VAL_20]] : i1
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = cond_br %[[VAL_21]]#2, %[[VAL_13]]#0 : index
// CHECK: sink %[[VAL_23]] : index
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = cond_br %[[VAL_21]]#1, %[[VAL_14]] : none
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_21]]#0, %[[VAL_19]]#0 : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_29:.*]] = merge %[[VAL_22]] : index
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_24]] : none
// CHECK: %[[VAL_32:.*]]:2 = fork [2] %[[VAL_30]] : none
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_33:.*]] = constant %[[VAL_32]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_34:.*]] = arith.addi %[[VAL_28]], %[[VAL_33]] : index
// CHECK: %[[VAL_12]] = br %[[VAL_29]] : index
// CHECK: %[[VAL_16]] = br %[[VAL_32]]#1 : none
// CHECK: %[[VAL_18]] = br %[[VAL_34]] : index
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = control_merge %[[VAL_25]] : none
// CHECK: sink %[[VAL_36]] : index
// CHECK: return %[[VAL_35]] : none
// CHECK: }
// CHECK: }
func @simple_loop() {
^bb0:
br ^bb1
^bb1: // pred: ^bb0

View File

@ -1,106 +1,103 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_dma_start(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_dma_start(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:6 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none, none, none)
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:6 = fork [6] %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]] = memref.alloc() : memref<100xf32>
// CHECK: %[[VAL_5:.*]] = memref.alloc() : memref<100xf32, 2>
// CHECK: %[[VAL_6:.*]] = memref.alloc() : memref<1xi32>
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_3]]#4) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_3]]#3) {value = 64 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.constant"(%[[VAL_3]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_11:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (index) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.branch"(%[[VAL_3]]#5) {control = true} : (none) -> none
// CHECK: %[[VAL_14:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (memref<100xf32>) -> memref<100xf32>
// CHECK: %[[VAL_15:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (memref<100xf32, 2>) -> memref<100xf32, 2>
// CHECK: %[[VAL_16:.*]] = "handshake.branch"(%[[VAL_6]]) {control = false} : (memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_17:.*]] = "handshake.branch"(%[[VAL_7]]) {control = false} : (index) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_19:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_20:.*]] = "handshake.branch"(%[[VAL_10]]) {control = false} : (index) -> index
// CHECK: %[[VAL_21:.*]] = "handshake.branch"(%[[VAL_11]]) {control = false} : (index) -> index
// CHECK: %[[VAL_22:.*]] = "handshake.mux"(%[[VAL_23:.*]]#8, %[[VAL_24:.*]], %[[VAL_20]]) : (index, index, index) -> index
// CHECK: %[[VAL_25:.*]]:2 = "handshake.fork"(%[[VAL_22]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_26:.*]] = "handshake.mux"(%[[VAL_23]]#7, %[[VAL_27:.*]], %[[VAL_12]]) : (index, index, index) -> index
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_23]]#6, %[[VAL_29:.*]], %[[VAL_14]]) : (index, memref<100xf32>, memref<100xf32>) -> memref<100xf32>
// CHECK: %[[VAL_30:.*]] = "handshake.mux"(%[[VAL_23]]#5, %[[VAL_31:.*]], %[[VAL_15]]) : (index, memref<100xf32, 2>, memref<100xf32, 2>) -> memref<100xf32, 2>
// CHECK: %[[VAL_32:.*]] = "handshake.mux"(%[[VAL_23]]#4, %[[VAL_33:.*]], %[[VAL_18]]) : (index, index, index) -> index
// CHECK: %[[VAL_34:.*]] = "handshake.mux"(%[[VAL_23]]#3, %[[VAL_35:.*]], %[[VAL_16]]) : (index, memref<1xi32>, memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_36:.*]] = "handshake.mux"(%[[VAL_23]]#2, %[[VAL_37:.*]], %[[VAL_17]]) : (index, index, index) -> index
// CHECK: %[[VAL_38:.*]] = "handshake.mux"(%[[VAL_23]]#1, %[[VAL_39:.*]], %[[VAL_21]]) : (index, index, index) -> index
// CHECK: %[[VAL_40:.*]]:2 = "handshake.control_merge"(%[[VAL_41:.*]], %[[VAL_13]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_23]]:9 = "handshake.fork"(%[[VAL_40]]#1) {control = false} : (index) -> (index, index, index, index, index, index, index, index, index)
// CHECK: %[[VAL_42:.*]] = "handshake.mux"(%[[VAL_23]]#0, %[[VAL_43:.*]], %[[VAL_19]]) : (index, index, index) -> index
// CHECK: %[[VAL_44:.*]]:2 = "handshake.fork"(%[[VAL_42]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_45:.*]] = arith.cmpi slt, %[[VAL_44]]#1, %[[VAL_25]]#1 : index
// CHECK: %[[VAL_46:.*]]:10 = "handshake.fork"(%[[VAL_45]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#9, %[[VAL_25]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_48]]) : (index) -> ()
// CHECK: %[[VAL_49:.*]], %[[VAL_50:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#8, %[[VAL_26]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_50]]) : (index) -> ()
// CHECK: %[[VAL_51:.*]], %[[VAL_52:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#7, %[[VAL_28]]) {control = false} : (i1, memref<100xf32>) -> (memref<100xf32>, memref<100xf32>)
// CHECK: "handshake.sink"(%[[VAL_52]]) : (memref<100xf32>) -> ()
// CHECK: %[[VAL_53:.*]], %[[VAL_54:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#6, %[[VAL_30]]) {control = false} : (i1, memref<100xf32, 2>) -> (memref<100xf32, 2>, memref<100xf32, 2>)
// CHECK: "handshake.sink"(%[[VAL_54]]) : (memref<100xf32, 2>) -> ()
// CHECK: %[[VAL_55:.*]], %[[VAL_56:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#5, %[[VAL_32]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_56]]) : (index) -> ()
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#4, %[[VAL_34]]) {control = false} : (i1, memref<1xi32>) -> (memref<1xi32>, memref<1xi32>)
// CHECK: "handshake.sink"(%[[VAL_58]]) : (memref<1xi32>) -> ()
// CHECK: %[[VAL_59:.*]], %[[VAL_60:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#3, %[[VAL_36]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_60]]) : (index) -> ()
// CHECK: %[[VAL_61:.*]], %[[VAL_62:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#2, %[[VAL_38]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_62]]) : (index) -> ()
// CHECK: %[[VAL_63:.*]], %[[VAL_64:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#1, %[[VAL_40]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_65:.*]], %[[VAL_66:.*]] = "handshake.conditional_branch"(%[[VAL_46]]#0, %[[VAL_44]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_66]]) : (index) -> ()
// CHECK: %[[VAL_67:.*]] = "handshake.merge"(%[[VAL_65]]) : (index) -> index
// CHECK: %[[VAL_68:.*]]:2 = "handshake.fork"(%[[VAL_67]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_69:.*]] = "handshake.merge"(%[[VAL_49]]) : (index) -> index
// CHECK: %[[VAL_70:.*]]:2 = "handshake.fork"(%[[VAL_69]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_71:.*]] = "handshake.merge"(%[[VAL_51]]) : (memref<100xf32>) -> memref<100xf32>
// CHECK: %[[VAL_72:.*]]:2 = "handshake.fork"(%[[VAL_71]]) {control = false} : (memref<100xf32>) -> (memref<100xf32>, memref<100xf32>)
// CHECK: %[[VAL_73:.*]] = "handshake.merge"(%[[VAL_53]]) : (memref<100xf32, 2>) -> memref<100xf32, 2>
// CHECK: %[[VAL_74:.*]]:2 = "handshake.fork"(%[[VAL_73]]) {control = false} : (memref<100xf32, 2>) -> (memref<100xf32, 2>, memref<100xf32, 2>)
// CHECK: %[[VAL_75:.*]] = "handshake.merge"(%[[VAL_55]]) : (index) -> index
// CHECK: %[[VAL_76:.*]]:2 = "handshake.fork"(%[[VAL_75]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_77:.*]] = "handshake.merge"(%[[VAL_57]]) : (memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_78:.*]]:2 = "handshake.fork"(%[[VAL_77]]) {control = false} : (memref<1xi32>) -> (memref<1xi32>, memref<1xi32>)
// CHECK: %[[VAL_79:.*]] = "handshake.merge"(%[[VAL_59]]) : (index) -> index
// CHECK: %[[VAL_80:.*]]:2 = "handshake.fork"(%[[VAL_79]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_81:.*]] = "handshake.merge"(%[[VAL_61]]) : (index) -> index
// CHECK: %[[VAL_82:.*]]:2 = "handshake.fork"(%[[VAL_81]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_83:.*]] = "handshake.merge"(%[[VAL_47]]) : (index) -> index
// CHECK: %[[VAL_84:.*]]:2 = "handshake.control_merge"(%[[VAL_63]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_85:.*]]:3 = "handshake.fork"(%[[VAL_84]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_84]]#1) : (index) -> ()
// CHECK: %[[VAL_86:.*]] = "handshake.constant"(%[[VAL_85]]#1) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_87:.*]] = arith.addi %[[VAL_68]]#1, %[[VAL_86]] : index
// CHECK: %[[VAL_88:.*]] = "handshake.constant"(%[[VAL_85]]#0) {value = 11 : index} : (none) -> index
// CHECK: %[[VAL_89:.*]] = arith.addi %[[VAL_70]]#1, %[[VAL_88]] : index
// CHECK: memref.dma_start %[[VAL_72]]#1{{\[}}%[[VAL_87]]], %[[VAL_74]]#1{{\[}}%[[VAL_89]]], %[[VAL_76]]#1, %[[VAL_78]]#1{{\[}}%[[VAL_80]]#1] : memref<100xf32>, memref<100xf32, 2>, memref<1xi32>
// CHECK: %[[VAL_90:.*]] = arith.addi %[[VAL_68]]#0, %[[VAL_82]]#1 : index
// CHECK: %[[VAL_27]] = "handshake.branch"(%[[VAL_70]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_72]]#0) {control = false} : (memref<100xf32>) -> memref<100xf32>
// CHECK: %[[VAL_31]] = "handshake.branch"(%[[VAL_74]]#0) {control = false} : (memref<100xf32, 2>) -> memref<100xf32, 2>
// CHECK: %[[VAL_33]] = "handshake.branch"(%[[VAL_76]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_35]] = "handshake.branch"(%[[VAL_78]]#0) {control = false} : (memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_37]] = "handshake.branch"(%[[VAL_80]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_39]] = "handshake.branch"(%[[VAL_82]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_24]] = "handshake.branch"(%[[VAL_83]]) {control = false} : (index) -> index
// CHECK: %[[VAL_41]] = "handshake.branch"(%[[VAL_85]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_43]] = "handshake.branch"(%[[VAL_90]]) {control = false} : (index) -> index
// CHECK: %[[VAL_91:.*]]:2 = "handshake.control_merge"(%[[VAL_64]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_91]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_91]]#0 : none
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_3]]#4 {value = 0 : index} : index
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_3]]#3 {value = 64 : index} : index
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_3]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_10:.*]] = constant %[[VAL_3]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_11:.*]] = constant %[[VAL_3]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_12:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_3]]#5 : none
// CHECK: %[[VAL_14:.*]] = br %[[VAL_4]] : memref<100xf32>
// CHECK: %[[VAL_15:.*]] = br %[[VAL_5]] : memref<100xf32, 2>
// CHECK: %[[VAL_16:.*]] = br %[[VAL_6]] : memref<1xi32>
// CHECK: %[[VAL_17:.*]] = br %[[VAL_7]] : index
// CHECK: %[[VAL_18:.*]] = br %[[VAL_8]] : index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_9]] : index
// CHECK: %[[VAL_20:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_21:.*]] = br %[[VAL_11]] : index
// CHECK: %[[VAL_22:.*]] = mux %[[VAL_23:.*]]#8 {{\[}}%[[VAL_24:.*]], %[[VAL_20]]] : index, index
// CHECK: %[[VAL_25:.*]]:2 = fork [2] %[[VAL_22]] : index
// CHECK: %[[VAL_26:.*]] = mux %[[VAL_23]]#7 {{\[}}%[[VAL_27:.*]], %[[VAL_12]]] : index, index
// CHECK: %[[VAL_28:.*]] = mux %[[VAL_23]]#6 {{\[}}%[[VAL_29:.*]], %[[VAL_14]]] : index, memref<100xf32>
// CHECK: %[[VAL_30:.*]] = mux %[[VAL_23]]#5 {{\[}}%[[VAL_31:.*]], %[[VAL_15]]] : index, memref<100xf32, 2>
// CHECK: %[[VAL_32:.*]] = mux %[[VAL_23]]#4 {{\[}}%[[VAL_33:.*]], %[[VAL_18]]] : index, index
// CHECK: %[[VAL_34:.*]] = mux %[[VAL_23]]#3 {{\[}}%[[VAL_35:.*]], %[[VAL_16]]] : index, memref<1xi32>
// CHECK: %[[VAL_36:.*]] = mux %[[VAL_23]]#2 {{\[}}%[[VAL_37:.*]], %[[VAL_17]]] : index, index
// CHECK: %[[VAL_38:.*]] = mux %[[VAL_23]]#1 {{\[}}%[[VAL_39:.*]], %[[VAL_21]]] : index, index
// CHECK: %[[VAL_40:.*]], %[[VAL_41:.*]] = control_merge %[[VAL_42:.*]], %[[VAL_13]] : none
// CHECK: %[[VAL_23]]:9 = fork [9] %[[VAL_41]] : index
// CHECK: %[[VAL_43:.*]] = mux %[[VAL_23]]#0 {{\[}}%[[VAL_44:.*]], %[[VAL_19]]] : index, index
// CHECK: %[[VAL_45:.*]]:2 = fork [2] %[[VAL_43]] : index
// CHECK: %[[VAL_46:.*]] = arith.cmpi slt, %[[VAL_45]]#1, %[[VAL_25]]#1 : index
// CHECK: %[[VAL_47:.*]]:10 = fork [10] %[[VAL_46]] : i1
// CHECK: %[[VAL_48:.*]], %[[VAL_49:.*]] = cond_br %[[VAL_47]]#9, %[[VAL_25]]#0 : index
// CHECK: sink %[[VAL_49]] : index
// CHECK: %[[VAL_50:.*]], %[[VAL_51:.*]] = cond_br %[[VAL_47]]#8, %[[VAL_26]] : index
// CHECK: sink %[[VAL_51]] : index
// CHECK: %[[VAL_52:.*]], %[[VAL_53:.*]] = cond_br %[[VAL_47]]#7, %[[VAL_28]] : memref<100xf32>
// CHECK: sink %[[VAL_53]] : memref<100xf32>
// CHECK: %[[VAL_54:.*]], %[[VAL_55:.*]] = cond_br %[[VAL_47]]#6, %[[VAL_30]] : memref<100xf32, 2>
// CHECK: sink %[[VAL_55]] : memref<100xf32, 2>
// CHECK: %[[VAL_56:.*]], %[[VAL_57:.*]] = cond_br %[[VAL_47]]#5, %[[VAL_32]] : index
// CHECK: sink %[[VAL_57]] : index
// CHECK: %[[VAL_58:.*]], %[[VAL_59:.*]] = cond_br %[[VAL_47]]#4, %[[VAL_34]] : memref<1xi32>
// CHECK: sink %[[VAL_59]] : memref<1xi32>
// CHECK: %[[VAL_60:.*]], %[[VAL_61:.*]] = cond_br %[[VAL_47]]#3, %[[VAL_36]] : index
// CHECK: sink %[[VAL_61]] : index
// CHECK: %[[VAL_62:.*]], %[[VAL_63:.*]] = cond_br %[[VAL_47]]#2, %[[VAL_38]] : index
// CHECK: sink %[[VAL_63]] : index
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = cond_br %[[VAL_47]]#1, %[[VAL_40]] : none
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = cond_br %[[VAL_47]]#0, %[[VAL_45]]#0 : index
// CHECK: sink %[[VAL_67]] : index
// CHECK: %[[VAL_68:.*]] = merge %[[VAL_66]] : index
// CHECK: %[[VAL_69:.*]]:2 = fork [2] %[[VAL_68]] : index
// CHECK: %[[VAL_70:.*]] = merge %[[VAL_50]] : index
// CHECK: %[[VAL_71:.*]]:2 = fork [2] %[[VAL_70]] : index
// CHECK: %[[VAL_72:.*]] = merge %[[VAL_52]] : memref<100xf32>
// CHECK: %[[VAL_73:.*]]:2 = fork [2] %[[VAL_72]] : memref<100xf32>
// CHECK: %[[VAL_74:.*]] = merge %[[VAL_54]] : memref<100xf32, 2>
// CHECK: %[[VAL_75:.*]]:2 = fork [2] %[[VAL_74]] : memref<100xf32, 2>
// CHECK: %[[VAL_76:.*]] = merge %[[VAL_56]] : index
// CHECK: %[[VAL_77:.*]]:2 = fork [2] %[[VAL_76]] : index
// CHECK: %[[VAL_78:.*]] = merge %[[VAL_58]] : memref<1xi32>
// CHECK: %[[VAL_79:.*]]:2 = fork [2] %[[VAL_78]] : memref<1xi32>
// CHECK: %[[VAL_80:.*]] = merge %[[VAL_60]] : index
// CHECK: %[[VAL_81:.*]]:2 = fork [2] %[[VAL_80]] : index
// CHECK: %[[VAL_82:.*]] = merge %[[VAL_62]] : index
// CHECK: %[[VAL_83:.*]]:2 = fork [2] %[[VAL_82]] : index
// CHECK: %[[VAL_84:.*]] = merge %[[VAL_48]] : index
// CHECK: %[[VAL_85:.*]], %[[VAL_86:.*]] = control_merge %[[VAL_64]] : none
// CHECK: %[[VAL_87:.*]]:3 = fork [3] %[[VAL_85]] : none
// CHECK: sink %[[VAL_86]] : index
// CHECK: %[[VAL_88:.*]] = constant %[[VAL_87]]#1 {value = 7 : index} : index
// CHECK: %[[VAL_89:.*]] = arith.addi %[[VAL_69]]#1, %[[VAL_88]] : index
// CHECK: %[[VAL_90:.*]] = constant %[[VAL_87]]#0 {value = 11 : index} : index
// CHECK: %[[VAL_91:.*]] = arith.addi %[[VAL_71]]#1, %[[VAL_90]] : index
// CHECK: memref.dma_start %[[VAL_73]]#1{{\[}}%[[VAL_89]]], %[[VAL_75]]#1{{\[}}%[[VAL_91]]], %[[VAL_77]]#1, %[[VAL_79]]#1{{\[}}%[[VAL_81]]#1] : memref<100xf32>, memref<100xf32, 2>, memref<1xi32>
// CHECK: %[[VAL_92:.*]] = arith.addi %[[VAL_69]]#0, %[[VAL_83]]#1 : index
// CHECK: %[[VAL_27]] = br %[[VAL_71]]#0 : index
// CHECK: %[[VAL_29]] = br %[[VAL_73]]#0 : memref<100xf32>
// CHECK: %[[VAL_31]] = br %[[VAL_75]]#0 : memref<100xf32, 2>
// CHECK: %[[VAL_33]] = br %[[VAL_77]]#0 : index
// CHECK: %[[VAL_35]] = br %[[VAL_79]]#0 : memref<1xi32>
// CHECK: %[[VAL_37]] = br %[[VAL_81]]#0 : index
// CHECK: %[[VAL_39]] = br %[[VAL_83]]#0 : index
// CHECK: %[[VAL_24]] = br %[[VAL_84]] : index
// CHECK: %[[VAL_42]] = br %[[VAL_87]]#2 : none
// CHECK: %[[VAL_44]] = br %[[VAL_92]] : index
// CHECK: %[[VAL_93:.*]], %[[VAL_94:.*]] = control_merge %[[VAL_65]] : none
// CHECK: sink %[[VAL_94]] : index
// CHECK: return %[[VAL_93]] : none
// CHECK: }
// CHECK: }
func @affine_dma_start(%arg0: index) {
%0 = memref.alloc() : memref<100xf32>
%1 = memref.alloc() : memref<100xf32, 2>
%2 = memref.alloc() : memref<1xi32>

View File

@ -1,106 +1,102 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @imperfectly_nested_loops() {
// CHECK: module {
// CHECK-LABEL: handshake.func @imperfectly_nested_loops(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.branch"(%[[VAL_1]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (index) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_3]]) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.mux"(%[[VAL_10:.*]]#2, %[[VAL_11:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]] = "handshake.mux"(%[[VAL_10]]#1, %[[VAL_14:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_15:.*]]:2 = "handshake.control_merge"(%[[VAL_16:.*]], %[[VAL_5]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_10]]:3 = "handshake.fork"(%[[VAL_15]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_17:.*]] = "handshake.mux"(%[[VAL_10]]#0, %[[VAL_18:.*]], %[[VAL_6]]) : (index, index, index) -> index
// CHECK: %[[VAL_19:.*]]:2 = "handshake.fork"(%[[VAL_17]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_19]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_21:.*]]:4 = "handshake.fork"(%[[VAL_20]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#3, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_23]]) : (index) -> ()
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#2, %[[VAL_13]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#1, %[[VAL_15]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#0, %[[VAL_19]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_29]]) : (index) -> ()
// CHECK: %[[VAL_30:.*]] = "handshake.merge"(%[[VAL_28]]) : (index) -> index
// CHECK: %[[VAL_31:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_32:.*]] = "handshake.merge"(%[[VAL_22]]) : (index) -> index
// CHECK: %[[VAL_33:.*]]:2 = "handshake.control_merge"(%[[VAL_26]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_34:.*]]:4 = "handshake.fork"(%[[VAL_33]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_33]]#1) : (index) -> ()
// CHECK: %[[VAL_35:.*]] = "handshake.constant"(%[[VAL_34]]#2) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_36:.*]] = "handshake.constant"(%[[VAL_34]]#1) {value = 56 : index} : (none) -> index
// CHECK: %[[VAL_37:.*]] = "handshake.constant"(%[[VAL_34]]#0) {value = 2 : index} : (none) -> index
// CHECK: %[[VAL_38:.*]] = "handshake.branch"(%[[VAL_30]]) {control = false} : (index) -> index
// CHECK: %[[VAL_39:.*]] = "handshake.branch"(%[[VAL_31]]) {control = false} : (index) -> index
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_32]]) {control = false} : (index) -> index
// CHECK: %[[VAL_41:.*]] = "handshake.branch"(%[[VAL_34]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_42:.*]] = "handshake.branch"(%[[VAL_35]]) {control = false} : (index) -> index
// CHECK: %[[VAL_43:.*]] = "handshake.branch"(%[[VAL_36]]) {control = false} : (index) -> index
// CHECK: %[[VAL_44:.*]] = "handshake.branch"(%[[VAL_37]]) {control = false} : (index) -> index
// CHECK: %[[VAL_45:.*]] = "handshake.mux"(%[[VAL_46:.*]]#5, %[[VAL_47:.*]], %[[VAL_43]]) : (index, index, index) -> index
// CHECK: %[[VAL_48:.*]]:2 = "handshake.fork"(%[[VAL_45]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_49:.*]] = "handshake.mux"(%[[VAL_46]]#4, %[[VAL_50:.*]], %[[VAL_44]]) : (index, index, index) -> index
// CHECK: %[[VAL_51:.*]] = "handshake.mux"(%[[VAL_46]]#3, %[[VAL_52:.*]], %[[VAL_38]]) : (index, index, index) -> index
// CHECK: %[[VAL_53:.*]] = "handshake.mux"(%[[VAL_46]]#2, %[[VAL_54:.*]], %[[VAL_39]]) : (index, index, index) -> index
// CHECK: %[[VAL_55:.*]] = "handshake.mux"(%[[VAL_46]]#1, %[[VAL_56:.*]], %[[VAL_40]]) : (index, index, index) -> index
// CHECK: %[[VAL_57:.*]]:2 = "handshake.control_merge"(%[[VAL_58:.*]], %[[VAL_41]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_46]]:6 = "handshake.fork"(%[[VAL_57]]#1) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_59:.*]] = "handshake.mux"(%[[VAL_46]]#0, %[[VAL_60:.*]], %[[VAL_42]]) : (index, index, index) -> index
// CHECK: %[[VAL_61:.*]]:2 = "handshake.fork"(%[[VAL_59]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_62:.*]] = arith.cmpi slt, %[[VAL_61]]#1, %[[VAL_48]]#1 : index
// CHECK: %[[VAL_63:.*]]:7 = "handshake.fork"(%[[VAL_62]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#6, %[[VAL_48]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_65]]) : (index) -> ()
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#5, %[[VAL_49]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_67]]) : (index) -> ()
// CHECK: %[[VAL_68:.*]], %[[VAL_69:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#4, %[[VAL_51]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_70:.*]], %[[VAL_71:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#3, %[[VAL_53]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_72:.*]], %[[VAL_73:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#2, %[[VAL_55]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_74:.*]], %[[VAL_75:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#1, %[[VAL_57]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_76:.*]], %[[VAL_77:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#0, %[[VAL_61]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_77]]) : (index) -> ()
// CHECK: %[[VAL_78:.*]] = "handshake.merge"(%[[VAL_76]]) : (index) -> index
// CHECK: %[[VAL_79:.*]] = "handshake.merge"(%[[VAL_66]]) : (index) -> index
// CHECK: %[[VAL_80:.*]]:2 = "handshake.fork"(%[[VAL_79]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_81:.*]] = "handshake.merge"(%[[VAL_64]]) : (index) -> index
// CHECK: %[[VAL_82:.*]] = "handshake.merge"(%[[VAL_68]]) : (index) -> index
// CHECK: %[[VAL_83:.*]] = "handshake.merge"(%[[VAL_70]]) : (index) -> index
// CHECK: %[[VAL_84:.*]] = "handshake.merge"(%[[VAL_72]]) : (index) -> index
// CHECK: %[[VAL_85:.*]]:2 = "handshake.control_merge"(%[[VAL_74]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_85]]#1) : (index) -> ()
// CHECK: %[[VAL_86:.*]] = arith.addi %[[VAL_78]], %[[VAL_80]]#1 : index
// CHECK: %[[VAL_50]] = "handshake.branch"(%[[VAL_80]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_47]] = "handshake.branch"(%[[VAL_81]]) {control = false} : (index) -> index
// CHECK: %[[VAL_52]] = "handshake.branch"(%[[VAL_82]]) {control = false} : (index) -> index
// CHECK: %[[VAL_54]] = "handshake.branch"(%[[VAL_83]]) {control = false} : (index) -> index
// CHECK: %[[VAL_56]] = "handshake.branch"(%[[VAL_84]]) {control = false} : (index) -> index
// CHECK: %[[VAL_58]] = "handshake.branch"(%[[VAL_85]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_60]] = "handshake.branch"(%[[VAL_86]]) {control = false} : (index) -> index
// CHECK: %[[VAL_87:.*]] = "handshake.merge"(%[[VAL_69]]) : (index) -> index
// CHECK: %[[VAL_88:.*]] = "handshake.merge"(%[[VAL_71]]) : (index) -> index
// CHECK: %[[VAL_89:.*]]:2 = "handshake.fork"(%[[VAL_88]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_90:.*]] = "handshake.merge"(%[[VAL_73]]) : (index) -> index
// CHECK: %[[VAL_91:.*]]:2 = "handshake.control_merge"(%[[VAL_75]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_91]]#1) : (index) -> ()
// CHECK: %[[VAL_92:.*]] = arith.addi %[[VAL_87]], %[[VAL_89]]#1 : index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_89]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_90]]) {control = false} : (index) -> index
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_91]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_18]] = "handshake.branch"(%[[VAL_92]]) {control = false} : (index) -> index
// CHECK: %[[VAL_93:.*]]:2 = "handshake.control_merge"(%[[VAL_27]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_93]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_93]]#0 : none
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_5:.*]] = br %[[VAL_1]]#3 : none
// CHECK: %[[VAL_6:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_3]] : index
// CHECK: %[[VAL_8:.*]] = br %[[VAL_4]] : index
// CHECK: %[[VAL_9:.*]] = mux %[[VAL_10:.*]]#2 {{\[}}%[[VAL_11:.*]], %[[VAL_7]]] : index, index
// CHECK: %[[VAL_12:.*]]:2 = fork [2] %[[VAL_9]] : index
// CHECK: %[[VAL_13:.*]] = mux %[[VAL_10]]#1 {{\[}}%[[VAL_14:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_15:.*]], %[[VAL_16:.*]] = control_merge %[[VAL_17:.*]], %[[VAL_5]] : none
// CHECK: %[[VAL_10]]:3 = fork [3] %[[VAL_16]] : index
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_10]]#0 {{\[}}%[[VAL_19:.*]], %[[VAL_6]]] : index, index
// CHECK: %[[VAL_20:.*]]:2 = fork [2] %[[VAL_18]] : index
// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_20]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_22:.*]]:4 = fork [4] %[[VAL_21]] : i1
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = cond_br %[[VAL_22]]#3, %[[VAL_12]]#0 : index
// CHECK: sink %[[VAL_24]] : index
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = cond_br %[[VAL_22]]#2, %[[VAL_13]] : index
// CHECK: sink %[[VAL_26]] : index
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = cond_br %[[VAL_22]]#1, %[[VAL_15]] : none
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = cond_br %[[VAL_22]]#0, %[[VAL_20]]#0 : index
// CHECK: sink %[[VAL_30]] : index
// CHECK: %[[VAL_31:.*]] = merge %[[VAL_29]] : index
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_25]] : index
// CHECK: %[[VAL_33:.*]] = merge %[[VAL_23]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_27]] : none
// CHECK: %[[VAL_36:.*]]:4 = fork [4] %[[VAL_34]] : none
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_37:.*]] = constant %[[VAL_36]]#2 {value = 7 : index} : index
// CHECK: %[[VAL_38:.*]] = constant %[[VAL_36]]#1 {value = 56 : index} : index
// CHECK: %[[VAL_39:.*]] = constant %[[VAL_36]]#0 {value = 2 : index} : index
// CHECK: %[[VAL_40:.*]] = br %[[VAL_31]] : index
// CHECK: %[[VAL_41:.*]] = br %[[VAL_32]] : index
// CHECK: %[[VAL_42:.*]] = br %[[VAL_33]] : index
// CHECK: %[[VAL_43:.*]] = br %[[VAL_36]]#3 : none
// CHECK: %[[VAL_44:.*]] = br %[[VAL_37]] : index
// CHECK: %[[VAL_45:.*]] = br %[[VAL_38]] : index
// CHECK: %[[VAL_46:.*]] = br %[[VAL_39]] : index
// CHECK: %[[VAL_47:.*]] = mux %[[VAL_48:.*]]#5 {{\[}}%[[VAL_49:.*]], %[[VAL_45]]] : index, index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_47]] : index
// CHECK: %[[VAL_51:.*]] = mux %[[VAL_48]]#4 {{\[}}%[[VAL_52:.*]], %[[VAL_46]]] : index, index
// CHECK: %[[VAL_53:.*]] = mux %[[VAL_48]]#3 {{\[}}%[[VAL_54:.*]], %[[VAL_40]]] : index, index
// CHECK: %[[VAL_55:.*]] = mux %[[VAL_48]]#2 {{\[}}%[[VAL_56:.*]], %[[VAL_41]]] : index, index
// CHECK: %[[VAL_57:.*]] = mux %[[VAL_48]]#1 {{\[}}%[[VAL_58:.*]], %[[VAL_42]]] : index, index
// CHECK: %[[VAL_59:.*]], %[[VAL_60:.*]] = control_merge %[[VAL_61:.*]], %[[VAL_43]] : none
// CHECK: %[[VAL_48]]:6 = fork [6] %[[VAL_60]] : index
// CHECK: %[[VAL_62:.*]] = mux %[[VAL_48]]#0 {{\[}}%[[VAL_63:.*]], %[[VAL_44]]] : index, index
// CHECK: %[[VAL_64:.*]]:2 = fork [2] %[[VAL_62]] : index
// CHECK: %[[VAL_65:.*]] = arith.cmpi slt, %[[VAL_64]]#1, %[[VAL_50]]#1 : index
// CHECK: %[[VAL_66:.*]]:7 = fork [7] %[[VAL_65]] : i1
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = cond_br %[[VAL_66]]#6, %[[VAL_50]]#0 : index
// CHECK: sink %[[VAL_68]] : index
// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = cond_br %[[VAL_66]]#5, %[[VAL_51]] : index
// CHECK: sink %[[VAL_70]] : index
// CHECK: %[[VAL_71:.*]], %[[VAL_72:.*]] = cond_br %[[VAL_66]]#4, %[[VAL_53]] : index
// CHECK: %[[VAL_73:.*]], %[[VAL_74:.*]] = cond_br %[[VAL_66]]#3, %[[VAL_55]] : index
// CHECK: %[[VAL_75:.*]], %[[VAL_76:.*]] = cond_br %[[VAL_66]]#2, %[[VAL_57]] : index
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = cond_br %[[VAL_66]]#1, %[[VAL_59]] : none
// CHECK: %[[VAL_79:.*]], %[[VAL_80:.*]] = cond_br %[[VAL_66]]#0, %[[VAL_64]]#0 : index
// CHECK: sink %[[VAL_80]] : index
// CHECK: %[[VAL_81:.*]] = merge %[[VAL_79]] : index
// CHECK: %[[VAL_82:.*]] = merge %[[VAL_69]] : index
// CHECK: %[[VAL_83:.*]]:2 = fork [2] %[[VAL_82]] : index
// CHECK: %[[VAL_84:.*]] = merge %[[VAL_67]] : index
// CHECK: %[[VAL_85:.*]] = merge %[[VAL_71]] : index
// CHECK: %[[VAL_86:.*]] = merge %[[VAL_73]] : index
// CHECK: %[[VAL_87:.*]] = merge %[[VAL_75]] : index
// CHECK: %[[VAL_88:.*]], %[[VAL_89:.*]] = control_merge %[[VAL_77]] : none
// CHECK: sink %[[VAL_89]] : index
// CHECK: %[[VAL_90:.*]] = arith.addi %[[VAL_81]], %[[VAL_83]]#1 : index
// CHECK: %[[VAL_52]] = br %[[VAL_83]]#0 : index
// CHECK: %[[VAL_49]] = br %[[VAL_84]] : index
// CHECK: %[[VAL_54]] = br %[[VAL_85]] : index
// CHECK: %[[VAL_56]] = br %[[VAL_86]] : index
// CHECK: %[[VAL_58]] = br %[[VAL_87]] : index
// CHECK: %[[VAL_61]] = br %[[VAL_88]] : none
// CHECK: %[[VAL_63]] = br %[[VAL_90]] : index
// CHECK: %[[VAL_91:.*]] = merge %[[VAL_72]] : index
// CHECK: %[[VAL_92:.*]] = merge %[[VAL_74]] : index
// CHECK: %[[VAL_93:.*]]:2 = fork [2] %[[VAL_92]] : index
// CHECK: %[[VAL_94:.*]] = merge %[[VAL_76]] : index
// CHECK: %[[VAL_95:.*]], %[[VAL_96:.*]] = control_merge %[[VAL_78]] : none
// CHECK: sink %[[VAL_96]] : index
// CHECK: %[[VAL_97:.*]] = arith.addi %[[VAL_91]], %[[VAL_93]]#1 : index
// CHECK: %[[VAL_14]] = br %[[VAL_93]]#0 : index
// CHECK: %[[VAL_11]] = br %[[VAL_94]] : index
// CHECK: %[[VAL_17]] = br %[[VAL_95]] : none
// CHECK: %[[VAL_19]] = br %[[VAL_97]] : index
// CHECK: %[[VAL_98:.*]], %[[VAL_99:.*]] = control_merge %[[VAL_28]] : none
// CHECK: sink %[[VAL_99]] : index
// CHECK: return %[[VAL_98]] : none
// CHECK: }
// CHECK: }
func @imperfectly_nested_loops() {
%c0 = arith.constant 0 : index
%c42 = arith.constant 42 : index
%c1 = arith.constant 1 : index

View File

@ -1,161 +1,157 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @more_imperfectly_nested_loops() {
// CHECK: module {
// CHECK-LABEL: handshake.func @more_imperfectly_nested_loops(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.branch"(%[[VAL_1]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (index) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_3]]) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.mux"(%[[VAL_10:.*]]#2, %[[VAL_11:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]] = "handshake.mux"(%[[VAL_10]]#1, %[[VAL_14:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_15:.*]]:2 = "handshake.control_merge"(%[[VAL_16:.*]], %[[VAL_5]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_10]]:3 = "handshake.fork"(%[[VAL_15]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_17:.*]] = "handshake.mux"(%[[VAL_10]]#0, %[[VAL_18:.*]], %[[VAL_6]]) : (index, index, index) -> index
// CHECK: %[[VAL_19:.*]]:2 = "handshake.fork"(%[[VAL_17]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_19]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_21:.*]]:4 = "handshake.fork"(%[[VAL_20]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#3, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_23]]) : (index) -> ()
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#2, %[[VAL_13]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#1, %[[VAL_15]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = "handshake.conditional_branch"(%[[VAL_21]]#0, %[[VAL_19]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_29]]) : (index) -> ()
// CHECK: %[[VAL_30:.*]] = "handshake.merge"(%[[VAL_28]]) : (index) -> index
// CHECK: %[[VAL_31:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_32:.*]] = "handshake.merge"(%[[VAL_22]]) : (index) -> index
// CHECK: %[[VAL_33:.*]]:2 = "handshake.control_merge"(%[[VAL_26]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_34:.*]]:4 = "handshake.fork"(%[[VAL_33]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_33]]#1) : (index) -> ()
// CHECK: %[[VAL_35:.*]] = "handshake.constant"(%[[VAL_34]]#2) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_36:.*]] = "handshake.constant"(%[[VAL_34]]#1) {value = 56 : index} : (none) -> index
// CHECK: %[[VAL_37:.*]] = "handshake.constant"(%[[VAL_34]]#0) {value = 2 : index} : (none) -> index
// CHECK: %[[VAL_38:.*]] = "handshake.branch"(%[[VAL_30]]) {control = false} : (index) -> index
// CHECK: %[[VAL_39:.*]] = "handshake.branch"(%[[VAL_31]]) {control = false} : (index) -> index
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_32]]) {control = false} : (index) -> index
// CHECK: %[[VAL_41:.*]] = "handshake.branch"(%[[VAL_34]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_42:.*]] = "handshake.branch"(%[[VAL_35]]) {control = false} : (index) -> index
// CHECK: %[[VAL_43:.*]] = "handshake.branch"(%[[VAL_36]]) {control = false} : (index) -> index
// CHECK: %[[VAL_44:.*]] = "handshake.branch"(%[[VAL_37]]) {control = false} : (index) -> index
// CHECK: %[[VAL_45:.*]] = "handshake.mux"(%[[VAL_46:.*]]#5, %[[VAL_47:.*]], %[[VAL_43]]) : (index, index, index) -> index
// CHECK: %[[VAL_48:.*]]:2 = "handshake.fork"(%[[VAL_45]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_49:.*]] = "handshake.mux"(%[[VAL_46]]#4, %[[VAL_50:.*]], %[[VAL_44]]) : (index, index, index) -> index
// CHECK: %[[VAL_51:.*]] = "handshake.mux"(%[[VAL_46]]#3, %[[VAL_52:.*]], %[[VAL_38]]) : (index, index, index) -> index
// CHECK: %[[VAL_53:.*]] = "handshake.mux"(%[[VAL_46]]#2, %[[VAL_54:.*]], %[[VAL_39]]) : (index, index, index) -> index
// CHECK: %[[VAL_55:.*]] = "handshake.mux"(%[[VAL_46]]#1, %[[VAL_56:.*]], %[[VAL_40]]) : (index, index, index) -> index
// CHECK: %[[VAL_57:.*]]:2 = "handshake.control_merge"(%[[VAL_58:.*]], %[[VAL_41]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_46]]:6 = "handshake.fork"(%[[VAL_57]]#1) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_59:.*]] = "handshake.mux"(%[[VAL_46]]#0, %[[VAL_60:.*]], %[[VAL_42]]) : (index, index, index) -> index
// CHECK: %[[VAL_61:.*]]:2 = "handshake.fork"(%[[VAL_59]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_62:.*]] = arith.cmpi slt, %[[VAL_61]]#1, %[[VAL_48]]#1 : index
// CHECK: %[[VAL_63:.*]]:7 = "handshake.fork"(%[[VAL_62]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#6, %[[VAL_48]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_65]]) : (index) -> ()
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#5, %[[VAL_49]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_67]]) : (index) -> ()
// CHECK: %[[VAL_68:.*]], %[[VAL_69:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#4, %[[VAL_51]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_70:.*]], %[[VAL_71:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#3, %[[VAL_53]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_72:.*]], %[[VAL_73:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#2, %[[VAL_55]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_74:.*]], %[[VAL_75:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#1, %[[VAL_57]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_76:.*]], %[[VAL_77:.*]] = "handshake.conditional_branch"(%[[VAL_63]]#0, %[[VAL_61]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_77]]) : (index) -> ()
// CHECK: %[[VAL_78:.*]] = "handshake.merge"(%[[VAL_76]]) : (index) -> index
// CHECK: %[[VAL_79:.*]] = "handshake.merge"(%[[VAL_66]]) : (index) -> index
// CHECK: %[[VAL_80:.*]]:2 = "handshake.fork"(%[[VAL_79]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_81:.*]] = "handshake.merge"(%[[VAL_64]]) : (index) -> index
// CHECK: %[[VAL_82:.*]] = "handshake.merge"(%[[VAL_68]]) : (index) -> index
// CHECK: %[[VAL_83:.*]] = "handshake.merge"(%[[VAL_70]]) : (index) -> index
// CHECK: %[[VAL_84:.*]] = "handshake.merge"(%[[VAL_72]]) : (index) -> index
// CHECK: %[[VAL_85:.*]]:2 = "handshake.control_merge"(%[[VAL_74]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_85]]#1) : (index) -> ()
// CHECK: %[[VAL_86:.*]] = arith.addi %[[VAL_78]], %[[VAL_80]]#1 : index
// CHECK: %[[VAL_50]] = "handshake.branch"(%[[VAL_80]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_47]] = "handshake.branch"(%[[VAL_81]]) {control = false} : (index) -> index
// CHECK: %[[VAL_52]] = "handshake.branch"(%[[VAL_82]]) {control = false} : (index) -> index
// CHECK: %[[VAL_54]] = "handshake.branch"(%[[VAL_83]]) {control = false} : (index) -> index
// CHECK: %[[VAL_56]] = "handshake.branch"(%[[VAL_84]]) {control = false} : (index) -> index
// CHECK: %[[VAL_58]] = "handshake.branch"(%[[VAL_85]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_60]] = "handshake.branch"(%[[VAL_86]]) {control = false} : (index) -> index
// CHECK: %[[VAL_87:.*]] = "handshake.merge"(%[[VAL_69]]) : (index) -> index
// CHECK: %[[VAL_88:.*]] = "handshake.merge"(%[[VAL_71]]) : (index) -> index
// CHECK: %[[VAL_89:.*]] = "handshake.merge"(%[[VAL_73]]) : (index) -> index
// CHECK: %[[VAL_90:.*]]:2 = "handshake.control_merge"(%[[VAL_75]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_91:.*]]:4 = "handshake.fork"(%[[VAL_90]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_90]]#1) : (index) -> ()
// CHECK: %[[VAL_92:.*]] = "handshake.constant"(%[[VAL_91]]#2) {value = 18 : index} : (none) -> index
// CHECK: %[[VAL_93:.*]] = "handshake.constant"(%[[VAL_91]]#1) {value = 37 : index} : (none) -> index
// CHECK: %[[VAL_94:.*]] = "handshake.constant"(%[[VAL_91]]#0) {value = 3 : index} : (none) -> index
// CHECK: %[[VAL_95:.*]] = "handshake.branch"(%[[VAL_87]]) {control = false} : (index) -> index
// CHECK: %[[VAL_96:.*]] = "handshake.branch"(%[[VAL_88]]) {control = false} : (index) -> index
// CHECK: %[[VAL_97:.*]] = "handshake.branch"(%[[VAL_89]]) {control = false} : (index) -> index
// CHECK: %[[VAL_98:.*]] = "handshake.branch"(%[[VAL_91]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_99:.*]] = "handshake.branch"(%[[VAL_92]]) {control = false} : (index) -> index
// CHECK: %[[VAL_100:.*]] = "handshake.branch"(%[[VAL_93]]) {control = false} : (index) -> index
// CHECK: %[[VAL_101:.*]] = "handshake.branch"(%[[VAL_94]]) {control = false} : (index) -> index
// CHECK: %[[VAL_102:.*]] = "handshake.mux"(%[[VAL_103:.*]]#5, %[[VAL_104:.*]], %[[VAL_100]]) : (index, index, index) -> index
// CHECK: %[[VAL_105:.*]]:2 = "handshake.fork"(%[[VAL_102]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_106:.*]] = "handshake.mux"(%[[VAL_103]]#4, %[[VAL_107:.*]], %[[VAL_101]]) : (index, index, index) -> index
// CHECK: %[[VAL_108:.*]] = "handshake.mux"(%[[VAL_103]]#3, %[[VAL_109:.*]], %[[VAL_95]]) : (index, index, index) -> index
// CHECK: %[[VAL_110:.*]] = "handshake.mux"(%[[VAL_103]]#2, %[[VAL_111:.*]], %[[VAL_96]]) : (index, index, index) -> index
// CHECK: %[[VAL_112:.*]] = "handshake.mux"(%[[VAL_103]]#1, %[[VAL_113:.*]], %[[VAL_97]]) : (index, index, index) -> index
// CHECK: %[[VAL_114:.*]]:2 = "handshake.control_merge"(%[[VAL_115:.*]], %[[VAL_98]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_103]]:6 = "handshake.fork"(%[[VAL_114]]#1) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_116:.*]] = "handshake.mux"(%[[VAL_103]]#0, %[[VAL_117:.*]], %[[VAL_99]]) : (index, index, index) -> index
// CHECK: %[[VAL_118:.*]]:2 = "handshake.fork"(%[[VAL_116]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_119:.*]] = arith.cmpi slt, %[[VAL_118]]#1, %[[VAL_105]]#1 : index
// CHECK: %[[VAL_120:.*]]:7 = "handshake.fork"(%[[VAL_119]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_121:.*]], %[[VAL_122:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#6, %[[VAL_105]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_122]]) : (index) -> ()
// CHECK: %[[VAL_123:.*]], %[[VAL_124:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#5, %[[VAL_106]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_124]]) : (index) -> ()
// CHECK: %[[VAL_125:.*]], %[[VAL_126:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#4, %[[VAL_108]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_127:.*]], %[[VAL_128:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#3, %[[VAL_110]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_129:.*]], %[[VAL_130:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#2, %[[VAL_112]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_131:.*]], %[[VAL_132:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#1, %[[VAL_114]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_133:.*]], %[[VAL_134:.*]] = "handshake.conditional_branch"(%[[VAL_120]]#0, %[[VAL_118]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_134]]) : (index) -> ()
// CHECK: %[[VAL_135:.*]] = "handshake.merge"(%[[VAL_133]]) : (index) -> index
// CHECK: %[[VAL_136:.*]] = "handshake.merge"(%[[VAL_123]]) : (index) -> index
// CHECK: %[[VAL_137:.*]]:2 = "handshake.fork"(%[[VAL_136]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_138:.*]] = "handshake.merge"(%[[VAL_121]]) : (index) -> index
// CHECK: %[[VAL_139:.*]] = "handshake.merge"(%[[VAL_125]]) : (index) -> index
// CHECK: %[[VAL_140:.*]] = "handshake.merge"(%[[VAL_127]]) : (index) -> index
// CHECK: %[[VAL_141:.*]] = "handshake.merge"(%[[VAL_129]]) : (index) -> index
// CHECK: %[[VAL_142:.*]]:2 = "handshake.control_merge"(%[[VAL_131]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_142]]#1) : (index) -> ()
// CHECK: %[[VAL_143:.*]] = arith.addi %[[VAL_135]], %[[VAL_137]]#1 : index
// CHECK: %[[VAL_107]] = "handshake.branch"(%[[VAL_137]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_104]] = "handshake.branch"(%[[VAL_138]]) {control = false} : (index) -> index
// CHECK: %[[VAL_109]] = "handshake.branch"(%[[VAL_139]]) {control = false} : (index) -> index
// CHECK: %[[VAL_111]] = "handshake.branch"(%[[VAL_140]]) {control = false} : (index) -> index
// CHECK: %[[VAL_113]] = "handshake.branch"(%[[VAL_141]]) {control = false} : (index) -> index
// CHECK: %[[VAL_115]] = "handshake.branch"(%[[VAL_142]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_117]] = "handshake.branch"(%[[VAL_143]]) {control = false} : (index) -> index
// CHECK: %[[VAL_144:.*]] = "handshake.merge"(%[[VAL_126]]) : (index) -> index
// CHECK: %[[VAL_145:.*]] = "handshake.merge"(%[[VAL_128]]) : (index) -> index
// CHECK: %[[VAL_146:.*]]:2 = "handshake.fork"(%[[VAL_145]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_147:.*]] = "handshake.merge"(%[[VAL_130]]) : (index) -> index
// CHECK: %[[VAL_148:.*]]:2 = "handshake.control_merge"(%[[VAL_132]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_148]]#1) : (index) -> ()
// CHECK: %[[VAL_149:.*]] = arith.addi %[[VAL_144]], %[[VAL_146]]#1 : index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_146]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_147]]) {control = false} : (index) -> index
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_148]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_18]] = "handshake.branch"(%[[VAL_149]]) {control = false} : (index) -> index
// CHECK: %[[VAL_150:.*]]:2 = "handshake.control_merge"(%[[VAL_27]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_150]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_150]]#0 : none
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_5:.*]] = br %[[VAL_1]]#3 : none
// CHECK: %[[VAL_6:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_3]] : index
// CHECK: %[[VAL_8:.*]] = br %[[VAL_4]] : index
// CHECK: %[[VAL_9:.*]] = mux %[[VAL_10:.*]]#2 {{\[}}%[[VAL_11:.*]], %[[VAL_7]]] : index, index
// CHECK: %[[VAL_12:.*]]:2 = fork [2] %[[VAL_9]] : index
// CHECK: %[[VAL_13:.*]] = mux %[[VAL_10]]#1 {{\[}}%[[VAL_14:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_15:.*]], %[[VAL_16:.*]] = control_merge %[[VAL_17:.*]], %[[VAL_5]] : none
// CHECK: %[[VAL_10]]:3 = fork [3] %[[VAL_16]] : index
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_10]]#0 {{\[}}%[[VAL_19:.*]], %[[VAL_6]]] : index, index
// CHECK: %[[VAL_20:.*]]:2 = fork [2] %[[VAL_18]] : index
// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_20]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_22:.*]]:4 = fork [4] %[[VAL_21]] : i1
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = cond_br %[[VAL_22]]#3, %[[VAL_12]]#0 : index
// CHECK: sink %[[VAL_24]] : index
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = cond_br %[[VAL_22]]#2, %[[VAL_13]] : index
// CHECK: sink %[[VAL_26]] : index
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = cond_br %[[VAL_22]]#1, %[[VAL_15]] : none
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = cond_br %[[VAL_22]]#0, %[[VAL_20]]#0 : index
// CHECK: sink %[[VAL_30]] : index
// CHECK: %[[VAL_31:.*]] = merge %[[VAL_29]] : index
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_25]] : index
// CHECK: %[[VAL_33:.*]] = merge %[[VAL_23]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_27]] : none
// CHECK: %[[VAL_36:.*]]:4 = fork [4] %[[VAL_34]] : none
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_37:.*]] = constant %[[VAL_36]]#2 {value = 7 : index} : index
// CHECK: %[[VAL_38:.*]] = constant %[[VAL_36]]#1 {value = 56 : index} : index
// CHECK: %[[VAL_39:.*]] = constant %[[VAL_36]]#0 {value = 2 : index} : index
// CHECK: %[[VAL_40:.*]] = br %[[VAL_31]] : index
// CHECK: %[[VAL_41:.*]] = br %[[VAL_32]] : index
// CHECK: %[[VAL_42:.*]] = br %[[VAL_33]] : index
// CHECK: %[[VAL_43:.*]] = br %[[VAL_36]]#3 : none
// CHECK: %[[VAL_44:.*]] = br %[[VAL_37]] : index
// CHECK: %[[VAL_45:.*]] = br %[[VAL_38]] : index
// CHECK: %[[VAL_46:.*]] = br %[[VAL_39]] : index
// CHECK: %[[VAL_47:.*]] = mux %[[VAL_48:.*]]#5 {{\[}}%[[VAL_49:.*]], %[[VAL_45]]] : index, index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_47]] : index
// CHECK: %[[VAL_51:.*]] = mux %[[VAL_48]]#4 {{\[}}%[[VAL_52:.*]], %[[VAL_46]]] : index, index
// CHECK: %[[VAL_53:.*]] = mux %[[VAL_48]]#3 {{\[}}%[[VAL_54:.*]], %[[VAL_40]]] : index, index
// CHECK: %[[VAL_55:.*]] = mux %[[VAL_48]]#2 {{\[}}%[[VAL_56:.*]], %[[VAL_41]]] : index, index
// CHECK: %[[VAL_57:.*]] = mux %[[VAL_48]]#1 {{\[}}%[[VAL_58:.*]], %[[VAL_42]]] : index, index
// CHECK: %[[VAL_59:.*]], %[[VAL_60:.*]] = control_merge %[[VAL_61:.*]], %[[VAL_43]] : none
// CHECK: %[[VAL_48]]:6 = fork [6] %[[VAL_60]] : index
// CHECK: %[[VAL_62:.*]] = mux %[[VAL_48]]#0 {{\[}}%[[VAL_63:.*]], %[[VAL_44]]] : index, index
// CHECK: %[[VAL_64:.*]]:2 = fork [2] %[[VAL_62]] : index
// CHECK: %[[VAL_65:.*]] = arith.cmpi slt, %[[VAL_64]]#1, %[[VAL_50]]#1 : index
// CHECK: %[[VAL_66:.*]]:7 = fork [7] %[[VAL_65]] : i1
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = cond_br %[[VAL_66]]#6, %[[VAL_50]]#0 : index
// CHECK: sink %[[VAL_68]] : index
// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = cond_br %[[VAL_66]]#5, %[[VAL_51]] : index
// CHECK: sink %[[VAL_70]] : index
// CHECK: %[[VAL_71:.*]], %[[VAL_72:.*]] = cond_br %[[VAL_66]]#4, %[[VAL_53]] : index
// CHECK: %[[VAL_73:.*]], %[[VAL_74:.*]] = cond_br %[[VAL_66]]#3, %[[VAL_55]] : index
// CHECK: %[[VAL_75:.*]], %[[VAL_76:.*]] = cond_br %[[VAL_66]]#2, %[[VAL_57]] : index
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = cond_br %[[VAL_66]]#1, %[[VAL_59]] : none
// CHECK: %[[VAL_79:.*]], %[[VAL_80:.*]] = cond_br %[[VAL_66]]#0, %[[VAL_64]]#0 : index
// CHECK: sink %[[VAL_80]] : index
// CHECK: %[[VAL_81:.*]] = merge %[[VAL_79]] : index
// CHECK: %[[VAL_82:.*]] = merge %[[VAL_69]] : index
// CHECK: %[[VAL_83:.*]]:2 = fork [2] %[[VAL_82]] : index
// CHECK: %[[VAL_84:.*]] = merge %[[VAL_67]] : index
// CHECK: %[[VAL_85:.*]] = merge %[[VAL_71]] : index
// CHECK: %[[VAL_86:.*]] = merge %[[VAL_73]] : index
// CHECK: %[[VAL_87:.*]] = merge %[[VAL_75]] : index
// CHECK: %[[VAL_88:.*]], %[[VAL_89:.*]] = control_merge %[[VAL_77]] : none
// CHECK: sink %[[VAL_89]] : index
// CHECK: %[[VAL_90:.*]] = arith.addi %[[VAL_81]], %[[VAL_83]]#1 : index
// CHECK: %[[VAL_52]] = br %[[VAL_83]]#0 : index
// CHECK: %[[VAL_49]] = br %[[VAL_84]] : index
// CHECK: %[[VAL_54]] = br %[[VAL_85]] : index
// CHECK: %[[VAL_56]] = br %[[VAL_86]] : index
// CHECK: %[[VAL_58]] = br %[[VAL_87]] : index
// CHECK: %[[VAL_61]] = br %[[VAL_88]] : none
// CHECK: %[[VAL_63]] = br %[[VAL_90]] : index
// CHECK: %[[VAL_91:.*]] = merge %[[VAL_72]] : index
// CHECK: %[[VAL_92:.*]] = merge %[[VAL_74]] : index
// CHECK: %[[VAL_93:.*]] = merge %[[VAL_76]] : index
// CHECK: %[[VAL_94:.*]], %[[VAL_95:.*]] = control_merge %[[VAL_78]] : none
// CHECK: %[[VAL_96:.*]]:4 = fork [4] %[[VAL_94]] : none
// CHECK: sink %[[VAL_95]] : index
// CHECK: %[[VAL_97:.*]] = constant %[[VAL_96]]#2 {value = 18 : index} : index
// CHECK: %[[VAL_98:.*]] = constant %[[VAL_96]]#1 {value = 37 : index} : index
// CHECK: %[[VAL_99:.*]] = constant %[[VAL_96]]#0 {value = 3 : index} : index
// CHECK: %[[VAL_100:.*]] = br %[[VAL_91]] : index
// CHECK: %[[VAL_101:.*]] = br %[[VAL_92]] : index
// CHECK: %[[VAL_102:.*]] = br %[[VAL_93]] : index
// CHECK: %[[VAL_103:.*]] = br %[[VAL_96]]#3 : none
// CHECK: %[[VAL_104:.*]] = br %[[VAL_97]] : index
// CHECK: %[[VAL_105:.*]] = br %[[VAL_98]] : index
// CHECK: %[[VAL_106:.*]] = br %[[VAL_99]] : index
// CHECK: %[[VAL_107:.*]] = mux %[[VAL_108:.*]]#5 {{\[}}%[[VAL_109:.*]], %[[VAL_105]]] : index, index
// CHECK: %[[VAL_110:.*]]:2 = fork [2] %[[VAL_107]] : index
// CHECK: %[[VAL_111:.*]] = mux %[[VAL_108]]#4 {{\[}}%[[VAL_112:.*]], %[[VAL_106]]] : index, index
// CHECK: %[[VAL_113:.*]] = mux %[[VAL_108]]#3 {{\[}}%[[VAL_114:.*]], %[[VAL_100]]] : index, index
// CHECK: %[[VAL_115:.*]] = mux %[[VAL_108]]#2 {{\[}}%[[VAL_116:.*]], %[[VAL_101]]] : index, index
// CHECK: %[[VAL_117:.*]] = mux %[[VAL_108]]#1 {{\[}}%[[VAL_118:.*]], %[[VAL_102]]] : index, index
// CHECK: %[[VAL_119:.*]], %[[VAL_120:.*]] = control_merge %[[VAL_121:.*]], %[[VAL_103]] : none
// CHECK: %[[VAL_108]]:6 = fork [6] %[[VAL_120]] : index
// CHECK: %[[VAL_122:.*]] = mux %[[VAL_108]]#0 {{\[}}%[[VAL_123:.*]], %[[VAL_104]]] : index, index
// CHECK: %[[VAL_124:.*]]:2 = fork [2] %[[VAL_122]] : index
// CHECK: %[[VAL_125:.*]] = arith.cmpi slt, %[[VAL_124]]#1, %[[VAL_110]]#1 : index
// CHECK: %[[VAL_126:.*]]:7 = fork [7] %[[VAL_125]] : i1
// CHECK: %[[VAL_127:.*]], %[[VAL_128:.*]] = cond_br %[[VAL_126]]#6, %[[VAL_110]]#0 : index
// CHECK: sink %[[VAL_128]] : index
// CHECK: %[[VAL_129:.*]], %[[VAL_130:.*]] = cond_br %[[VAL_126]]#5, %[[VAL_111]] : index
// CHECK: sink %[[VAL_130]] : index
// CHECK: %[[VAL_131:.*]], %[[VAL_132:.*]] = cond_br %[[VAL_126]]#4, %[[VAL_113]] : index
// CHECK: %[[VAL_133:.*]], %[[VAL_134:.*]] = cond_br %[[VAL_126]]#3, %[[VAL_115]] : index
// CHECK: %[[VAL_135:.*]], %[[VAL_136:.*]] = cond_br %[[VAL_126]]#2, %[[VAL_117]] : index
// CHECK: %[[VAL_137:.*]], %[[VAL_138:.*]] = cond_br %[[VAL_126]]#1, %[[VAL_119]] : none
// CHECK: %[[VAL_139:.*]], %[[VAL_140:.*]] = cond_br %[[VAL_126]]#0, %[[VAL_124]]#0 : index
// CHECK: sink %[[VAL_140]] : index
// CHECK: %[[VAL_141:.*]] = merge %[[VAL_139]] : index
// CHECK: %[[VAL_142:.*]] = merge %[[VAL_129]] : index
// CHECK: %[[VAL_143:.*]]:2 = fork [2] %[[VAL_142]] : index
// CHECK: %[[VAL_144:.*]] = merge %[[VAL_127]] : index
// CHECK: %[[VAL_145:.*]] = merge %[[VAL_131]] : index
// CHECK: %[[VAL_146:.*]] = merge %[[VAL_133]] : index
// CHECK: %[[VAL_147:.*]] = merge %[[VAL_135]] : index
// CHECK: %[[VAL_148:.*]], %[[VAL_149:.*]] = control_merge %[[VAL_137]] : none
// CHECK: sink %[[VAL_149]] : index
// CHECK: %[[VAL_150:.*]] = arith.addi %[[VAL_141]], %[[VAL_143]]#1 : index
// CHECK: %[[VAL_112]] = br %[[VAL_143]]#0 : index
// CHECK: %[[VAL_109]] = br %[[VAL_144]] : index
// CHECK: %[[VAL_114]] = br %[[VAL_145]] : index
// CHECK: %[[VAL_116]] = br %[[VAL_146]] : index
// CHECK: %[[VAL_118]] = br %[[VAL_147]] : index
// CHECK: %[[VAL_121]] = br %[[VAL_148]] : none
// CHECK: %[[VAL_123]] = br %[[VAL_150]] : index
// CHECK: %[[VAL_151:.*]] = merge %[[VAL_132]] : index
// CHECK: %[[VAL_152:.*]] = merge %[[VAL_134]] : index
// CHECK: %[[VAL_153:.*]]:2 = fork [2] %[[VAL_152]] : index
// CHECK: %[[VAL_154:.*]] = merge %[[VAL_136]] : index
// CHECK: %[[VAL_155:.*]], %[[VAL_156:.*]] = control_merge %[[VAL_138]] : none
// CHECK: sink %[[VAL_156]] : index
// CHECK: %[[VAL_157:.*]] = arith.addi %[[VAL_151]], %[[VAL_153]]#1 : index
// CHECK: %[[VAL_14]] = br %[[VAL_153]]#0 : index
// CHECK: %[[VAL_11]] = br %[[VAL_154]] : index
// CHECK: %[[VAL_17]] = br %[[VAL_155]] : none
// CHECK: %[[VAL_19]] = br %[[VAL_157]] : index
// CHECK: %[[VAL_158:.*]], %[[VAL_159:.*]] = control_merge %[[VAL_28]] : none
// CHECK: sink %[[VAL_159]] : index
// CHECK: return %[[VAL_158]] : none
// CHECK: }
// CHECK: }
func @more_imperfectly_nested_loops() {
%c0 = arith.constant 0 : index
%c42 = arith.constant 42 : index
%c1 = arith.constant 1 : index

View File

@ -1,106 +1,103 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_apply_loops_shorthand(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_apply_loops_shorthand(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (index) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_3]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.mux"(%[[VAL_11:.*]]#2, %[[VAL_12:.*]], %[[VAL_6]]) : (index, index, index) -> index
// CHECK: %[[VAL_13:.*]]:2 = "handshake.fork"(%[[VAL_10]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_14:.*]] = "handshake.mux"(%[[VAL_11]]#1, %[[VAL_15:.*]], %[[VAL_9]]) : (index, index, index) -> index
// CHECK: %[[VAL_16:.*]]:2 = "handshake.control_merge"(%[[VAL_17:.*]], %[[VAL_7]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_11]]:3 = "handshake.fork"(%[[VAL_16]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_18:.*]] = "handshake.mux"(%[[VAL_11]]#0, %[[VAL_19:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_20:.*]]:2 = "handshake.fork"(%[[VAL_18]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_20]]#1, %[[VAL_13]]#1 : index
// CHECK: %[[VAL_22:.*]]:4 = "handshake.fork"(%[[VAL_21]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = "handshake.conditional_branch"(%[[VAL_22]]#3, %[[VAL_13]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_24]]) : (index) -> ()
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = "handshake.conditional_branch"(%[[VAL_22]]#2, %[[VAL_14]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_26]]) : (index) -> ()
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = "handshake.conditional_branch"(%[[VAL_22]]#1, %[[VAL_16]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = "handshake.conditional_branch"(%[[VAL_22]]#0, %[[VAL_20]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_30]]) : (index) -> ()
// CHECK: %[[VAL_31:.*]] = "handshake.merge"(%[[VAL_29]]) : (index) -> index
// CHECK: %[[VAL_32:.*]]:2 = "handshake.fork"(%[[VAL_31]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_33:.*]] = "handshake.merge"(%[[VAL_25]]) : (index) -> index
// CHECK: %[[VAL_34:.*]] = "handshake.merge"(%[[VAL_23]]) : (index) -> index
// CHECK: %[[VAL_35:.*]]:2 = "handshake.control_merge"(%[[VAL_27]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_36:.*]]:3 = "handshake.fork"(%[[VAL_35]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_35]]#1) : (index) -> ()
// CHECK: %[[VAL_37:.*]] = "handshake.constant"(%[[VAL_36]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_38:.*]] = "handshake.constant"(%[[VAL_36]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_39:.*]] = "handshake.branch"(%[[VAL_32]]#1) {control = false} : (index) -> index
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_32]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_41:.*]] = "handshake.branch"(%[[VAL_33]]) {control = false} : (index) -> index
// CHECK: %[[VAL_42:.*]] = "handshake.branch"(%[[VAL_34]]) {control = false} : (index) -> index
// CHECK: %[[VAL_43:.*]] = "handshake.branch"(%[[VAL_36]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_44:.*]] = "handshake.branch"(%[[VAL_37]]) {control = false} : (index) -> index
// CHECK: %[[VAL_45:.*]] = "handshake.branch"(%[[VAL_38]]) {control = false} : (index) -> index
// CHECK: %[[VAL_46:.*]] = "handshake.mux"(%[[VAL_47:.*]]#5, %[[VAL_48:.*]], %[[VAL_44]]) : (index, index, index) -> index
// CHECK: %[[VAL_49:.*]]:2 = "handshake.fork"(%[[VAL_46]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_50:.*]] = "handshake.mux"(%[[VAL_47]]#4, %[[VAL_51:.*]], %[[VAL_45]]) : (index, index, index) -> index
// CHECK: %[[VAL_52:.*]] = "handshake.mux"(%[[VAL_47]]#3, %[[VAL_53:.*]], %[[VAL_40]]) : (index, index, index) -> index
// CHECK: %[[VAL_54:.*]] = "handshake.mux"(%[[VAL_47]]#2, %[[VAL_55:.*]], %[[VAL_41]]) : (index, index, index) -> index
// CHECK: %[[VAL_56:.*]] = "handshake.mux"(%[[VAL_47]]#1, %[[VAL_57:.*]], %[[VAL_42]]) : (index, index, index) -> index
// CHECK: %[[VAL_58:.*]]:2 = "handshake.control_merge"(%[[VAL_59:.*]], %[[VAL_43]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_47]]:6 = "handshake.fork"(%[[VAL_58]]#1) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_60:.*]] = "handshake.mux"(%[[VAL_47]]#0, %[[VAL_61:.*]], %[[VAL_39]]) : (index, index, index) -> index
// CHECK: %[[VAL_62:.*]]:2 = "handshake.fork"(%[[VAL_60]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_63:.*]] = arith.cmpi slt, %[[VAL_62]]#1, %[[VAL_49]]#1 : index
// CHECK: %[[VAL_64:.*]]:7 = "handshake.fork"(%[[VAL_63]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_65:.*]], %[[VAL_66:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#6, %[[VAL_49]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_66]]) : (index) -> ()
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#5, %[[VAL_50]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_68]]) : (index) -> ()
// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#4, %[[VAL_52]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_71:.*]], %[[VAL_72:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#3, %[[VAL_54]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_73:.*]], %[[VAL_74:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#2, %[[VAL_56]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_75:.*]], %[[VAL_76:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#1, %[[VAL_58]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = "handshake.conditional_branch"(%[[VAL_64]]#0, %[[VAL_62]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_78]]) : (index) -> ()
// CHECK: %[[VAL_79:.*]] = "handshake.merge"(%[[VAL_77]]) : (index) -> index
// CHECK: %[[VAL_80:.*]] = "handshake.merge"(%[[VAL_67]]) : (index) -> index
// CHECK: %[[VAL_81:.*]]:2 = "handshake.fork"(%[[VAL_80]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_82:.*]] = "handshake.merge"(%[[VAL_65]]) : (index) -> index
// CHECK: %[[VAL_83:.*]] = "handshake.merge"(%[[VAL_69]]) : (index) -> index
// CHECK: %[[VAL_84:.*]] = "handshake.merge"(%[[VAL_71]]) : (index) -> index
// CHECK: %[[VAL_85:.*]] = "handshake.merge"(%[[VAL_73]]) : (index) -> index
// CHECK: %[[VAL_86:.*]]:2 = "handshake.control_merge"(%[[VAL_75]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_86]]#1) : (index) -> ()
// CHECK: %[[VAL_87:.*]] = arith.addi %[[VAL_79]], %[[VAL_81]]#1 : index
// CHECK: %[[VAL_51]] = "handshake.branch"(%[[VAL_81]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_48]] = "handshake.branch"(%[[VAL_82]]) {control = false} : (index) -> index
// CHECK: %[[VAL_53]] = "handshake.branch"(%[[VAL_83]]) {control = false} : (index) -> index
// CHECK: %[[VAL_55]] = "handshake.branch"(%[[VAL_84]]) {control = false} : (index) -> index
// CHECK: %[[VAL_57]] = "handshake.branch"(%[[VAL_85]]) {control = false} : (index) -> index
// CHECK: %[[VAL_59]] = "handshake.branch"(%[[VAL_86]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_61]] = "handshake.branch"(%[[VAL_87]]) {control = false} : (index) -> index
// CHECK: %[[VAL_88:.*]] = "handshake.merge"(%[[VAL_70]]) : (index) -> index
// CHECK: %[[VAL_89:.*]] = "handshake.merge"(%[[VAL_72]]) : (index) -> index
// CHECK: %[[VAL_90:.*]]:2 = "handshake.fork"(%[[VAL_89]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_91:.*]] = "handshake.merge"(%[[VAL_74]]) : (index) -> index
// CHECK: %[[VAL_92:.*]]:2 = "handshake.control_merge"(%[[VAL_76]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_92]]#1) : (index) -> ()
// CHECK: %[[VAL_93:.*]] = arith.addi %[[VAL_88]], %[[VAL_90]]#1 : index
// CHECK: %[[VAL_15]] = "handshake.branch"(%[[VAL_90]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_12]] = "handshake.branch"(%[[VAL_91]]) {control = false} : (index) -> index
// CHECK: %[[VAL_17]] = "handshake.branch"(%[[VAL_92]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_19]] = "handshake.branch"(%[[VAL_93]]) {control = false} : (index) -> index
// CHECK: %[[VAL_94:.*]]:2 = "handshake.control_merge"(%[[VAL_28]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_94]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_94]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:3 = fork [3] %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_3]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_3]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_6:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_3]]#2 : none
// CHECK: %[[VAL_8:.*]] = br %[[VAL_4]] : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_10:.*]] = mux %[[VAL_11:.*]]#2 {{\[}}%[[VAL_12:.*]], %[[VAL_6]]] : index, index
// CHECK: %[[VAL_13:.*]]:2 = fork [2] %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]] = mux %[[VAL_11]]#1 {{\[}}%[[VAL_15:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = control_merge %[[VAL_18:.*]], %[[VAL_7]] : none
// CHECK: %[[VAL_11]]:3 = fork [3] %[[VAL_17]] : index
// CHECK: %[[VAL_19:.*]] = mux %[[VAL_11]]#0 {{\[}}%[[VAL_20:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_21:.*]]:2 = fork [2] %[[VAL_19]] : index
// CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_21]]#1, %[[VAL_13]]#1 : index
// CHECK: %[[VAL_23:.*]]:4 = fork [4] %[[VAL_22]] : i1
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = cond_br %[[VAL_23]]#3, %[[VAL_13]]#0 : index
// CHECK: sink %[[VAL_25]] : index
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_23]]#2, %[[VAL_14]] : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = cond_br %[[VAL_23]]#1, %[[VAL_16]] : none
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = cond_br %[[VAL_23]]#0, %[[VAL_21]]#0 : index
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]]:2 = fork [2] %[[VAL_32]] : index
// CHECK: %[[VAL_34:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_35:.*]] = merge %[[VAL_24]] : index
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = control_merge %[[VAL_28]] : none
// CHECK: %[[VAL_38:.*]]:3 = fork [3] %[[VAL_36]] : none
// CHECK: sink %[[VAL_37]] : index
// CHECK: %[[VAL_39:.*]] = constant %[[VAL_38]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_40:.*]] = constant %[[VAL_38]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_41:.*]] = br %[[VAL_33]]#1 : index
// CHECK: %[[VAL_42:.*]] = br %[[VAL_33]]#0 : index
// CHECK: %[[VAL_43:.*]] = br %[[VAL_34]] : index
// CHECK: %[[VAL_44:.*]] = br %[[VAL_35]] : index
// CHECK: %[[VAL_45:.*]] = br %[[VAL_38]]#2 : none
// CHECK: %[[VAL_46:.*]] = br %[[VAL_39]] : index
// CHECK: %[[VAL_47:.*]] = br %[[VAL_40]] : index
// CHECK: %[[VAL_48:.*]] = mux %[[VAL_49:.*]]#5 {{\[}}%[[VAL_50:.*]], %[[VAL_46]]] : index, index
// CHECK: %[[VAL_51:.*]]:2 = fork [2] %[[VAL_48]] : index
// CHECK: %[[VAL_52:.*]] = mux %[[VAL_49]]#4 {{\[}}%[[VAL_53:.*]], %[[VAL_47]]] : index, index
// CHECK: %[[VAL_54:.*]] = mux %[[VAL_49]]#3 {{\[}}%[[VAL_55:.*]], %[[VAL_42]]] : index, index
// CHECK: %[[VAL_56:.*]] = mux %[[VAL_49]]#2 {{\[}}%[[VAL_57:.*]], %[[VAL_43]]] : index, index
// CHECK: %[[VAL_58:.*]] = mux %[[VAL_49]]#1 {{\[}}%[[VAL_59:.*]], %[[VAL_44]]] : index, index
// CHECK: %[[VAL_60:.*]], %[[VAL_61:.*]] = control_merge %[[VAL_62:.*]], %[[VAL_45]] : none
// CHECK: %[[VAL_49]]:6 = fork [6] %[[VAL_61]] : index
// CHECK: %[[VAL_63:.*]] = mux %[[VAL_49]]#0 {{\[}}%[[VAL_64:.*]], %[[VAL_41]]] : index, index
// CHECK: %[[VAL_65:.*]]:2 = fork [2] %[[VAL_63]] : index
// CHECK: %[[VAL_66:.*]] = arith.cmpi slt, %[[VAL_65]]#1, %[[VAL_51]]#1 : index
// CHECK: %[[VAL_67:.*]]:7 = fork [7] %[[VAL_66]] : i1
// CHECK: %[[VAL_68:.*]], %[[VAL_69:.*]] = cond_br %[[VAL_67]]#6, %[[VAL_51]]#0 : index
// CHECK: sink %[[VAL_69]] : index
// CHECK: %[[VAL_70:.*]], %[[VAL_71:.*]] = cond_br %[[VAL_67]]#5, %[[VAL_52]] : index
// CHECK: sink %[[VAL_71]] : index
// CHECK: %[[VAL_72:.*]], %[[VAL_73:.*]] = cond_br %[[VAL_67]]#4, %[[VAL_54]] : index
// CHECK: %[[VAL_74:.*]], %[[VAL_75:.*]] = cond_br %[[VAL_67]]#3, %[[VAL_56]] : index
// CHECK: %[[VAL_76:.*]], %[[VAL_77:.*]] = cond_br %[[VAL_67]]#2, %[[VAL_58]] : index
// CHECK: %[[VAL_78:.*]], %[[VAL_79:.*]] = cond_br %[[VAL_67]]#1, %[[VAL_60]] : none
// CHECK: %[[VAL_80:.*]], %[[VAL_81:.*]] = cond_br %[[VAL_67]]#0, %[[VAL_65]]#0 : index
// CHECK: sink %[[VAL_81]] : index
// CHECK: %[[VAL_82:.*]] = merge %[[VAL_80]] : index
// CHECK: %[[VAL_83:.*]] = merge %[[VAL_70]] : index
// CHECK: %[[VAL_84:.*]]:2 = fork [2] %[[VAL_83]] : index
// CHECK: %[[VAL_85:.*]] = merge %[[VAL_68]] : index
// CHECK: %[[VAL_86:.*]] = merge %[[VAL_72]] : index
// CHECK: %[[VAL_87:.*]] = merge %[[VAL_74]] : index
// CHECK: %[[VAL_88:.*]] = merge %[[VAL_76]] : index
// CHECK: %[[VAL_89:.*]], %[[VAL_90:.*]] = control_merge %[[VAL_78]] : none
// CHECK: sink %[[VAL_90]] : index
// CHECK: %[[VAL_91:.*]] = arith.addi %[[VAL_82]], %[[VAL_84]]#1 : index
// CHECK: %[[VAL_53]] = br %[[VAL_84]]#0 : index
// CHECK: %[[VAL_50]] = br %[[VAL_85]] : index
// CHECK: %[[VAL_55]] = br %[[VAL_86]] : index
// CHECK: %[[VAL_57]] = br %[[VAL_87]] : index
// CHECK: %[[VAL_59]] = br %[[VAL_88]] : index
// CHECK: %[[VAL_62]] = br %[[VAL_89]] : none
// CHECK: %[[VAL_64]] = br %[[VAL_91]] : index
// CHECK: %[[VAL_92:.*]] = merge %[[VAL_73]] : index
// CHECK: %[[VAL_93:.*]] = merge %[[VAL_75]] : index
// CHECK: %[[VAL_94:.*]]:2 = fork [2] %[[VAL_93]] : index
// CHECK: %[[VAL_95:.*]] = merge %[[VAL_77]] : index
// CHECK: %[[VAL_96:.*]], %[[VAL_97:.*]] = control_merge %[[VAL_79]] : none
// CHECK: sink %[[VAL_97]] : index
// CHECK: %[[VAL_98:.*]] = arith.addi %[[VAL_92]], %[[VAL_94]]#1 : index
// CHECK: %[[VAL_15]] = br %[[VAL_94]]#0 : index
// CHECK: %[[VAL_12]] = br %[[VAL_95]] : index
// CHECK: %[[VAL_18]] = br %[[VAL_96]] : none
// CHECK: %[[VAL_20]] = br %[[VAL_98]] : index
// CHECK: %[[VAL_99:.*]], %[[VAL_100:.*]] = control_merge %[[VAL_29]] : none
// CHECK: sink %[[VAL_100]] : index
// CHECK: return %[[VAL_99]] : none
// CHECK: }
// CHECK: }
func @affine_apply_loops_shorthand(%arg0: index) {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
br ^bb1(%c0 : index)

View File

@ -1,78 +1,75 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_store(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_store(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.memory"(%[[VAL_3:.*]]#0, %[[VAL_3]]#1) {id = 0 : i32, ld_count = 0 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index) -> none
// CHECK: %[[VAL_4:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_5:.*]]:5 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none, none)
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_5]]#3) {value = 1.100000e+01 : f32} : (none) -> f32
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_5]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_5]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.constant"(%[[VAL_5]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_11:.*]] = "handshake.branch"(%[[VAL_5]]#4) {control = true} : (none) -> none
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_6]]) {control = false} : (f32) -> f32
// CHECK: %[[VAL_13:.*]] = "handshake.branch"(%[[VAL_7]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_15:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_16:.*]] = "handshake.mux"(%[[VAL_17:.*]]#4, %[[VAL_18:.*]], %[[VAL_14]]) : (index, index, index) -> index
// CHECK: %[[VAL_19:.*]]:2 = "handshake.fork"(%[[VAL_16]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_20:.*]] = "handshake.mux"(%[[VAL_17]]#3, %[[VAL_21:.*]], %[[VAL_10]]) : (index, index, index) -> index
// CHECK: %[[VAL_22:.*]] = "handshake.mux"(%[[VAL_17]]#2, %[[VAL_23:.*]], %[[VAL_12]]) : (index, f32, f32) -> f32
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_17]]#1, %[[VAL_25:.*]], %[[VAL_15]]) : (index, index, index) -> index
// CHECK: %[[VAL_26:.*]]:2 = "handshake.control_merge"(%[[VAL_27:.*]], %[[VAL_11]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_17]]:5 = "handshake.fork"(%[[VAL_26]]#1) {control = false} : (index) -> (index, index, index, index, index)
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_17]]#0, %[[VAL_29:.*]], %[[VAL_13]]) : (index, index, index) -> index
// CHECK: %[[VAL_30:.*]]:2 = "handshake.fork"(%[[VAL_28]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_31:.*]] = arith.cmpi slt, %[[VAL_30]]#1, %[[VAL_19]]#1 : index
// CHECK: %[[VAL_32:.*]]:6 = "handshake.fork"(%[[VAL_31]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_33:.*]], %[[VAL_34:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#5, %[[VAL_19]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_34]]) : (index) -> ()
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#4, %[[VAL_20]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_36]]) : (index) -> ()
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#3, %[[VAL_22]]) {control = false} : (i1, f32) -> (f32, f32)
// CHECK: "handshake.sink"(%[[VAL_38]]) : (f32) -> ()
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#2, %[[VAL_24]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_40]]) : (index) -> ()
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#1, %[[VAL_26]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#0, %[[VAL_30]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_44]]) : (index) -> ()
// CHECK: %[[VAL_45:.*]] = "handshake.merge"(%[[VAL_35]]) : (index) -> index
// CHECK: %[[VAL_46:.*]]:2 = "handshake.fork"(%[[VAL_45]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_47:.*]] = "handshake.merge"(%[[VAL_43]]) : (index) -> index
// CHECK: %[[VAL_48:.*]]:2 = "handshake.fork"(%[[VAL_47]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_49:.*]] = "handshake.merge"(%[[VAL_37]]) : (f32) -> f32
// CHECK: %[[VAL_50:.*]]:2 = "handshake.fork"(%[[VAL_49]]) {control = false} : (f32) -> (f32, f32)
// CHECK: %[[VAL_51:.*]] = "handshake.merge"(%[[VAL_39]]) : (index) -> index
// CHECK: %[[VAL_52:.*]]:2 = "handshake.fork"(%[[VAL_51]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_53:.*]] = "handshake.merge"(%[[VAL_33]]) : (index) -> index
// CHECK: %[[VAL_54:.*]]:2 = "handshake.control_merge"(%[[VAL_41]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_55:.*]]:2 = "handshake.fork"(%[[VAL_54]]#0) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_56:.*]]:3 = "handshake.fork"(%[[VAL_55]]#1) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_57:.*]] = "handshake.join"(%[[VAL_56]]#2, %[[VAL_2]]) {control = true} : (none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_54]]#1) : (index) -> ()
// CHECK: %[[VAL_58:.*]] = "handshake.constant"(%[[VAL_56]]#1) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_59:.*]] = arith.muli %[[VAL_46]]#1, %[[VAL_58]] : index
// CHECK: %[[VAL_60:.*]] = arith.addi %[[VAL_48]]#1, %[[VAL_59]] : index
// CHECK: %[[VAL_61:.*]] = "handshake.constant"(%[[VAL_56]]#0) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_62:.*]] = arith.addi %[[VAL_60]], %[[VAL_61]] : index
// CHECK: %[[VAL_3]]:2 = "handshake.store"(%[[VAL_50]]#1, %[[VAL_62]], %[[VAL_55]]#0) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_63:.*]] = arith.addi %[[VAL_48]]#0, %[[VAL_52]]#1 : index
// CHECK: %[[VAL_21]] = "handshake.branch"(%[[VAL_46]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_23]] = "handshake.branch"(%[[VAL_50]]#0) {control = false} : (f32) -> f32
// CHECK: %[[VAL_25]] = "handshake.branch"(%[[VAL_52]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_18]] = "handshake.branch"(%[[VAL_53]]) {control = false} : (index) -> index
// CHECK: %[[VAL_27]] = "handshake.branch"(%[[VAL_57]]) {control = true} : (none) -> none
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_63]]) {control = false} : (index) -> index
// CHECK: %[[VAL_64:.*]]:2 = "handshake.control_merge"(%[[VAL_42]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_64]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_64]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = memory[ld = 0, st = 1] (%[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index) -> none
// CHECK: %[[VAL_5:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_6:.*]]:5 = fork [5] %[[VAL_1]] : none
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_6]]#3 {value = 1.100000e+01 : f32} : f32
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_6]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_6]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_10:.*]] = constant %[[VAL_6]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_11:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_12:.*]] = br %[[VAL_6]]#4 : none
// CHECK: %[[VAL_13:.*]] = br %[[VAL_7]] : f32
// CHECK: %[[VAL_14:.*]] = br %[[VAL_8]] : index
// CHECK: %[[VAL_15:.*]] = br %[[VAL_9]] : index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_17:.*]] = mux %[[VAL_18:.*]]#4 {{\[}}%[[VAL_19:.*]], %[[VAL_15]]] : index, index
// CHECK: %[[VAL_20:.*]]:2 = fork [2] %[[VAL_17]] : index
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_18]]#3 {{\[}}%[[VAL_22:.*]], %[[VAL_11]]] : index, index
// CHECK: %[[VAL_23:.*]] = mux %[[VAL_18]]#2 {{\[}}%[[VAL_24:.*]], %[[VAL_13]]] : index, f32
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_18]]#1 {{\[}}%[[VAL_26:.*]], %[[VAL_16]]] : index, index
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = control_merge %[[VAL_29:.*]], %[[VAL_12]] : none
// CHECK: %[[VAL_18]]:5 = fork [5] %[[VAL_28]] : index
// CHECK: %[[VAL_30:.*]] = mux %[[VAL_18]]#0 {{\[}}%[[VAL_31:.*]], %[[VAL_14]]] : index, index
// CHECK: %[[VAL_32:.*]]:2 = fork [2] %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]] = arith.cmpi slt, %[[VAL_32]]#1, %[[VAL_20]]#1 : index
// CHECK: %[[VAL_34:.*]]:6 = fork [6] %[[VAL_33]] : i1
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = cond_br %[[VAL_34]]#5, %[[VAL_20]]#0 : index
// CHECK: sink %[[VAL_36]] : index
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = cond_br %[[VAL_34]]#4, %[[VAL_21]] : index
// CHECK: sink %[[VAL_38]] : index
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = cond_br %[[VAL_34]]#3, %[[VAL_23]] : f32
// CHECK: sink %[[VAL_40]] : f32
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = cond_br %[[VAL_34]]#2, %[[VAL_25]] : index
// CHECK: sink %[[VAL_42]] : index
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = cond_br %[[VAL_34]]#1, %[[VAL_27]] : none
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = cond_br %[[VAL_34]]#0, %[[VAL_32]]#0 : index
// CHECK: sink %[[VAL_46]] : index
// CHECK: %[[VAL_47:.*]] = merge %[[VAL_37]] : index
// CHECK: %[[VAL_48:.*]]:2 = fork [2] %[[VAL_47]] : index
// CHECK: %[[VAL_49:.*]] = merge %[[VAL_45]] : index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_49]] : index
// CHECK: %[[VAL_51:.*]] = merge %[[VAL_39]] : f32
// CHECK: %[[VAL_52:.*]]:2 = fork [2] %[[VAL_51]] : f32
// CHECK: %[[VAL_53:.*]] = merge %[[VAL_41]] : index
// CHECK: %[[VAL_54:.*]]:2 = fork [2] %[[VAL_53]] : index
// CHECK: %[[VAL_55:.*]] = merge %[[VAL_35]] : index
// CHECK: %[[VAL_56:.*]], %[[VAL_57:.*]] = control_merge %[[VAL_43]] : none
// CHECK: %[[VAL_58:.*]]:2 = fork [2] %[[VAL_56]] : none
// CHECK: %[[VAL_59:.*]]:3 = fork [3] %[[VAL_58]]#1 : none
// CHECK: %[[VAL_60:.*]] = join %[[VAL_59]]#2, %[[VAL_2]] : none
// CHECK: sink %[[VAL_57]] : index
// CHECK: %[[VAL_61:.*]] = constant %[[VAL_59]]#1 {value = -1 : index} : index
// CHECK: %[[VAL_62:.*]] = arith.muli %[[VAL_48]]#1, %[[VAL_61]] : index
// CHECK: %[[VAL_63:.*]] = arith.addi %[[VAL_50]]#1, %[[VAL_62]] : index
// CHECK: %[[VAL_64:.*]] = constant %[[VAL_59]]#0 {value = 7 : index} : index
// CHECK: %[[VAL_65:.*]] = arith.addi %[[VAL_63]], %[[VAL_64]] : index
// CHECK: %[[VAL_3]], %[[VAL_4]] = store {{\[}}%[[VAL_65]]] %[[VAL_52]]#1, %[[VAL_58]]#0 : index, f32
// CHECK: %[[VAL_66:.*]] = arith.addi %[[VAL_50]]#0, %[[VAL_54]]#1 : index
// CHECK: %[[VAL_22]] = br %[[VAL_48]]#0 : index
// CHECK: %[[VAL_24]] = br %[[VAL_52]]#0 : f32
// CHECK: %[[VAL_26]] = br %[[VAL_54]]#0 : index
// CHECK: %[[VAL_19]] = br %[[VAL_55]] : index
// CHECK: %[[VAL_29]] = br %[[VAL_60]] : none
// CHECK: %[[VAL_31]] = br %[[VAL_66]] : index
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = control_merge %[[VAL_44]] : none
// CHECK: sink %[[VAL_68]] : index
// CHECK: return %[[VAL_67]] : none
// CHECK: }
// CHECK: }
func @affine_store(%arg0: index) {
%0 = memref.alloc() : memref<10xf32>
%cst = arith.constant 1.100000e+01 : f32
%c0 = arith.constant 0 : index

View File

@ -1,69 +1,66 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_load(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_load(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:2 = "handshake.memory"(%[[VAL_3:.*]]) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 0 : i32, type = memref<10xf32>} : (index) -> (f32, none)
// CHECK: %[[VAL_4:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_5:.*]]:4 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_5]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_5]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_5]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.branch"(%[[VAL_5]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_11:.*]] = "handshake.branch"(%[[VAL_6]]) {control = false} : (index) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_7]]) {control = false} : (index) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14:.*]] = "handshake.mux"(%[[VAL_15:.*]]#3, %[[VAL_16:.*]], %[[VAL_12]]) : (index, index, index) -> index
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_14]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_18:.*]] = "handshake.mux"(%[[VAL_15]]#2, %[[VAL_19:.*]], %[[VAL_9]]) : (index, index, index) -> index
// CHECK: %[[VAL_20:.*]] = "handshake.mux"(%[[VAL_15]]#1, %[[VAL_21:.*]], %[[VAL_13]]) : (index, index, index) -> index
// CHECK: %[[VAL_22:.*]]:2 = "handshake.control_merge"(%[[VAL_23:.*]], %[[VAL_10]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_15]]:4 = "handshake.fork"(%[[VAL_22]]#1) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_15]]#0, %[[VAL_25:.*]], %[[VAL_11]]) : (index, index, index) -> index
// CHECK: %[[VAL_26:.*]]:2 = "handshake.fork"(%[[VAL_24]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_26]]#1, %[[VAL_17]]#1 : index
// CHECK: %[[VAL_28:.*]]:5 = "handshake.fork"(%[[VAL_27]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1)
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = "handshake.conditional_branch"(%[[VAL_28]]#4, %[[VAL_17]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_30]]) : (index) -> ()
// CHECK: %[[VAL_31:.*]], %[[VAL_32:.*]] = "handshake.conditional_branch"(%[[VAL_28]]#3, %[[VAL_18]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_32]]) : (index) -> ()
// CHECK: %[[VAL_33:.*]], %[[VAL_34:.*]] = "handshake.conditional_branch"(%[[VAL_28]]#2, %[[VAL_20]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_34]]) : (index) -> ()
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_28]]#1, %[[VAL_22]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = "handshake.conditional_branch"(%[[VAL_28]]#0, %[[VAL_26]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_38]]) : (index) -> ()
// CHECK: %[[VAL_39:.*]] = "handshake.merge"(%[[VAL_37]]) : (index) -> index
// CHECK: %[[VAL_40:.*]]:2 = "handshake.fork"(%[[VAL_39]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_41:.*]] = "handshake.merge"(%[[VAL_31]]) : (index) -> index
// CHECK: %[[VAL_42:.*]]:2 = "handshake.fork"(%[[VAL_41]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_43:.*]] = "handshake.merge"(%[[VAL_33]]) : (index) -> index
// CHECK: %[[VAL_44:.*]]:2 = "handshake.fork"(%[[VAL_43]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_45:.*]] = "handshake.merge"(%[[VAL_29]]) : (index) -> index
// CHECK: %[[VAL_46:.*]]:2 = "handshake.control_merge"(%[[VAL_35]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_47:.*]]:2 = "handshake.fork"(%[[VAL_46]]#0) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_48:.*]]:2 = "handshake.fork"(%[[VAL_47]]#1) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_49:.*]] = "handshake.join"(%[[VAL_48]]#1, %[[VAL_2]]#1) {control = true} : (none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_46]]#1) : (index) -> ()
// CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_40]]#1, %[[VAL_42]]#1 : index
// CHECK: %[[VAL_51:.*]] = "handshake.constant"(%[[VAL_48]]#0) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_52:.*]] = arith.addi %[[VAL_50]], %[[VAL_51]] : index
// CHECK: %[[VAL_53:.*]], %[[VAL_3]] = "handshake.load"(%[[VAL_52]], %[[VAL_2]]#0, %[[VAL_47]]#0) : (index, f32, none) -> (f32, index)
// CHECK: "handshake.sink"(%[[VAL_53]]) : (f32) -> ()
// CHECK: %[[VAL_54:.*]] = arith.addi %[[VAL_40]]#0, %[[VAL_44]]#1 : index
// CHECK: %[[VAL_19]] = "handshake.branch"(%[[VAL_42]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_21]] = "handshake.branch"(%[[VAL_44]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_45]]) {control = false} : (index) -> index
// CHECK: %[[VAL_23]] = "handshake.branch"(%[[VAL_49]]) {control = true} : (none) -> none
// CHECK: %[[VAL_25]] = "handshake.branch"(%[[VAL_54]]) {control = false} : (index) -> index
// CHECK: %[[VAL_55:.*]]:2 = "handshake.control_merge"(%[[VAL_36]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_55]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_55]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:2 = memory[ld = 1, st = 0] (%[[VAL_3:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (index) -> (f32, none)
// CHECK: %[[VAL_4:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_5:.*]]:4 = fork [4] %[[VAL_1]] : none
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_5]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_5]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_5]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_4]] : index
// CHECK: %[[VAL_10:.*]] = br %[[VAL_5]]#3 : none
// CHECK: %[[VAL_11:.*]] = br %[[VAL_6]] : index
// CHECK: %[[VAL_12:.*]] = br %[[VAL_7]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_8]] : index
// CHECK: %[[VAL_14:.*]] = mux %[[VAL_15:.*]]#3 {{\[}}%[[VAL_16:.*]], %[[VAL_12]]] : index, index
// CHECK: %[[VAL_17:.*]]:2 = fork [2] %[[VAL_14]] : index
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_15]]#2 {{\[}}%[[VAL_19:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_20:.*]] = mux %[[VAL_15]]#1 {{\[}}%[[VAL_21:.*]], %[[VAL_13]]] : index, index
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = control_merge %[[VAL_24:.*]], %[[VAL_10]] : none
// CHECK: %[[VAL_15]]:4 = fork [4] %[[VAL_23]] : index
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_15]]#0 {{\[}}%[[VAL_26:.*]], %[[VAL_11]]] : index, index
// CHECK: %[[VAL_27:.*]]:2 = fork [2] %[[VAL_25]] : index
// CHECK: %[[VAL_28:.*]] = arith.cmpi slt, %[[VAL_27]]#1, %[[VAL_17]]#1 : index
// CHECK: %[[VAL_29:.*]]:5 = fork [5] %[[VAL_28]] : i1
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = cond_br %[[VAL_29]]#4, %[[VAL_17]]#0 : index
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = cond_br %[[VAL_29]]#3, %[[VAL_18]] : index
// CHECK: sink %[[VAL_33]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = cond_br %[[VAL_29]]#2, %[[VAL_20]] : index
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = cond_br %[[VAL_29]]#1, %[[VAL_22]] : none
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = cond_br %[[VAL_29]]#0, %[[VAL_27]]#0 : index
// CHECK: sink %[[VAL_39]] : index
// CHECK: %[[VAL_40:.*]] = merge %[[VAL_38]] : index
// CHECK: %[[VAL_41:.*]]:2 = fork [2] %[[VAL_40]] : index
// CHECK: %[[VAL_42:.*]] = merge %[[VAL_32]] : index
// CHECK: %[[VAL_43:.*]]:2 = fork [2] %[[VAL_42]] : index
// CHECK: %[[VAL_44:.*]] = merge %[[VAL_34]] : index
// CHECK: %[[VAL_45:.*]]:2 = fork [2] %[[VAL_44]] : index
// CHECK: %[[VAL_46:.*]] = merge %[[VAL_30]] : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge %[[VAL_36]] : none
// CHECK: %[[VAL_49:.*]]:2 = fork [2] %[[VAL_47]] : none
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_49]]#1 : none
// CHECK: %[[VAL_51:.*]] = join %[[VAL_50]]#1, %[[VAL_2]]#1 : none
// CHECK: sink %[[VAL_48]] : index
// CHECK: %[[VAL_52:.*]] = arith.addi %[[VAL_41]]#1, %[[VAL_43]]#1 : index
// CHECK: %[[VAL_53:.*]] = constant %[[VAL_50]]#0 {value = 7 : index} : index
// CHECK: %[[VAL_54:.*]] = arith.addi %[[VAL_52]], %[[VAL_53]] : index
// CHECK: %[[VAL_55:.*]], %[[VAL_3]] = load {{\[}}%[[VAL_54]]] %[[VAL_2]]#0, %[[VAL_49]]#0 : index, f32
// CHECK: sink %[[VAL_55]] : f32
// CHECK: %[[VAL_56:.*]] = arith.addi %[[VAL_41]]#0, %[[VAL_45]]#1 : index
// CHECK: %[[VAL_19]] = br %[[VAL_43]]#0 : index
// CHECK: %[[VAL_21]] = br %[[VAL_45]]#0 : index
// CHECK: %[[VAL_16]] = br %[[VAL_46]] : index
// CHECK: %[[VAL_24]] = br %[[VAL_51]] : none
// CHECK: %[[VAL_26]] = br %[[VAL_56]] : index
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = control_merge %[[VAL_37]] : none
// CHECK: sink %[[VAL_58]] : index
// CHECK: return %[[VAL_57]] : none
// CHECK: }
// CHECK: }
func @affine_load(%arg0: index) {
%0 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%c10 = arith.constant 10 : index

View File

@ -1,32 +1,29 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_apply_ceildiv(%arg0: index) -> index {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_apply_ceildiv(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> (index, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_4:.*]]:4 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_4]]#2) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_4]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_6]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_4]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]]:2 = "handshake.fork"(%[[VAL_8]]) {control = false} : (index) -> (index, index)
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> (index, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:3 = fork [3] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]]:4 = fork [4] %[[VAL_1]] : none
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#2 {value = 42 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_4]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_7:.*]]:3 = fork [3] %[[VAL_6]] : index
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_4]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_9:.*]]:2 = fork [2] %[[VAL_8]] : index
// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_3]]#2, %[[VAL_7]]#0 : index
// CHECK: %[[VAL_11:.*]]:2 = "handshake.fork"(%[[VAL_10]]) {control = false} : (i1) -> (i1, i1)
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_10]] : i1
// CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_7]]#1, %[[VAL_3]]#1 : index
// CHECK: %[[VAL_13:.*]] = arith.subi %[[VAL_3]]#0, %[[VAL_9]]#0 : index
// CHECK: %[[VAL_14:.*]] = select %[[VAL_11]]#1, %[[VAL_12]], %[[VAL_13]] : index
// CHECK: %[[VAL_14:.*]] = std.select %[[VAL_11]]#1, %[[VAL_12]], %[[VAL_13]] : index
// CHECK: %[[VAL_15:.*]] = arith.divsi %[[VAL_14]], %[[VAL_5]] : index
// CHECK: %[[VAL_16:.*]]:2 = "handshake.fork"(%[[VAL_15]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_16:.*]]:2 = fork [2] %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_7]]#2, %[[VAL_16]]#1 : index
// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_16]]#0, %[[VAL_9]]#1 : index
// CHECK: %[[VAL_19:.*]] = select %[[VAL_11]]#0, %[[VAL_17]], %[[VAL_18]] : index
// CHECK: handshake.return %[[VAL_19]], %[[VAL_4]]#3 : index, none
// CHECK: %[[VAL_19:.*]] = std.select %[[VAL_11]]#0, %[[VAL_17]], %[[VAL_18]] : index
// CHECK: return %[[VAL_19]], %[[VAL_4]]#3 : index, none
// CHECK: }
// CHECK: }
func @affine_apply_ceildiv(%arg0: index) -> index {
%c42 = arith.constant 42 : index
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index

View File

@ -1,29 +1,26 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_apply_floordiv(%arg0: index) -> index {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_apply_floordiv(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> (index, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_4:.*]]:4 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_4]]#2) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_4]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_4]]#0) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_8:.*]]:2 = "handshake.fork"(%[[VAL_7]]) {control = false} : (index) -> (index, index)
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> (index, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:3 = fork [3] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]]:4 = fork [4] %[[VAL_1]] : none
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#2 {value = 42 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_4]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_4]]#0 {value = -1 : index} : index
// CHECK: %[[VAL_8:.*]]:2 = fork [2] %[[VAL_7]] : index
// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_3]]#2, %[[VAL_6]] : index
// CHECK: %[[VAL_10:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (i1) -> (i1, i1)
// CHECK: %[[VAL_10:.*]]:2 = fork [2] %[[VAL_9]] : i1
// CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_8]]#0, %[[VAL_3]]#1 : index
// CHECK: %[[VAL_12:.*]] = select %[[VAL_10]]#1, %[[VAL_11]], %[[VAL_3]]#0 : index
// CHECK: %[[VAL_12:.*]] = std.select %[[VAL_10]]#1, %[[VAL_11]], %[[VAL_3]]#0 : index
// CHECK: %[[VAL_13:.*]] = arith.divsi %[[VAL_12]], %[[VAL_5]] : index
// CHECK: %[[VAL_14:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_14:.*]]:2 = fork [2] %[[VAL_13]] : index
// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_8]]#1, %[[VAL_14]]#1 : index
// CHECK: %[[VAL_16:.*]] = select %[[VAL_10]]#0, %[[VAL_15]], %[[VAL_14]]#0 : index
// CHECK: handshake.return %[[VAL_16]], %[[VAL_4]]#3 : index, none
// CHECK: %[[VAL_16:.*]] = std.select %[[VAL_10]]#0, %[[VAL_15]], %[[VAL_14]]#0 : index
// CHECK: return %[[VAL_16]], %[[VAL_4]]#3 : index, none
// CHECK: }
// CHECK: }
func @affine_apply_floordiv(%arg0: index) -> index {
%c42 = arith.constant 42 : index
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index

View File

@ -1,24 +1,21 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_apply_mod(%arg0: index) -> index {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_apply_mod(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> (index, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_4]]) {control = false} : (index) -> (index, index)
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> (index, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:3 = fork [3] %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_3]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_5:.*]]:2 = fork [2] %[[VAL_4]] : index
// CHECK: %[[VAL_6:.*]] = arith.remsi %[[VAL_2]], %[[VAL_5]]#0 : index
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_6]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]]:3 = fork [3] %[[VAL_6]] : index
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_3]]#0 {value = 0 : index} : index
// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_7]]#2, %[[VAL_8]] : index
// CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_7]]#1, %[[VAL_5]]#1 : index
// CHECK: %[[VAL_11:.*]] = select %[[VAL_9]], %[[VAL_10]], %[[VAL_7]]#0 : index
// CHECK: handshake.return %[[VAL_11]], %[[VAL_3]]#2 : index, none
// CHECK: %[[VAL_11:.*]] = std.select %[[VAL_9]], %[[VAL_10]], %[[VAL_7]]#0 : index
// CHECK: return %[[VAL_11]], %[[VAL_3]]#2 : index, none
// CHECK: }
// CHECK: }
func @affine_apply_mod(%arg0: index) -> index {
%c42 = arith.constant 42 : index
%0 = arith.remsi %arg0, %c42 : index
%c0 = arith.constant 0 : index

View File

@ -1,51 +1,47 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_applies() {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_applies(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:18 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#16) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_1]]#15) {value = 101 : index} : (none) -> index
// CHECK: "handshake.sink"(%[[VAL_4]]) : (index) -> ()
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_1]]#14) {value = 102 : index} : (none) -> index
// CHECK: "handshake.sink"(%[[VAL_5]]) : (index) -> ()
// CHECK: %[[VAL_1:.*]]:18 = fork [18] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#16 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]]:2 = fork [2] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#15 {value = 101 : index} : index
// CHECK: sink %[[VAL_4]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_1]]#14 {value = 102 : index} : index
// CHECK: sink %[[VAL_5]] : index
// CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_3]]#0, %[[VAL_3]]#1 : index
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_1]]#13) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_1]]#13 {value = 1 : index} : index
// CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_6]], %[[VAL_7]] : index
// CHECK: "handshake.sink"(%[[VAL_8]]) : (index) -> ()
// CHECK: %[[VAL_9:.*]] = "handshake.constant"(%[[VAL_1]]#12) {value = 103 : index} : (none) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.constant"(%[[VAL_1]]#11) {value = 104 : index} : (none) -> index
// CHECK: %[[VAL_11:.*]] = "handshake.constant"(%[[VAL_1]]#10) {value = 105 : index} : (none) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.constant"(%[[VAL_1]]#9) {value = 106 : index} : (none) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.constant"(%[[VAL_1]]#8) {value = 107 : index} : (none) -> index
// CHECK: %[[VAL_14:.*]] = "handshake.constant"(%[[VAL_1]]#7) {value = 108 : index} : (none) -> index
// CHECK: %[[VAL_15:.*]] = "handshake.constant"(%[[VAL_1]]#6) {value = 109 : index} : (none) -> index
// CHECK: %[[VAL_16:.*]] = "handshake.constant"(%[[VAL_1]]#5) {value = 2 : index} : (none) -> index
// CHECK: sink %[[VAL_8]] : index
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_1]]#12 {value = 103 : index} : index
// CHECK: %[[VAL_10:.*]] = constant %[[VAL_1]]#11 {value = 104 : index} : index
// CHECK: %[[VAL_11:.*]] = constant %[[VAL_1]]#10 {value = 105 : index} : index
// CHECK: %[[VAL_12:.*]] = constant %[[VAL_1]]#9 {value = 106 : index} : index
// CHECK: %[[VAL_13:.*]] = constant %[[VAL_1]]#8 {value = 107 : index} : index
// CHECK: %[[VAL_14:.*]] = constant %[[VAL_1]]#7 {value = 108 : index} : index
// CHECK: %[[VAL_15:.*]] = constant %[[VAL_1]]#6 {value = 109 : index} : index
// CHECK: %[[VAL_16:.*]] = constant %[[VAL_1]]#5 {value = 2 : index} : index
// CHECK: %[[VAL_17:.*]] = arith.muli %[[VAL_10]], %[[VAL_16]] : index
// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_9]], %[[VAL_17]] : index
// CHECK: %[[VAL_19:.*]] = "handshake.constant"(%[[VAL_1]]#4) {value = 3 : index} : (none) -> index
// CHECK: %[[VAL_19:.*]] = constant %[[VAL_1]]#4 {value = 3 : index} : index
// CHECK: %[[VAL_20:.*]] = arith.muli %[[VAL_11]], %[[VAL_19]] : index
// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_18]], %[[VAL_20]] : index
// CHECK: %[[VAL_22:.*]] = "handshake.constant"(%[[VAL_1]]#3) {value = 4 : index} : (none) -> index
// CHECK: %[[VAL_22:.*]] = constant %[[VAL_1]]#3 {value = 4 : index} : index
// CHECK: %[[VAL_23:.*]] = arith.muli %[[VAL_12]], %[[VAL_22]] : index
// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_21]], %[[VAL_23]] : index
// CHECK: %[[VAL_25:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 5 : index} : (none) -> index
// CHECK: %[[VAL_25:.*]] = constant %[[VAL_1]]#2 {value = 5 : index} : index
// CHECK: %[[VAL_26:.*]] = arith.muli %[[VAL_13]], %[[VAL_25]] : index
// CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_24]], %[[VAL_26]] : index
// CHECK: %[[VAL_28:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = 6 : index} : (none) -> index
// CHECK: %[[VAL_28:.*]] = constant %[[VAL_1]]#1 {value = 6 : index} : index
// CHECK: %[[VAL_29:.*]] = arith.muli %[[VAL_14]], %[[VAL_28]] : index
// CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_27]], %[[VAL_29]] : index
// CHECK: %[[VAL_31:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_31:.*]] = constant %[[VAL_1]]#0 {value = 7 : index} : index
// CHECK: %[[VAL_32:.*]] = arith.muli %[[VAL_15]], %[[VAL_31]] : index
// CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_30]], %[[VAL_32]] : index
// CHECK: "handshake.sink"(%[[VAL_33]]) : (index) -> ()
// CHECK: handshake.return %[[VAL_1]]#17 : none
// CHECK: sink %[[VAL_33]] : index
// CHECK: return %[[VAL_1]]#17 : none
// CHECK: }
// CHECK: }
func @affine_applies() {
%c0 = arith.constant 0 : index
%c101 = arith.constant 101 : index
%c102 = arith.constant 102 : index

View File

@ -1,99 +1,94 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @imperfectly_nested_loops() {
// CHECK: module {
// CHECK-LABEL: handshake.func @imperfectly_nested_loops(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = "handshake.branch"(%[[VAL_0]]) {control = true} : (none) -> none
// CHECK: %[[VAL_2:.*]]:2 = "handshake.control_merge"(%[[VAL_1]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_2]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_2]]#1) : (index) -> ()
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_3]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.mux"(%[[VAL_10:.*]]#1, %[[VAL_11:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_14:.*]], %[[VAL_6]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_10]]:2 = "handshake.fork"(%[[VAL_13]]#1) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.mux"(%[[VAL_10]]#0, %[[VAL_16:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_15]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_17]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_19:.*]]:3 = "handshake.fork"(%[[VAL_18]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#2, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_21]]) : (index) -> ()
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#1, %[[VAL_13]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#0, %[[VAL_17]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_27:.*]] = "handshake.merge"(%[[VAL_20]]) : (index) -> index
// CHECK: %[[VAL_28:.*]]:2 = "handshake.control_merge"(%[[VAL_22]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_28]]#1) : (index) -> ()
// CHECK: %[[VAL_29:.*]] = "handshake.branch"(%[[VAL_26]]) {control = false} : (index) -> index
// CHECK: %[[VAL_30:.*]] = "handshake.branch"(%[[VAL_27]]) {control = false} : (index) -> index
// CHECK: %[[VAL_31:.*]] = "handshake.branch"(%[[VAL_28]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_32:.*]] = "handshake.merge"(%[[VAL_29]]) : (index) -> index
// CHECK: %[[VAL_33:.*]] = "handshake.merge"(%[[VAL_30]]) : (index) -> index
// CHECK: %[[VAL_34:.*]]:2 = "handshake.control_merge"(%[[VAL_31]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_35:.*]]:3 = "handshake.fork"(%[[VAL_34]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_34]]#1) : (index) -> ()
// CHECK: %[[VAL_36:.*]] = "handshake.constant"(%[[VAL_35]]#1) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_37:.*]] = "handshake.constant"(%[[VAL_35]]#0) {value = 56 : index} : (none) -> index
// CHECK: %[[VAL_38:.*]] = "handshake.branch"(%[[VAL_32]]) {control = false} : (index) -> index
// CHECK: %[[VAL_39:.*]] = "handshake.branch"(%[[VAL_33]]) {control = false} : (index) -> index
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_35]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_41:.*]] = "handshake.branch"(%[[VAL_36]]) {control = false} : (index) -> index
// CHECK: %[[VAL_42:.*]] = "handshake.branch"(%[[VAL_37]]) {control = false} : (index) -> index
// CHECK: %[[VAL_43:.*]] = "handshake.mux"(%[[VAL_44:.*]]#3, %[[VAL_45:.*]], %[[VAL_42]]) : (index, index, index) -> index
// CHECK: %[[VAL_46:.*]]:2 = "handshake.fork"(%[[VAL_43]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_47:.*]] = "handshake.mux"(%[[VAL_44]]#2, %[[VAL_48:.*]], %[[VAL_38]]) : (index, index, index) -> index
// CHECK: %[[VAL_49:.*]] = "handshake.mux"(%[[VAL_44]]#1, %[[VAL_50:.*]], %[[VAL_39]]) : (index, index, index) -> index
// CHECK: %[[VAL_51:.*]]:2 = "handshake.control_merge"(%[[VAL_52:.*]], %[[VAL_40]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_44]]:4 = "handshake.fork"(%[[VAL_51]]#1) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_53:.*]] = "handshake.mux"(%[[VAL_44]]#0, %[[VAL_54:.*]], %[[VAL_41]]) : (index, index, index) -> index
// CHECK: %[[VAL_55:.*]]:2 = "handshake.fork"(%[[VAL_53]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_56:.*]] = arith.cmpi slt, %[[VAL_55]]#1, %[[VAL_46]]#1 : index
// CHECK: %[[VAL_57:.*]]:5 = "handshake.fork"(%[[VAL_56]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1)
// CHECK: %[[VAL_58:.*]], %[[VAL_59:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#4, %[[VAL_46]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_59]]) : (index) -> ()
// CHECK: %[[VAL_60:.*]], %[[VAL_61:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#3, %[[VAL_47]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_62:.*]], %[[VAL_63:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#2, %[[VAL_49]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#1, %[[VAL_51]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#0, %[[VAL_55]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_67]]) : (index) -> ()
// CHECK: %[[VAL_68:.*]] = "handshake.merge"(%[[VAL_66]]) : (index) -> index
// CHECK: %[[VAL_69:.*]] = "handshake.merge"(%[[VAL_58]]) : (index) -> index
// CHECK: %[[VAL_70:.*]] = "handshake.merge"(%[[VAL_60]]) : (index) -> index
// CHECK: %[[VAL_71:.*]] = "handshake.merge"(%[[VAL_62]]) : (index) -> index
// CHECK: %[[VAL_72:.*]]:2 = "handshake.control_merge"(%[[VAL_64]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_73:.*]]:2 = "handshake.fork"(%[[VAL_72]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_72]]#1) : (index) -> ()
// CHECK: %[[VAL_74:.*]] = "handshake.constant"(%[[VAL_73]]#0) {value = 2 : index} : (none) -> index
// CHECK: %[[VAL_75:.*]] = arith.addi %[[VAL_68]], %[[VAL_74]] : index
// CHECK: %[[VAL_45]] = "handshake.branch"(%[[VAL_69]]) {control = false} : (index) -> index
// CHECK: %[[VAL_48]] = "handshake.branch"(%[[VAL_70]]) {control = false} : (index) -> index
// CHECK: %[[VAL_50]] = "handshake.branch"(%[[VAL_71]]) {control = false} : (index) -> index
// CHECK: %[[VAL_52]] = "handshake.branch"(%[[VAL_73]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_54]] = "handshake.branch"(%[[VAL_75]]) {control = false} : (index) -> index
// CHECK: %[[VAL_76:.*]] = "handshake.merge"(%[[VAL_61]]) : (index) -> index
// CHECK: %[[VAL_77:.*]] = "handshake.merge"(%[[VAL_63]]) : (index) -> index
// CHECK: %[[VAL_78:.*]]:2 = "handshake.control_merge"(%[[VAL_65]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_79:.*]]:2 = "handshake.fork"(%[[VAL_78]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_78]]#1) : (index) -> ()
// CHECK: %[[VAL_80:.*]] = "handshake.constant"(%[[VAL_79]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_76]], %[[VAL_80]] : index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_77]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_79]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_81]]) {control = false} : (index) -> index
// CHECK: %[[VAL_82:.*]]:2 = "handshake.control_merge"(%[[VAL_23]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_82]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_82]]#0 : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:3 = fork [3] %[[VAL_2]] : none
// CHECK: sink %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_4]]#0 {value = 42 : index} : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_4]]#2 : none
// CHECK: %[[VAL_8:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_6]] : index
// CHECK: %[[VAL_10:.*]] = mux %[[VAL_11:.*]]#1 {{\[}}%[[VAL_12:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_13:.*]]:2 = fork [2] %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_16:.*]], %[[VAL_7]] : none
// CHECK: %[[VAL_11]]:2 = fork [2] %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]] = mux %[[VAL_11]]#0 {{\[}}%[[VAL_18:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_19:.*]]:2 = fork [2] %[[VAL_17]] : index
// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_19]]#1, %[[VAL_13]]#1 : index
// CHECK: %[[VAL_21:.*]]:3 = fork [3] %[[VAL_20]] : i1
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = cond_br %[[VAL_21]]#2, %[[VAL_13]]#0 : index
// CHECK: sink %[[VAL_23]] : index
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = cond_br %[[VAL_21]]#1, %[[VAL_14]] : none
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_21]]#0, %[[VAL_19]]#0 : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_29:.*]] = merge %[[VAL_22]] : index
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_24]] : none
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]] = br %[[VAL_28]] : index
// CHECK: %[[VAL_33:.*]] = br %[[VAL_29]] : index
// CHECK: %[[VAL_34:.*]] = br %[[VAL_30]] : none
// CHECK: %[[VAL_35:.*]] = merge %[[VAL_32]] : index
// CHECK: %[[VAL_36:.*]] = merge %[[VAL_33]] : index
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = control_merge %[[VAL_34]] : none
// CHECK: %[[VAL_39:.*]]:3 = fork [3] %[[VAL_37]] : none
// CHECK: sink %[[VAL_38]] : index
// CHECK: %[[VAL_40:.*]] = constant %[[VAL_39]]#1 {value = 7 : index} : index
// CHECK: %[[VAL_41:.*]] = constant %[[VAL_39]]#0 {value = 56 : index} : index
// CHECK: %[[VAL_42:.*]] = br %[[VAL_35]] : index
// CHECK: %[[VAL_43:.*]] = br %[[VAL_36]] : index
// CHECK: %[[VAL_44:.*]] = br %[[VAL_39]]#2 : none
// CHECK: %[[VAL_45:.*]] = br %[[VAL_40]] : index
// CHECK: %[[VAL_46:.*]] = br %[[VAL_41]] : index
// CHECK: %[[VAL_47:.*]] = mux %[[VAL_48:.*]]#3 {{\[}}%[[VAL_49:.*]], %[[VAL_46]]] : index, index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_47]] : index
// CHECK: %[[VAL_51:.*]] = mux %[[VAL_48]]#2 {{\[}}%[[VAL_52:.*]], %[[VAL_42]]] : index, index
// CHECK: %[[VAL_53:.*]] = mux %[[VAL_48]]#1 {{\[}}%[[VAL_54:.*]], %[[VAL_43]]] : index, index
// CHECK: %[[VAL_55:.*]], %[[VAL_56:.*]] = control_merge %[[VAL_57:.*]], %[[VAL_44]] : none
// CHECK: %[[VAL_48]]:4 = fork [4] %[[VAL_56]] : index
// CHECK: %[[VAL_58:.*]] = mux %[[VAL_48]]#0 {{\[}}%[[VAL_59:.*]], %[[VAL_45]]] : index, index
// CHECK: %[[VAL_60:.*]]:2 = fork [2] %[[VAL_58]] : index
// CHECK: %[[VAL_61:.*]] = arith.cmpi slt, %[[VAL_60]]#1, %[[VAL_50]]#1 : index
// CHECK: %[[VAL_62:.*]]:5 = fork [5] %[[VAL_61]] : i1
// CHECK: %[[VAL_63:.*]], %[[VAL_64:.*]] = cond_br %[[VAL_62]]#4, %[[VAL_50]]#0 : index
// CHECK: sink %[[VAL_64]] : index
// CHECK: %[[VAL_65:.*]], %[[VAL_66:.*]] = cond_br %[[VAL_62]]#3, %[[VAL_51]] : index
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = cond_br %[[VAL_62]]#2, %[[VAL_53]] : index
// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = cond_br %[[VAL_62]]#1, %[[VAL_55]] : none
// CHECK: %[[VAL_71:.*]], %[[VAL_72:.*]] = cond_br %[[VAL_62]]#0, %[[VAL_60]]#0 : index
// CHECK: sink %[[VAL_72]] : index
// CHECK: %[[VAL_73:.*]] = merge %[[VAL_71]] : index
// CHECK: %[[VAL_74:.*]] = merge %[[VAL_63]] : index
// CHECK: %[[VAL_75:.*]] = merge %[[VAL_65]] : index
// CHECK: %[[VAL_76:.*]] = merge %[[VAL_67]] : index
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = control_merge %[[VAL_69]] : none
// CHECK: %[[VAL_79:.*]]:2 = fork [2] %[[VAL_77]] : none
// CHECK: sink %[[VAL_78]] : index
// CHECK: %[[VAL_80:.*]] = constant %[[VAL_79]]#0 {value = 2 : index} : index
// CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_73]], %[[VAL_80]] : index
// CHECK: %[[VAL_49]] = br %[[VAL_74]] : index
// CHECK: %[[VAL_52]] = br %[[VAL_75]] : index
// CHECK: %[[VAL_54]] = br %[[VAL_76]] : index
// CHECK: %[[VAL_57]] = br %[[VAL_79]]#1 : none
// CHECK: %[[VAL_59]] = br %[[VAL_81]] : index
// CHECK: %[[VAL_82:.*]] = merge %[[VAL_66]] : index
// CHECK: %[[VAL_83:.*]] = merge %[[VAL_68]] : index
// CHECK: %[[VAL_84:.*]], %[[VAL_85:.*]] = control_merge %[[VAL_70]] : none
// CHECK: %[[VAL_86:.*]]:2 = fork [2] %[[VAL_84]] : none
// CHECK: sink %[[VAL_85]] : index
// CHECK: %[[VAL_87:.*]] = constant %[[VAL_86]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_88:.*]] = arith.addi %[[VAL_82]], %[[VAL_87]] : index
// CHECK: %[[VAL_12]] = br %[[VAL_83]] : index
// CHECK: %[[VAL_16]] = br %[[VAL_86]]#1 : none
// CHECK: %[[VAL_18]] = br %[[VAL_88]] : index
// CHECK: %[[VAL_89:.*]], %[[VAL_90:.*]] = control_merge %[[VAL_25]] : none
// CHECK: sink %[[VAL_90]] : index
// CHECK: return %[[VAL_89]] : none
// CHECK: }
// CHECK: }
func @imperfectly_nested_loops() {
^bb0:
br ^bb1
^bb1: // pred: ^bb0

View File

@ -1,69 +1,66 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @min_reduction_tree(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @min_reduction_tree(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:14 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index, index, index, index, index, index, index, index, index, index, index, index, index)
// CHECK: %[[VAL_4:.*]]:3 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_4]]#1) {value = 0 : index} : (none) -> index
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:14 = fork [14] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]]:3 = fork [3] %[[VAL_1]] : none
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_6:.*]] = arith.cmpi slt, %[[VAL_3]]#12, %[[VAL_3]]#13 : index
// CHECK: %[[VAL_7:.*]] = select %[[VAL_6]], %[[VAL_3]]#10, %[[VAL_3]]#11 : index
// CHECK: %[[VAL_8:.*]]:2 = "handshake.fork"(%[[VAL_7]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_7:.*]] = std.select %[[VAL_6]], %[[VAL_3]]#10, %[[VAL_3]]#11 : index
// CHECK: %[[VAL_8:.*]]:2 = fork [2] %[[VAL_7]] : index
// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]]#1, %[[VAL_3]]#9 : index
// CHECK: %[[VAL_10:.*]] = select %[[VAL_9]], %[[VAL_8]]#0, %[[VAL_3]]#8 : index
// CHECK: %[[VAL_11:.*]]:2 = "handshake.fork"(%[[VAL_10]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_10:.*]] = std.select %[[VAL_9]], %[[VAL_8]]#0, %[[VAL_3]]#8 : index
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_10]] : index
// CHECK: %[[VAL_12:.*]] = arith.cmpi slt, %[[VAL_11]]#1, %[[VAL_3]]#7 : index
// CHECK: %[[VAL_13:.*]] = select %[[VAL_12]], %[[VAL_11]]#0, %[[VAL_3]]#6 : index
// CHECK: %[[VAL_14:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]] = std.select %[[VAL_12]], %[[VAL_11]]#0, %[[VAL_3]]#6 : index
// CHECK: %[[VAL_14:.*]]:2 = fork [2] %[[VAL_13]] : index
// CHECK: %[[VAL_15:.*]] = arith.cmpi slt, %[[VAL_14]]#1, %[[VAL_3]]#5 : index
// CHECK: %[[VAL_16:.*]] = select %[[VAL_15]], %[[VAL_14]]#0, %[[VAL_3]]#4 : index
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_16]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_16:.*]] = std.select %[[VAL_15]], %[[VAL_14]]#0, %[[VAL_3]]#4 : index
// CHECK: %[[VAL_17:.*]]:2 = fork [2] %[[VAL_16]] : index
// CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_17]]#1, %[[VAL_3]]#3 : index
// CHECK: %[[VAL_19:.*]] = select %[[VAL_18]], %[[VAL_17]]#0, %[[VAL_3]]#2 : index
// CHECK: %[[VAL_20:.*]]:2 = "handshake.fork"(%[[VAL_19]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_19:.*]] = std.select %[[VAL_18]], %[[VAL_17]]#0, %[[VAL_3]]#2 : index
// CHECK: %[[VAL_20:.*]]:2 = fork [2] %[[VAL_19]] : index
// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_20]]#1, %[[VAL_3]]#1 : index
// CHECK: %[[VAL_22:.*]] = select %[[VAL_21]], %[[VAL_20]]#0, %[[VAL_3]]#0 : index
// CHECK: %[[VAL_23:.*]] = "handshake.constant"(%[[VAL_4]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_24:.*]] = "handshake.branch"(%[[VAL_4]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_25:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_26:.*]] = "handshake.branch"(%[[VAL_22]]) {control = false} : (index) -> index
// CHECK: %[[VAL_27:.*]] = "handshake.branch"(%[[VAL_23]]) {control = false} : (index) -> index
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_29:.*]]#2, %[[VAL_30:.*]], %[[VAL_26]]) : (index, index, index) -> index
// CHECK: %[[VAL_31:.*]]:2 = "handshake.fork"(%[[VAL_28]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_32:.*]] = "handshake.mux"(%[[VAL_29]]#1, %[[VAL_33:.*]], %[[VAL_27]]) : (index, index, index) -> index
// CHECK: %[[VAL_34:.*]]:2 = "handshake.control_merge"(%[[VAL_35:.*]], %[[VAL_24]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_29]]:3 = "handshake.fork"(%[[VAL_34]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_36:.*]] = "handshake.mux"(%[[VAL_29]]#0, %[[VAL_37:.*]], %[[VAL_25]]) : (index, index, index) -> index
// CHECK: %[[VAL_38:.*]]:2 = "handshake.fork"(%[[VAL_36]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_39:.*]] = arith.cmpi slt, %[[VAL_38]]#1, %[[VAL_31]]#1 : index
// CHECK: %[[VAL_40:.*]]:4 = "handshake.fork"(%[[VAL_39]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#3, %[[VAL_31]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_42]]) : (index) -> ()
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#2, %[[VAL_32]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_44]]) : (index) -> ()
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#1, %[[VAL_34]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#0, %[[VAL_38]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_48]]) : (index) -> ()
// CHECK: %[[VAL_49:.*]] = "handshake.merge"(%[[VAL_47]]) : (index) -> index
// CHECK: %[[VAL_50:.*]] = "handshake.merge"(%[[VAL_43]]) : (index) -> index
// CHECK: %[[VAL_51:.*]]:2 = "handshake.fork"(%[[VAL_50]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_52:.*]] = "handshake.merge"(%[[VAL_41]]) : (index) -> index
// CHECK: %[[VAL_53:.*]]:2 = "handshake.control_merge"(%[[VAL_45]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_53]]#1) : (index) -> ()
// CHECK: %[[VAL_54:.*]] = arith.addi %[[VAL_49]], %[[VAL_51]]#1 : index
// CHECK: %[[VAL_33]] = "handshake.branch"(%[[VAL_51]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_30]] = "handshake.branch"(%[[VAL_52]]) {control = false} : (index) -> index
// CHECK: %[[VAL_35]] = "handshake.branch"(%[[VAL_53]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_37]] = "handshake.branch"(%[[VAL_54]]) {control = false} : (index) -> index
// CHECK: %[[VAL_55:.*]]:2 = "handshake.control_merge"(%[[VAL_46]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_55]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_55]]#0 : none
// CHECK: %[[VAL_22:.*]] = std.select %[[VAL_21]], %[[VAL_20]]#0, %[[VAL_3]]#0 : index
// CHECK: %[[VAL_23:.*]] = constant %[[VAL_4]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_24:.*]] = br %[[VAL_4]]#2 : none
// CHECK: %[[VAL_25:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_26:.*]] = br %[[VAL_22]] : index
// CHECK: %[[VAL_27:.*]] = br %[[VAL_23]] : index
// CHECK: %[[VAL_28:.*]] = mux %[[VAL_29:.*]]#2 {{\[}}%[[VAL_30:.*]], %[[VAL_26]]] : index, index
// CHECK: %[[VAL_31:.*]]:2 = fork [2] %[[VAL_28]] : index
// CHECK: %[[VAL_32:.*]] = mux %[[VAL_29]]#1 {{\[}}%[[VAL_33:.*]], %[[VAL_27]]] : index, index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_36:.*]], %[[VAL_24]] : none
// CHECK: %[[VAL_29]]:3 = fork [3] %[[VAL_35]] : index
// CHECK: %[[VAL_37:.*]] = mux %[[VAL_29]]#0 {{\[}}%[[VAL_38:.*]], %[[VAL_25]]] : index, index
// CHECK: %[[VAL_39:.*]]:2 = fork [2] %[[VAL_37]] : index
// CHECK: %[[VAL_40:.*]] = arith.cmpi slt, %[[VAL_39]]#1, %[[VAL_31]]#1 : index
// CHECK: %[[VAL_41:.*]]:4 = fork [4] %[[VAL_40]] : i1
// CHECK: %[[VAL_42:.*]], %[[VAL_43:.*]] = cond_br %[[VAL_41]]#3, %[[VAL_31]]#0 : index
// CHECK: sink %[[VAL_43]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = cond_br %[[VAL_41]]#2, %[[VAL_32]] : index
// CHECK: sink %[[VAL_45]] : index
// CHECK: %[[VAL_46:.*]], %[[VAL_47:.*]] = cond_br %[[VAL_41]]#1, %[[VAL_34]] : none
// CHECK: %[[VAL_48:.*]], %[[VAL_49:.*]] = cond_br %[[VAL_41]]#0, %[[VAL_39]]#0 : index
// CHECK: sink %[[VAL_49]] : index
// CHECK: %[[VAL_50:.*]] = merge %[[VAL_48]] : index
// CHECK: %[[VAL_51:.*]] = merge %[[VAL_44]] : index
// CHECK: %[[VAL_52:.*]]:2 = fork [2] %[[VAL_51]] : index
// CHECK: %[[VAL_53:.*]] = merge %[[VAL_42]] : index
// CHECK: %[[VAL_54:.*]], %[[VAL_55:.*]] = control_merge %[[VAL_46]] : none
// CHECK: sink %[[VAL_55]] : index
// CHECK: %[[VAL_56:.*]] = arith.addi %[[VAL_50]], %[[VAL_52]]#1 : index
// CHECK: %[[VAL_33]] = br %[[VAL_52]]#0 : index
// CHECK: %[[VAL_30]] = br %[[VAL_53]] : index
// CHECK: %[[VAL_36]] = br %[[VAL_54]] : none
// CHECK: %[[VAL_38]] = br %[[VAL_56]] : index
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = control_merge %[[VAL_47]] : none
// CHECK: sink %[[VAL_58]] : index
// CHECK: return %[[VAL_57]] : none
// CHECK: }
// CHECK: }
func @min_reduction_tree(%arg0: index) {
%c0 = arith.constant 0 : index
%0 = arith.cmpi slt, %arg0, %arg0 : index
%1 = select %0, %arg0, %arg0 : index

View File

@ -1,130 +1,127 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @loop_min_max(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @loop_min_max(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:4 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_3]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_9:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_11:.*]] = "handshake.branch"(%[[VAL_6]]) {control = false} : (index) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.mux"(%[[VAL_13:.*]]#3, %[[VAL_14:.*]], %[[VAL_10]]) : (index, index, index) -> index
// CHECK: %[[VAL_15:.*]]:2 = "handshake.fork"(%[[VAL_12]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_16:.*]] = "handshake.mux"(%[[VAL_13]]#2, %[[VAL_17:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.mux"(%[[VAL_13]]#1, %[[VAL_19:.*]], %[[VAL_11]]) : (index, index, index) -> index
// CHECK: %[[VAL_20:.*]]:2 = "handshake.control_merge"(%[[VAL_21:.*]], %[[VAL_8]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_13]]:4 = "handshake.fork"(%[[VAL_20]]#1) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_22:.*]] = "handshake.mux"(%[[VAL_13]]#0, %[[VAL_23:.*]], %[[VAL_9]]) : (index, index, index) -> index
// CHECK: %[[VAL_24:.*]]:2 = "handshake.fork"(%[[VAL_22]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_25:.*]] = arith.cmpi slt, %[[VAL_24]]#1, %[[VAL_15]]#1 : index
// CHECK: %[[VAL_26:.*]]:5 = "handshake.fork"(%[[VAL_25]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1)
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = "handshake.conditional_branch"(%[[VAL_26]]#4, %[[VAL_15]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_28]]) : (index) -> ()
// CHECK: %[[VAL_29:.*]], %[[VAL_30:.*]] = "handshake.conditional_branch"(%[[VAL_26]]#3, %[[VAL_16]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_30]]) : (index) -> ()
// CHECK: %[[VAL_31:.*]], %[[VAL_32:.*]] = "handshake.conditional_branch"(%[[VAL_26]]#2, %[[VAL_18]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_32]]) : (index) -> ()
// CHECK: %[[VAL_33:.*]], %[[VAL_34:.*]] = "handshake.conditional_branch"(%[[VAL_26]]#1, %[[VAL_20]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_26]]#0, %[[VAL_24]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_36]]) : (index) -> ()
// CHECK: %[[VAL_37:.*]] = "handshake.merge"(%[[VAL_35]]) : (index) -> index
// CHECK: %[[VAL_38:.*]]:5 = "handshake.fork"(%[[VAL_37]]) {control = false} : (index) -> (index, index, index, index, index)
// CHECK: %[[VAL_39:.*]] = "handshake.merge"(%[[VAL_29]]) : (index) -> index
// CHECK: %[[VAL_40:.*]]:4 = "handshake.fork"(%[[VAL_39]]) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_41:.*]] = "handshake.merge"(%[[VAL_31]]) : (index) -> index
// CHECK: %[[VAL_42:.*]] = "handshake.merge"(%[[VAL_27]]) : (index) -> index
// CHECK: %[[VAL_43:.*]]:2 = "handshake.control_merge"(%[[VAL_33]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_44:.*]]:4 = "handshake.fork"(%[[VAL_43]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_43]]#1) : (index) -> ()
// CHECK: %[[VAL_45:.*]] = "handshake.constant"(%[[VAL_44]]#2) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_46:.*]] = arith.muli %[[VAL_38]]#4, %[[VAL_45]] : index
// CHECK: %[[VAL_47:.*]] = arith.addi %[[VAL_46]], %[[VAL_40]]#3 : index
// CHECK: %[[VAL_48:.*]]:2 = "handshake.fork"(%[[VAL_47]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_49:.*]] = arith.cmpi sgt, %[[VAL_38]]#3, %[[VAL_48]]#1 : index
// CHECK: %[[VAL_50:.*]] = select %[[VAL_49]], %[[VAL_38]]#2, %[[VAL_48]]#0 : index
// CHECK: %[[VAL_51:.*]] = "handshake.constant"(%[[VAL_44]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_52:.*]] = arith.addi %[[VAL_38]]#1, %[[VAL_51]] : index
// CHECK: %[[VAL_53:.*]]:2 = "handshake.fork"(%[[VAL_52]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_54:.*]] = arith.cmpi slt, %[[VAL_40]]#2, %[[VAL_53]]#1 : index
// CHECK: %[[VAL_55:.*]] = select %[[VAL_54]], %[[VAL_40]]#1, %[[VAL_53]]#0 : index
// CHECK: %[[VAL_56:.*]] = "handshake.constant"(%[[VAL_44]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_57:.*]] = "handshake.branch"(%[[VAL_38]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_58:.*]] = "handshake.branch"(%[[VAL_40]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_59:.*]] = "handshake.branch"(%[[VAL_41]]) {control = false} : (index) -> index
// CHECK: %[[VAL_60:.*]] = "handshake.branch"(%[[VAL_42]]) {control = false} : (index) -> index
// CHECK: %[[VAL_61:.*]] = "handshake.branch"(%[[VAL_44]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_62:.*]] = "handshake.branch"(%[[VAL_50]]) {control = false} : (index) -> index
// CHECK: %[[VAL_63:.*]] = "handshake.branch"(%[[VAL_55]]) {control = false} : (index) -> index
// CHECK: %[[VAL_64:.*]] = "handshake.branch"(%[[VAL_56]]) {control = false} : (index) -> index
// CHECK: %[[VAL_65:.*]] = "handshake.mux"(%[[VAL_66:.*]]#6, %[[VAL_67:.*]], %[[VAL_63]]) : (index, index, index) -> index
// CHECK: %[[VAL_68:.*]]:2 = "handshake.fork"(%[[VAL_65]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_69:.*]] = "handshake.mux"(%[[VAL_66]]#5, %[[VAL_70:.*]], %[[VAL_64]]) : (index, index, index) -> index
// CHECK: %[[VAL_71:.*]] = "handshake.mux"(%[[VAL_66]]#4, %[[VAL_72:.*]], %[[VAL_57]]) : (index, index, index) -> index
// CHECK: %[[VAL_73:.*]] = "handshake.mux"(%[[VAL_66]]#3, %[[VAL_74:.*]], %[[VAL_59]]) : (index, index, index) -> index
// CHECK: %[[VAL_75:.*]] = "handshake.mux"(%[[VAL_66]]#2, %[[VAL_76:.*]], %[[VAL_60]]) : (index, index, index) -> index
// CHECK: %[[VAL_77:.*]] = "handshake.mux"(%[[VAL_66]]#1, %[[VAL_78:.*]], %[[VAL_58]]) : (index, index, index) -> index
// CHECK: %[[VAL_79:.*]]:2 = "handshake.control_merge"(%[[VAL_80:.*]], %[[VAL_61]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_66]]:7 = "handshake.fork"(%[[VAL_79]]#1) {control = false} : (index) -> (index, index, index, index, index, index, index)
// CHECK: %[[VAL_81:.*]] = "handshake.mux"(%[[VAL_66]]#0, %[[VAL_82:.*]], %[[VAL_62]]) : (index, index, index) -> index
// CHECK: %[[VAL_83:.*]]:2 = "handshake.fork"(%[[VAL_81]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_84:.*]] = arith.cmpi slt, %[[VAL_83]]#1, %[[VAL_68]]#1 : index
// CHECK: %[[VAL_85:.*]]:8 = "handshake.fork"(%[[VAL_84]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_86:.*]], %[[VAL_87:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#7, %[[VAL_68]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_87]]) : (index) -> ()
// CHECK: %[[VAL_88:.*]], %[[VAL_89:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#6, %[[VAL_69]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_89]]) : (index) -> ()
// CHECK: %[[VAL_90:.*]], %[[VAL_91:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#5, %[[VAL_71]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_92:.*]], %[[VAL_93:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#4, %[[VAL_73]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_94:.*]], %[[VAL_95:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#3, %[[VAL_75]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_96:.*]], %[[VAL_97:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#2, %[[VAL_77]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_98:.*]], %[[VAL_99:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#1, %[[VAL_79]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_100:.*]], %[[VAL_101:.*]] = "handshake.conditional_branch"(%[[VAL_85]]#0, %[[VAL_83]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_101]]) : (index) -> ()
// CHECK: %[[VAL_102:.*]] = "handshake.merge"(%[[VAL_100]]) : (index) -> index
// CHECK: %[[VAL_103:.*]] = "handshake.merge"(%[[VAL_88]]) : (index) -> index
// CHECK: %[[VAL_104:.*]]:2 = "handshake.fork"(%[[VAL_103]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_105:.*]] = "handshake.merge"(%[[VAL_86]]) : (index) -> index
// CHECK: %[[VAL_106:.*]] = "handshake.merge"(%[[VAL_90]]) : (index) -> index
// CHECK: %[[VAL_107:.*]] = "handshake.merge"(%[[VAL_92]]) : (index) -> index
// CHECK: %[[VAL_108:.*]] = "handshake.merge"(%[[VAL_94]]) : (index) -> index
// CHECK: %[[VAL_109:.*]] = "handshake.merge"(%[[VAL_96]]) : (index) -> index
// CHECK: %[[VAL_110:.*]]:2 = "handshake.control_merge"(%[[VAL_98]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_110]]#1) : (index) -> ()
// CHECK: %[[VAL_111:.*]] = arith.addi %[[VAL_102]], %[[VAL_104]]#1 : index
// CHECK: %[[VAL_70]] = "handshake.branch"(%[[VAL_104]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_67]] = "handshake.branch"(%[[VAL_105]]) {control = false} : (index) -> index
// CHECK: %[[VAL_72]] = "handshake.branch"(%[[VAL_106]]) {control = false} : (index) -> index
// CHECK: %[[VAL_74]] = "handshake.branch"(%[[VAL_107]]) {control = false} : (index) -> index
// CHECK: %[[VAL_76]] = "handshake.branch"(%[[VAL_108]]) {control = false} : (index) -> index
// CHECK: %[[VAL_78]] = "handshake.branch"(%[[VAL_109]]) {control = false} : (index) -> index
// CHECK: %[[VAL_80]] = "handshake.branch"(%[[VAL_110]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_82]] = "handshake.branch"(%[[VAL_111]]) {control = false} : (index) -> index
// CHECK: %[[VAL_112:.*]] = "handshake.merge"(%[[VAL_91]]) : (index) -> index
// CHECK: %[[VAL_113:.*]] = "handshake.merge"(%[[VAL_93]]) : (index) -> index
// CHECK: %[[VAL_114:.*]]:2 = "handshake.fork"(%[[VAL_113]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_115:.*]] = "handshake.merge"(%[[VAL_95]]) : (index) -> index
// CHECK: %[[VAL_116:.*]] = "handshake.merge"(%[[VAL_97]]) : (index) -> index
// CHECK: %[[VAL_117:.*]]:2 = "handshake.control_merge"(%[[VAL_99]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_117]]#1) : (index) -> ()
// CHECK: %[[VAL_118:.*]] = arith.addi %[[VAL_112]], %[[VAL_114]]#1 : index
// CHECK: %[[VAL_19]] = "handshake.branch"(%[[VAL_114]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_115]]) {control = false} : (index) -> index
// CHECK: %[[VAL_17]] = "handshake.branch"(%[[VAL_116]]) {control = false} : (index) -> index
// CHECK: %[[VAL_21]] = "handshake.branch"(%[[VAL_117]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_23]] = "handshake.branch"(%[[VAL_118]]) {control = false} : (index) -> index
// CHECK: %[[VAL_119:.*]]:2 = "handshake.control_merge"(%[[VAL_34]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_119]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_119]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:4 = fork [4] %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_3]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_3]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_3]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_8:.*]] = br %[[VAL_3]]#3 : none
// CHECK: %[[VAL_9:.*]] = br %[[VAL_4]] : index
// CHECK: %[[VAL_10:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_11:.*]] = br %[[VAL_6]] : index
// CHECK: %[[VAL_12:.*]] = mux %[[VAL_13:.*]]#3 {{\[}}%[[VAL_14:.*]], %[[VAL_10]]] : index, index
// CHECK: %[[VAL_15:.*]]:2 = fork [2] %[[VAL_12]] : index
// CHECK: %[[VAL_16:.*]] = mux %[[VAL_13]]#2 {{\[}}%[[VAL_17:.*]], %[[VAL_7]]] : index, index
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_13]]#1 {{\[}}%[[VAL_19:.*]], %[[VAL_11]]] : index, index
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = control_merge %[[VAL_22:.*]], %[[VAL_8]] : none
// CHECK: %[[VAL_13]]:4 = fork [4] %[[VAL_21]] : index
// CHECK: %[[VAL_23:.*]] = mux %[[VAL_13]]#0 {{\[}}%[[VAL_24:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_25:.*]]:2 = fork [2] %[[VAL_23]] : index
// CHECK: %[[VAL_26:.*]] = arith.cmpi slt, %[[VAL_25]]#1, %[[VAL_15]]#1 : index
// CHECK: %[[VAL_27:.*]]:5 = fork [5] %[[VAL_26]] : i1
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = cond_br %[[VAL_27]]#4, %[[VAL_15]]#0 : index
// CHECK: sink %[[VAL_29]] : index
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = cond_br %[[VAL_27]]#3, %[[VAL_16]] : index
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = cond_br %[[VAL_27]]#2, %[[VAL_18]] : index
// CHECK: sink %[[VAL_33]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = cond_br %[[VAL_27]]#1, %[[VAL_20]] : none
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = cond_br %[[VAL_27]]#0, %[[VAL_25]]#0 : index
// CHECK: sink %[[VAL_37]] : index
// CHECK: %[[VAL_38:.*]] = merge %[[VAL_36]] : index
// CHECK: %[[VAL_39:.*]]:5 = fork [5] %[[VAL_38]] : index
// CHECK: %[[VAL_40:.*]] = merge %[[VAL_30]] : index
// CHECK: %[[VAL_41:.*]]:4 = fork [4] %[[VAL_40]] : index
// CHECK: %[[VAL_42:.*]] = merge %[[VAL_32]] : index
// CHECK: %[[VAL_43:.*]] = merge %[[VAL_28]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = control_merge %[[VAL_34]] : none
// CHECK: %[[VAL_46:.*]]:4 = fork [4] %[[VAL_44]] : none
// CHECK: sink %[[VAL_45]] : index
// CHECK: %[[VAL_47:.*]] = constant %[[VAL_46]]#2 {value = -1 : index} : index
// CHECK: %[[VAL_48:.*]] = arith.muli %[[VAL_39]]#4, %[[VAL_47]] : index
// CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_48]], %[[VAL_41]]#3 : index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_49]] : index
// CHECK: %[[VAL_51:.*]] = arith.cmpi sgt, %[[VAL_39]]#3, %[[VAL_50]]#1 : index
// CHECK: %[[VAL_52:.*]] = std.select %[[VAL_51]], %[[VAL_39]]#2, %[[VAL_50]]#0 : index
// CHECK: %[[VAL_53:.*]] = constant %[[VAL_46]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_54:.*]] = arith.addi %[[VAL_39]]#1, %[[VAL_53]] : index
// CHECK: %[[VAL_55:.*]]:2 = fork [2] %[[VAL_54]] : index
// CHECK: %[[VAL_56:.*]] = arith.cmpi slt, %[[VAL_41]]#2, %[[VAL_55]]#1 : index
// CHECK: %[[VAL_57:.*]] = std.select %[[VAL_56]], %[[VAL_41]]#1, %[[VAL_55]]#0 : index
// CHECK: %[[VAL_58:.*]] = constant %[[VAL_46]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_59:.*]] = br %[[VAL_39]]#0 : index
// CHECK: %[[VAL_60:.*]] = br %[[VAL_41]]#0 : index
// CHECK: %[[VAL_61:.*]] = br %[[VAL_42]] : index
// CHECK: %[[VAL_62:.*]] = br %[[VAL_43]] : index
// CHECK: %[[VAL_63:.*]] = br %[[VAL_46]]#3 : none
// CHECK: %[[VAL_64:.*]] = br %[[VAL_52]] : index
// CHECK: %[[VAL_65:.*]] = br %[[VAL_57]] : index
// CHECK: %[[VAL_66:.*]] = br %[[VAL_58]] : index
// CHECK: %[[VAL_67:.*]] = mux %[[VAL_68:.*]]#6 {{\[}}%[[VAL_69:.*]], %[[VAL_65]]] : index, index
// CHECK: %[[VAL_70:.*]]:2 = fork [2] %[[VAL_67]] : index
// CHECK: %[[VAL_71:.*]] = mux %[[VAL_68]]#5 {{\[}}%[[VAL_72:.*]], %[[VAL_66]]] : index, index
// CHECK: %[[VAL_73:.*]] = mux %[[VAL_68]]#4 {{\[}}%[[VAL_74:.*]], %[[VAL_59]]] : index, index
// CHECK: %[[VAL_75:.*]] = mux %[[VAL_68]]#3 {{\[}}%[[VAL_76:.*]], %[[VAL_61]]] : index, index
// CHECK: %[[VAL_77:.*]] = mux %[[VAL_68]]#2 {{\[}}%[[VAL_78:.*]], %[[VAL_62]]] : index, index
// CHECK: %[[VAL_79:.*]] = mux %[[VAL_68]]#1 {{\[}}%[[VAL_80:.*]], %[[VAL_60]]] : index, index
// CHECK: %[[VAL_81:.*]], %[[VAL_82:.*]] = control_merge %[[VAL_83:.*]], %[[VAL_63]] : none
// CHECK: %[[VAL_68]]:7 = fork [7] %[[VAL_82]] : index
// CHECK: %[[VAL_84:.*]] = mux %[[VAL_68]]#0 {{\[}}%[[VAL_85:.*]], %[[VAL_64]]] : index, index
// CHECK: %[[VAL_86:.*]]:2 = fork [2] %[[VAL_84]] : index
// CHECK: %[[VAL_87:.*]] = arith.cmpi slt, %[[VAL_86]]#1, %[[VAL_70]]#1 : index
// CHECK: %[[VAL_88:.*]]:8 = fork [8] %[[VAL_87]] : i1
// CHECK: %[[VAL_89:.*]], %[[VAL_90:.*]] = cond_br %[[VAL_88]]#7, %[[VAL_70]]#0 : index
// CHECK: sink %[[VAL_90]] : index
// CHECK: %[[VAL_91:.*]], %[[VAL_92:.*]] = cond_br %[[VAL_88]]#6, %[[VAL_71]] : index
// CHECK: sink %[[VAL_92]] : index
// CHECK: %[[VAL_93:.*]], %[[VAL_94:.*]] = cond_br %[[VAL_88]]#5, %[[VAL_73]] : index
// CHECK: %[[VAL_95:.*]], %[[VAL_96:.*]] = cond_br %[[VAL_88]]#4, %[[VAL_75]] : index
// CHECK: %[[VAL_97:.*]], %[[VAL_98:.*]] = cond_br %[[VAL_88]]#3, %[[VAL_77]] : index
// CHECK: %[[VAL_99:.*]], %[[VAL_100:.*]] = cond_br %[[VAL_88]]#2, %[[VAL_79]] : index
// CHECK: %[[VAL_101:.*]], %[[VAL_102:.*]] = cond_br %[[VAL_88]]#1, %[[VAL_81]] : none
// CHECK: %[[VAL_103:.*]], %[[VAL_104:.*]] = cond_br %[[VAL_88]]#0, %[[VAL_86]]#0 : index
// CHECK: sink %[[VAL_104]] : index
// CHECK: %[[VAL_105:.*]] = merge %[[VAL_103]] : index
// CHECK: %[[VAL_106:.*]] = merge %[[VAL_91]] : index
// CHECK: %[[VAL_107:.*]]:2 = fork [2] %[[VAL_106]] : index
// CHECK: %[[VAL_108:.*]] = merge %[[VAL_89]] : index
// CHECK: %[[VAL_109:.*]] = merge %[[VAL_93]] : index
// CHECK: %[[VAL_110:.*]] = merge %[[VAL_95]] : index
// CHECK: %[[VAL_111:.*]] = merge %[[VAL_97]] : index
// CHECK: %[[VAL_112:.*]] = merge %[[VAL_99]] : index
// CHECK: %[[VAL_113:.*]], %[[VAL_114:.*]] = control_merge %[[VAL_101]] : none
// CHECK: sink %[[VAL_114]] : index
// CHECK: %[[VAL_115:.*]] = arith.addi %[[VAL_105]], %[[VAL_107]]#1 : index
// CHECK: %[[VAL_72]] = br %[[VAL_107]]#0 : index
// CHECK: %[[VAL_69]] = br %[[VAL_108]] : index
// CHECK: %[[VAL_74]] = br %[[VAL_109]] : index
// CHECK: %[[VAL_76]] = br %[[VAL_110]] : index
// CHECK: %[[VAL_78]] = br %[[VAL_111]] : index
// CHECK: %[[VAL_80]] = br %[[VAL_112]] : index
// CHECK: %[[VAL_83]] = br %[[VAL_113]] : none
// CHECK: %[[VAL_85]] = br %[[VAL_115]] : index
// CHECK: %[[VAL_116:.*]] = merge %[[VAL_94]] : index
// CHECK: %[[VAL_117:.*]] = merge %[[VAL_96]] : index
// CHECK: %[[VAL_118:.*]]:2 = fork [2] %[[VAL_117]] : index
// CHECK: %[[VAL_119:.*]] = merge %[[VAL_98]] : index
// CHECK: %[[VAL_120:.*]] = merge %[[VAL_100]] : index
// CHECK: %[[VAL_121:.*]], %[[VAL_122:.*]] = control_merge %[[VAL_102]] : none
// CHECK: sink %[[VAL_122]] : index
// CHECK: %[[VAL_123:.*]] = arith.addi %[[VAL_116]], %[[VAL_118]]#1 : index
// CHECK: %[[VAL_19]] = br %[[VAL_118]]#0 : index
// CHECK: %[[VAL_14]] = br %[[VAL_119]] : index
// CHECK: %[[VAL_17]] = br %[[VAL_120]] : index
// CHECK: %[[VAL_22]] = br %[[VAL_121]] : none
// CHECK: %[[VAL_24]] = br %[[VAL_123]] : index
// CHECK: %[[VAL_124:.*]], %[[VAL_125:.*]] = control_merge %[[VAL_35]] : none
// CHECK: sink %[[VAL_125]] : index
// CHECK: return %[[VAL_124]] : none
// CHECK: }
// CHECK: }
func @loop_min_max(%arg0: index) {
%c0 = arith.constant 0 : index
%c42 = arith.constant 42 : index
%c1 = arith.constant 1 : index

View File

@ -1,207 +1,203 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @if_for() {
// CHECK: module {
// CHECK-LABEL: handshake.func @if_for(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_4:.*]]:2 = "handshake.fork"(%[[VAL_3]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]]#1 {value = -1 : index} : index
// CHECK: %[[VAL_4:.*]]:2 = fork [2] %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = arith.muli %[[VAL_4]]#0, %[[VAL_4]]#1 : index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 20 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_1]]#0 {value = 20 : index} : index
// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_5]], %[[VAL_6]] : index
// CHECK: %[[VAL_8:.*]] = arith.cmpi sge, %[[VAL_7]], %[[VAL_2]] : index
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = "handshake.conditional_branch"(%[[VAL_8]], %[[VAL_1]]#3) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_11:.*]]:2 = "handshake.control_merge"(%[[VAL_9]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_12:.*]]:4 = "handshake.fork"(%[[VAL_11]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_11]]#1) : (index) -> ()
// CHECK: %[[VAL_13:.*]] = "handshake.constant"(%[[VAL_12]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_14:.*]] = "handshake.constant"(%[[VAL_12]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_15:.*]] = "handshake.constant"(%[[VAL_12]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_16:.*]] = "handshake.branch"(%[[VAL_12]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_17:.*]] = "handshake.branch"(%[[VAL_13]]) {control = false} : (index) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.branch"(%[[VAL_14]]) {control = false} : (index) -> index
// CHECK: %[[VAL_19:.*]] = "handshake.branch"(%[[VAL_15]]) {control = false} : (index) -> index
// CHECK: %[[VAL_20:.*]] = "handshake.mux"(%[[VAL_21:.*]]#2, %[[VAL_22:.*]], %[[VAL_18]]) : (index, index, index) -> index
// CHECK: %[[VAL_23:.*]]:2 = "handshake.fork"(%[[VAL_20]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_21]]#1, %[[VAL_25:.*]], %[[VAL_19]]) : (index, index, index) -> index
// CHECK: %[[VAL_26:.*]]:2 = "handshake.control_merge"(%[[VAL_27:.*]], %[[VAL_16]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_21]]:3 = "handshake.fork"(%[[VAL_26]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_21]]#0, %[[VAL_29:.*]], %[[VAL_17]]) : (index, index, index) -> index
// CHECK: %[[VAL_30:.*]]:2 = "handshake.fork"(%[[VAL_28]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_31:.*]] = arith.cmpi slt, %[[VAL_30]]#1, %[[VAL_23]]#1 : index
// CHECK: %[[VAL_32:.*]]:4 = "handshake.fork"(%[[VAL_31]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_33:.*]], %[[VAL_34:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#3, %[[VAL_23]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_34]]) : (index) -> ()
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#2, %[[VAL_24]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_36]]) : (index) -> ()
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#1, %[[VAL_26]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#0, %[[VAL_30]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_40]]) : (index) -> ()
// CHECK: %[[VAL_41:.*]] = "handshake.merge"(%[[VAL_39]]) : (index) -> index
// CHECK: %[[VAL_42:.*]]:2 = "handshake.fork"(%[[VAL_41]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_43:.*]] = "handshake.merge"(%[[VAL_35]]) : (index) -> index
// CHECK: %[[VAL_44:.*]] = "handshake.merge"(%[[VAL_33]]) : (index) -> index
// CHECK: %[[VAL_45:.*]]:2 = "handshake.control_merge"(%[[VAL_37]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_46:.*]]:3 = "handshake.fork"(%[[VAL_45]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_45]]#1) : (index) -> ()
// CHECK: %[[VAL_47:.*]] = "handshake.constant"(%[[VAL_46]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_48:.*]] = "handshake.constant"(%[[VAL_46]]#0) {value = -10 : index} : (none) -> index
// CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_42]]#1, %[[VAL_48]] : index
// CHECK: %[[VAL_50:.*]] = arith.cmpi sge, %[[VAL_49]], %[[VAL_47]] : index
// CHECK: %[[VAL_51:.*]]:4 = "handshake.fork"(%[[VAL_50]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_52:.*]], %[[VAL_53:.*]] = "handshake.conditional_branch"(%[[VAL_51]]#3, %[[VAL_42]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_54:.*]], %[[VAL_55:.*]] = "handshake.conditional_branch"(%[[VAL_51]]#2, %[[VAL_43]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_56:.*]], %[[VAL_57:.*]] = "handshake.conditional_branch"(%[[VAL_51]]#1, %[[VAL_44]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_58:.*]], %[[VAL_59:.*]] = "handshake.conditional_branch"(%[[VAL_51]]#0, %[[VAL_46]]#2) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_60:.*]] = "handshake.merge"(%[[VAL_52]]) : (index) -> index
// CHECK: %[[VAL_61:.*]] = "handshake.merge"(%[[VAL_54]]) : (index) -> index
// CHECK: %[[VAL_62:.*]] = "handshake.merge"(%[[VAL_56]]) : (index) -> index
// CHECK: %[[VAL_63:.*]]:2 = "handshake.control_merge"(%[[VAL_58]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_63]]#1) : (index) -> ()
// CHECK: %[[VAL_64:.*]] = "handshake.branch"(%[[VAL_60]]) {control = false} : (index) -> index
// CHECK: %[[VAL_65:.*]] = "handshake.branch"(%[[VAL_61]]) {control = false} : (index) -> index
// CHECK: %[[VAL_66:.*]] = "handshake.branch"(%[[VAL_62]]) {control = false} : (index) -> index
// CHECK: %[[VAL_67:.*]] = "handshake.branch"(%[[VAL_63]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_68:.*]] = "handshake.mux"(%[[VAL_69:.*]]#2, %[[VAL_64]], %[[VAL_53]]) : (index, index, index) -> index
// CHECK: %[[VAL_70:.*]] = "handshake.mux"(%[[VAL_69]]#1, %[[VAL_65]], %[[VAL_55]]) : (index, index, index) -> index
// CHECK: %[[VAL_71:.*]]:2 = "handshake.fork"(%[[VAL_70]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_72:.*]] = "handshake.mux"(%[[VAL_69]]#0, %[[VAL_66]], %[[VAL_57]]) : (index, index, index) -> index
// CHECK: %[[VAL_73:.*]]:2 = "handshake.control_merge"(%[[VAL_67]], %[[VAL_59]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_69]]:3 = "handshake.fork"(%[[VAL_73]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_74:.*]] = arith.addi %[[VAL_68]], %[[VAL_71]]#1 : index
// CHECK: %[[VAL_25]] = "handshake.branch"(%[[VAL_71]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_22]] = "handshake.branch"(%[[VAL_72]]) {control = false} : (index) -> index
// CHECK: %[[VAL_27]] = "handshake.branch"(%[[VAL_73]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_74]]) {control = false} : (index) -> index
// CHECK: %[[VAL_75:.*]]:2 = "handshake.control_merge"(%[[VAL_38]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_75]]#1) : (index) -> ()
// CHECK: %[[VAL_76:.*]] = "handshake.branch"(%[[VAL_75]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_77:.*]]:2 = "handshake.control_merge"(%[[VAL_76]], %[[VAL_10]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_78:.*]]:4 = "handshake.fork"(%[[VAL_77]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_77]]#1) : (index) -> ()
// CHECK: %[[VAL_79:.*]] = "handshake.constant"(%[[VAL_78]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_80:.*]] = "handshake.constant"(%[[VAL_78]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_81:.*]] = "handshake.constant"(%[[VAL_78]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_82:.*]] = "handshake.branch"(%[[VAL_78]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_83:.*]] = "handshake.branch"(%[[VAL_79]]) {control = false} : (index) -> index
// CHECK: %[[VAL_84:.*]] = "handshake.branch"(%[[VAL_80]]) {control = false} : (index) -> index
// CHECK: %[[VAL_85:.*]] = "handshake.branch"(%[[VAL_81]]) {control = false} : (index) -> index
// CHECK: %[[VAL_86:.*]] = "handshake.mux"(%[[VAL_87:.*]]#2, %[[VAL_88:.*]], %[[VAL_84]]) : (index, index, index) -> index
// CHECK: %[[VAL_89:.*]]:2 = "handshake.fork"(%[[VAL_86]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_90:.*]] = "handshake.mux"(%[[VAL_87]]#1, %[[VAL_91:.*]], %[[VAL_85]]) : (index, index, index) -> index
// CHECK: %[[VAL_92:.*]]:2 = "handshake.control_merge"(%[[VAL_93:.*]], %[[VAL_82]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_87]]:3 = "handshake.fork"(%[[VAL_92]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_94:.*]] = "handshake.mux"(%[[VAL_87]]#0, %[[VAL_95:.*]], %[[VAL_83]]) : (index, index, index) -> index
// CHECK: %[[VAL_96:.*]]:2 = "handshake.fork"(%[[VAL_94]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_97:.*]] = arith.cmpi slt, %[[VAL_96]]#1, %[[VAL_89]]#1 : index
// CHECK: %[[VAL_98:.*]]:4 = "handshake.fork"(%[[VAL_97]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_99:.*]], %[[VAL_100:.*]] = "handshake.conditional_branch"(%[[VAL_98]]#3, %[[VAL_89]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_100]]) : (index) -> ()
// CHECK: %[[VAL_101:.*]], %[[VAL_102:.*]] = "handshake.conditional_branch"(%[[VAL_98]]#2, %[[VAL_90]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_102]]) : (index) -> ()
// CHECK: %[[VAL_103:.*]], %[[VAL_104:.*]] = "handshake.conditional_branch"(%[[VAL_98]]#1, %[[VAL_92]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_105:.*]], %[[VAL_106:.*]] = "handshake.conditional_branch"(%[[VAL_98]]#0, %[[VAL_96]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_106]]) : (index) -> ()
// CHECK: %[[VAL_107:.*]] = "handshake.merge"(%[[VAL_105]]) : (index) -> index
// CHECK: %[[VAL_108:.*]]:2 = "handshake.fork"(%[[VAL_107]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_109:.*]] = "handshake.merge"(%[[VAL_101]]) : (index) -> index
// CHECK: %[[VAL_110:.*]] = "handshake.merge"(%[[VAL_99]]) : (index) -> index
// CHECK: %[[VAL_111:.*]]:2 = "handshake.control_merge"(%[[VAL_103]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_112:.*]]:3 = "handshake.fork"(%[[VAL_111]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_111]]#1) : (index) -> ()
// CHECK: %[[VAL_113:.*]] = "handshake.constant"(%[[VAL_112]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_114:.*]] = "handshake.constant"(%[[VAL_112]]#0) {value = -10 : index} : (none) -> index
// CHECK: %[[VAL_115:.*]] = arith.addi %[[VAL_108]]#1, %[[VAL_114]] : index
// CHECK: %[[VAL_116:.*]] = arith.cmpi sge, %[[VAL_115]], %[[VAL_113]] : index
// CHECK: %[[VAL_117:.*]]:4 = "handshake.fork"(%[[VAL_116]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_118:.*]], %[[VAL_119:.*]] = "handshake.conditional_branch"(%[[VAL_117]]#3, %[[VAL_108]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_120:.*]], %[[VAL_121:.*]] = "handshake.conditional_branch"(%[[VAL_117]]#2, %[[VAL_109]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_122:.*]], %[[VAL_123:.*]] = "handshake.conditional_branch"(%[[VAL_117]]#1, %[[VAL_110]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_124:.*]], %[[VAL_125:.*]] = "handshake.conditional_branch"(%[[VAL_117]]#0, %[[VAL_112]]#2) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_126:.*]] = "handshake.merge"(%[[VAL_118]]) : (index) -> index
// CHECK: %[[VAL_127:.*]] = "handshake.merge"(%[[VAL_120]]) : (index) -> index
// CHECK: %[[VAL_128:.*]] = "handshake.merge"(%[[VAL_122]]) : (index) -> index
// CHECK: %[[VAL_129:.*]]:2 = "handshake.control_merge"(%[[VAL_124]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_130:.*]]:4 = "handshake.fork"(%[[VAL_129]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: "handshake.sink"(%[[VAL_129]]#1) : (index) -> ()
// CHECK: %[[VAL_131:.*]] = "handshake.constant"(%[[VAL_130]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_132:.*]] = "handshake.constant"(%[[VAL_130]]#1) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_133:.*]] = "handshake.constant"(%[[VAL_130]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_134:.*]] = "handshake.branch"(%[[VAL_126]]) {control = false} : (index) -> index
// CHECK: %[[VAL_135:.*]] = "handshake.branch"(%[[VAL_127]]) {control = false} : (index) -> index
// CHECK: %[[VAL_136:.*]] = "handshake.branch"(%[[VAL_128]]) {control = false} : (index) -> index
// CHECK: %[[VAL_137:.*]] = "handshake.branch"(%[[VAL_130]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_138:.*]] = "handshake.branch"(%[[VAL_131]]) {control = false} : (index) -> index
// CHECK: %[[VAL_139:.*]] = "handshake.branch"(%[[VAL_132]]) {control = false} : (index) -> index
// CHECK: %[[VAL_140:.*]] = "handshake.branch"(%[[VAL_133]]) {control = false} : (index) -> index
// CHECK: %[[VAL_141:.*]] = "handshake.mux"(%[[VAL_142:.*]]#5, %[[VAL_143:.*]], %[[VAL_139]]) : (index, index, index) -> index
// CHECK: %[[VAL_144:.*]]:2 = "handshake.fork"(%[[VAL_141]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_145:.*]] = "handshake.mux"(%[[VAL_142]]#4, %[[VAL_146:.*]], %[[VAL_140]]) : (index, index, index) -> index
// CHECK: %[[VAL_147:.*]] = "handshake.mux"(%[[VAL_142]]#3, %[[VAL_148:.*]], %[[VAL_134]]) : (index, index, index) -> index
// CHECK: %[[VAL_149:.*]] = "handshake.mux"(%[[VAL_142]]#2, %[[VAL_150:.*]], %[[VAL_135]]) : (index, index, index) -> index
// CHECK: %[[VAL_151:.*]] = "handshake.mux"(%[[VAL_142]]#1, %[[VAL_152:.*]], %[[VAL_136]]) : (index, index, index) -> index
// CHECK: %[[VAL_153:.*]]:2 = "handshake.control_merge"(%[[VAL_154:.*]], %[[VAL_137]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_142]]:6 = "handshake.fork"(%[[VAL_153]]#1) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_155:.*]] = "handshake.mux"(%[[VAL_142]]#0, %[[VAL_156:.*]], %[[VAL_138]]) : (index, index, index) -> index
// CHECK: %[[VAL_157:.*]]:2 = "handshake.fork"(%[[VAL_155]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_158:.*]] = arith.cmpi slt, %[[VAL_157]]#1, %[[VAL_144]]#1 : index
// CHECK: %[[VAL_159:.*]]:7 = "handshake.fork"(%[[VAL_158]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_160:.*]], %[[VAL_161:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#6, %[[VAL_144]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_161]]) : (index) -> ()
// CHECK: %[[VAL_162:.*]], %[[VAL_163:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#5, %[[VAL_145]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_163]]) : (index) -> ()
// CHECK: %[[VAL_164:.*]], %[[VAL_165:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#4, %[[VAL_147]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_166:.*]], %[[VAL_167:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#3, %[[VAL_149]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_168:.*]], %[[VAL_169:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#2, %[[VAL_151]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_170:.*]], %[[VAL_171:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#1, %[[VAL_153]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_172:.*]], %[[VAL_173:.*]] = "handshake.conditional_branch"(%[[VAL_159]]#0, %[[VAL_157]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_173]]) : (index) -> ()
// CHECK: %[[VAL_174:.*]] = "handshake.merge"(%[[VAL_172]]) : (index) -> index
// CHECK: %[[VAL_175:.*]] = "handshake.merge"(%[[VAL_162]]) : (index) -> index
// CHECK: %[[VAL_176:.*]]:2 = "handshake.fork"(%[[VAL_175]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_177:.*]] = "handshake.merge"(%[[VAL_160]]) : (index) -> index
// CHECK: %[[VAL_178:.*]] = "handshake.merge"(%[[VAL_164]]) : (index) -> index
// CHECK: %[[VAL_179:.*]] = "handshake.merge"(%[[VAL_166]]) : (index) -> index
// CHECK: %[[VAL_180:.*]] = "handshake.merge"(%[[VAL_168]]) : (index) -> index
// CHECK: %[[VAL_181:.*]]:2 = "handshake.control_merge"(%[[VAL_170]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_181]]#1) : (index) -> ()
// CHECK: %[[VAL_182:.*]] = arith.addi %[[VAL_174]], %[[VAL_176]]#1 : index
// CHECK: %[[VAL_146]] = "handshake.branch"(%[[VAL_176]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_143]] = "handshake.branch"(%[[VAL_177]]) {control = false} : (index) -> index
// CHECK: %[[VAL_148]] = "handshake.branch"(%[[VAL_178]]) {control = false} : (index) -> index
// CHECK: %[[VAL_150]] = "handshake.branch"(%[[VAL_179]]) {control = false} : (index) -> index
// CHECK: %[[VAL_152]] = "handshake.branch"(%[[VAL_180]]) {control = false} : (index) -> index
// CHECK: %[[VAL_154]] = "handshake.branch"(%[[VAL_181]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_156]] = "handshake.branch"(%[[VAL_182]]) {control = false} : (index) -> index
// CHECK: %[[VAL_183:.*]] = "handshake.merge"(%[[VAL_165]]) : (index) -> index
// CHECK: %[[VAL_184:.*]] = "handshake.merge"(%[[VAL_167]]) : (index) -> index
// CHECK: %[[VAL_185:.*]] = "handshake.merge"(%[[VAL_169]]) : (index) -> index
// CHECK: %[[VAL_186:.*]]:2 = "handshake.control_merge"(%[[VAL_171]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_186]]#1) : (index) -> ()
// CHECK: %[[VAL_187:.*]] = "handshake.branch"(%[[VAL_183]]) {control = false} : (index) -> index
// CHECK: %[[VAL_188:.*]] = "handshake.branch"(%[[VAL_184]]) {control = false} : (index) -> index
// CHECK: %[[VAL_189:.*]] = "handshake.branch"(%[[VAL_185]]) {control = false} : (index) -> index
// CHECK: %[[VAL_190:.*]] = "handshake.branch"(%[[VAL_186]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_191:.*]] = "handshake.mux"(%[[VAL_192:.*]]#2, %[[VAL_187]], %[[VAL_119]]) : (index, index, index) -> index
// CHECK: %[[VAL_193:.*]] = "handshake.mux"(%[[VAL_192]]#1, %[[VAL_188]], %[[VAL_121]]) : (index, index, index) -> index
// CHECK: %[[VAL_194:.*]]:2 = "handshake.fork"(%[[VAL_193]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_195:.*]] = "handshake.mux"(%[[VAL_192]]#0, %[[VAL_189]], %[[VAL_123]]) : (index, index, index) -> index
// CHECK: %[[VAL_196:.*]]:2 = "handshake.control_merge"(%[[VAL_190]], %[[VAL_125]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_192]]:3 = "handshake.fork"(%[[VAL_196]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_197:.*]] = arith.addi %[[VAL_191]], %[[VAL_194]]#1 : index
// CHECK: %[[VAL_91]] = "handshake.branch"(%[[VAL_194]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_88]] = "handshake.branch"(%[[VAL_195]]) {control = false} : (index) -> index
// CHECK: %[[VAL_93]] = "handshake.branch"(%[[VAL_196]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_95]] = "handshake.branch"(%[[VAL_197]]) {control = false} : (index) -> index
// CHECK: %[[VAL_198:.*]]:2 = "handshake.control_merge"(%[[VAL_104]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_198]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_198]]#0 : none
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = cond_br %[[VAL_8]], %[[VAL_1]]#3 : none
// CHECK: %[[VAL_11:.*]], %[[VAL_12:.*]] = control_merge %[[VAL_9]] : none
// CHECK: %[[VAL_13:.*]]:4 = fork [4] %[[VAL_11]] : none
// CHECK: sink %[[VAL_12]] : index
// CHECK: %[[VAL_14:.*]] = constant %[[VAL_13]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_15:.*]] = constant %[[VAL_13]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_16:.*]] = constant %[[VAL_13]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_17:.*]] = br %[[VAL_13]]#3 : none
// CHECK: %[[VAL_18:.*]] = br %[[VAL_14]] : index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_15]] : index
// CHECK: %[[VAL_20:.*]] = br %[[VAL_16]] : index
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_22:.*]]#2 {{\[}}%[[VAL_23:.*]], %[[VAL_19]]] : index, index
// CHECK: %[[VAL_24:.*]]:2 = fork [2] %[[VAL_21]] : index
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_22]]#1 {{\[}}%[[VAL_26:.*]], %[[VAL_20]]] : index, index
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = control_merge %[[VAL_29:.*]], %[[VAL_17]] : none
// CHECK: %[[VAL_22]]:3 = fork [3] %[[VAL_28]] : index
// CHECK: %[[VAL_30:.*]] = mux %[[VAL_22]]#0 {{\[}}%[[VAL_31:.*]], %[[VAL_18]]] : index, index
// CHECK: %[[VAL_32:.*]]:2 = fork [2] %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]] = arith.cmpi slt, %[[VAL_32]]#1, %[[VAL_24]]#1 : index
// CHECK: %[[VAL_34:.*]]:4 = fork [4] %[[VAL_33]] : i1
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = cond_br %[[VAL_34]]#3, %[[VAL_24]]#0 : index
// CHECK: sink %[[VAL_36]] : index
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = cond_br %[[VAL_34]]#2, %[[VAL_25]] : index
// CHECK: sink %[[VAL_38]] : index
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = cond_br %[[VAL_34]]#1, %[[VAL_27]] : none
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = cond_br %[[VAL_34]]#0, %[[VAL_32]]#0 : index
// CHECK: sink %[[VAL_42]] : index
// CHECK: %[[VAL_43:.*]] = merge %[[VAL_41]] : index
// CHECK: %[[VAL_44:.*]]:2 = fork [2] %[[VAL_43]] : index
// CHECK: %[[VAL_45:.*]] = merge %[[VAL_37]] : index
// CHECK: %[[VAL_46:.*]] = merge %[[VAL_35]] : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge %[[VAL_39]] : none
// CHECK: %[[VAL_49:.*]]:3 = fork [3] %[[VAL_47]] : none
// CHECK: sink %[[VAL_48]] : index
// CHECK: %[[VAL_50:.*]] = constant %[[VAL_49]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_51:.*]] = constant %[[VAL_49]]#0 {value = -10 : index} : index
// CHECK: %[[VAL_52:.*]] = arith.addi %[[VAL_44]]#1, %[[VAL_51]] : index
// CHECK: %[[VAL_53:.*]] = arith.cmpi sge, %[[VAL_52]], %[[VAL_50]] : index
// CHECK: %[[VAL_54:.*]]:4 = fork [4] %[[VAL_53]] : i1
// CHECK: %[[VAL_55:.*]], %[[VAL_56:.*]] = cond_br %[[VAL_54]]#3, %[[VAL_44]]#0 : index
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = cond_br %[[VAL_54]]#2, %[[VAL_45]] : index
// CHECK: %[[VAL_59:.*]], %[[VAL_60:.*]] = cond_br %[[VAL_54]]#1, %[[VAL_46]] : index
// CHECK: %[[VAL_61:.*]], %[[VAL_62:.*]] = cond_br %[[VAL_54]]#0, %[[VAL_49]]#2 : none
// CHECK: %[[VAL_63:.*]] = merge %[[VAL_55]] : index
// CHECK: %[[VAL_64:.*]] = merge %[[VAL_57]] : index
// CHECK: %[[VAL_65:.*]] = merge %[[VAL_59]] : index
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = control_merge %[[VAL_61]] : none
// CHECK: sink %[[VAL_67]] : index
// CHECK: %[[VAL_68:.*]] = br %[[VAL_63]] : index
// CHECK: %[[VAL_69:.*]] = br %[[VAL_64]] : index
// CHECK: %[[VAL_70:.*]] = br %[[VAL_65]] : index
// CHECK: %[[VAL_71:.*]] = br %[[VAL_66]] : none
// CHECK: %[[VAL_72:.*]] = mux %[[VAL_73:.*]]#2 {{\[}}%[[VAL_68]], %[[VAL_56]]] : index, index
// CHECK: %[[VAL_74:.*]] = mux %[[VAL_73]]#1 {{\[}}%[[VAL_69]], %[[VAL_58]]] : index, index
// CHECK: %[[VAL_75:.*]]:2 = fork [2] %[[VAL_74]] : index
// CHECK: %[[VAL_76:.*]] = mux %[[VAL_73]]#0 {{\[}}%[[VAL_70]], %[[VAL_60]]] : index, index
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = control_merge %[[VAL_71]], %[[VAL_62]] : none
// CHECK: %[[VAL_73]]:3 = fork [3] %[[VAL_78]] : index
// CHECK: %[[VAL_79:.*]] = arith.addi %[[VAL_72]], %[[VAL_75]]#1 : index
// CHECK: %[[VAL_26]] = br %[[VAL_75]]#0 : index
// CHECK: %[[VAL_23]] = br %[[VAL_76]] : index
// CHECK: %[[VAL_29]] = br %[[VAL_77]] : none
// CHECK: %[[VAL_31]] = br %[[VAL_79]] : index
// CHECK: %[[VAL_80:.*]], %[[VAL_81:.*]] = control_merge %[[VAL_40]] : none
// CHECK: sink %[[VAL_81]] : index
// CHECK: %[[VAL_82:.*]] = br %[[VAL_80]] : none
// CHECK: %[[VAL_83:.*]], %[[VAL_84:.*]] = control_merge %[[VAL_82]], %[[VAL_10]] : none
// CHECK: %[[VAL_85:.*]]:4 = fork [4] %[[VAL_83]] : none
// CHECK: sink %[[VAL_84]] : index
// CHECK: %[[VAL_86:.*]] = constant %[[VAL_85]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_87:.*]] = constant %[[VAL_85]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_88:.*]] = constant %[[VAL_85]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_89:.*]] = br %[[VAL_85]]#3 : none
// CHECK: %[[VAL_90:.*]] = br %[[VAL_86]] : index
// CHECK: %[[VAL_91:.*]] = br %[[VAL_87]] : index
// CHECK: %[[VAL_92:.*]] = br %[[VAL_88]] : index
// CHECK: %[[VAL_93:.*]] = mux %[[VAL_94:.*]]#2 {{\[}}%[[VAL_95:.*]], %[[VAL_91]]] : index, index
// CHECK: %[[VAL_96:.*]]:2 = fork [2] %[[VAL_93]] : index
// CHECK: %[[VAL_97:.*]] = mux %[[VAL_94]]#1 {{\[}}%[[VAL_98:.*]], %[[VAL_92]]] : index, index
// CHECK: %[[VAL_99:.*]], %[[VAL_100:.*]] = control_merge %[[VAL_101:.*]], %[[VAL_89]] : none
// CHECK: %[[VAL_94]]:3 = fork [3] %[[VAL_100]] : index
// CHECK: %[[VAL_102:.*]] = mux %[[VAL_94]]#0 {{\[}}%[[VAL_103:.*]], %[[VAL_90]]] : index, index
// CHECK: %[[VAL_104:.*]]:2 = fork [2] %[[VAL_102]] : index
// CHECK: %[[VAL_105:.*]] = arith.cmpi slt, %[[VAL_104]]#1, %[[VAL_96]]#1 : index
// CHECK: %[[VAL_106:.*]]:4 = fork [4] %[[VAL_105]] : i1
// CHECK: %[[VAL_107:.*]], %[[VAL_108:.*]] = cond_br %[[VAL_106]]#3, %[[VAL_96]]#0 : index
// CHECK: sink %[[VAL_108]] : index
// CHECK: %[[VAL_109:.*]], %[[VAL_110:.*]] = cond_br %[[VAL_106]]#2, %[[VAL_97]] : index
// CHECK: sink %[[VAL_110]] : index
// CHECK: %[[VAL_111:.*]], %[[VAL_112:.*]] = cond_br %[[VAL_106]]#1, %[[VAL_99]] : none
// CHECK: %[[VAL_113:.*]], %[[VAL_114:.*]] = cond_br %[[VAL_106]]#0, %[[VAL_104]]#0 : index
// CHECK: sink %[[VAL_114]] : index
// CHECK: %[[VAL_115:.*]] = merge %[[VAL_113]] : index
// CHECK: %[[VAL_116:.*]]:2 = fork [2] %[[VAL_115]] : index
// CHECK: %[[VAL_117:.*]] = merge %[[VAL_109]] : index
// CHECK: %[[VAL_118:.*]] = merge %[[VAL_107]] : index
// CHECK: %[[VAL_119:.*]], %[[VAL_120:.*]] = control_merge %[[VAL_111]] : none
// CHECK: %[[VAL_121:.*]]:3 = fork [3] %[[VAL_119]] : none
// CHECK: sink %[[VAL_120]] : index
// CHECK: %[[VAL_122:.*]] = constant %[[VAL_121]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_123:.*]] = constant %[[VAL_121]]#0 {value = -10 : index} : index
// CHECK: %[[VAL_124:.*]] = arith.addi %[[VAL_116]]#1, %[[VAL_123]] : index
// CHECK: %[[VAL_125:.*]] = arith.cmpi sge, %[[VAL_124]], %[[VAL_122]] : index
// CHECK: %[[VAL_126:.*]]:4 = fork [4] %[[VAL_125]] : i1
// CHECK: %[[VAL_127:.*]], %[[VAL_128:.*]] = cond_br %[[VAL_126]]#3, %[[VAL_116]]#0 : index
// CHECK: %[[VAL_129:.*]], %[[VAL_130:.*]] = cond_br %[[VAL_126]]#2, %[[VAL_117]] : index
// CHECK: %[[VAL_131:.*]], %[[VAL_132:.*]] = cond_br %[[VAL_126]]#1, %[[VAL_118]] : index
// CHECK: %[[VAL_133:.*]], %[[VAL_134:.*]] = cond_br %[[VAL_126]]#0, %[[VAL_121]]#2 : none
// CHECK: %[[VAL_135:.*]] = merge %[[VAL_127]] : index
// CHECK: %[[VAL_136:.*]] = merge %[[VAL_129]] : index
// CHECK: %[[VAL_137:.*]] = merge %[[VAL_131]] : index
// CHECK: %[[VAL_138:.*]], %[[VAL_139:.*]] = control_merge %[[VAL_133]] : none
// CHECK: %[[VAL_140:.*]]:4 = fork [4] %[[VAL_138]] : none
// CHECK: sink %[[VAL_139]] : index
// CHECK: %[[VAL_141:.*]] = constant %[[VAL_140]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_142:.*]] = constant %[[VAL_140]]#1 {value = 42 : index} : index
// CHECK: %[[VAL_143:.*]] = constant %[[VAL_140]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_144:.*]] = br %[[VAL_135]] : index
// CHECK: %[[VAL_145:.*]] = br %[[VAL_136]] : index
// CHECK: %[[VAL_146:.*]] = br %[[VAL_137]] : index
// CHECK: %[[VAL_147:.*]] = br %[[VAL_140]]#3 : none
// CHECK: %[[VAL_148:.*]] = br %[[VAL_141]] : index
// CHECK: %[[VAL_149:.*]] = br %[[VAL_142]] : index
// CHECK: %[[VAL_150:.*]] = br %[[VAL_143]] : index
// CHECK: %[[VAL_151:.*]] = mux %[[VAL_152:.*]]#5 {{\[}}%[[VAL_153:.*]], %[[VAL_149]]] : index, index
// CHECK: %[[VAL_154:.*]]:2 = fork [2] %[[VAL_151]] : index
// CHECK: %[[VAL_155:.*]] = mux %[[VAL_152]]#4 {{\[}}%[[VAL_156:.*]], %[[VAL_150]]] : index, index
// CHECK: %[[VAL_157:.*]] = mux %[[VAL_152]]#3 {{\[}}%[[VAL_158:.*]], %[[VAL_144]]] : index, index
// CHECK: %[[VAL_159:.*]] = mux %[[VAL_152]]#2 {{\[}}%[[VAL_160:.*]], %[[VAL_145]]] : index, index
// CHECK: %[[VAL_161:.*]] = mux %[[VAL_152]]#1 {{\[}}%[[VAL_162:.*]], %[[VAL_146]]] : index, index
// CHECK: %[[VAL_163:.*]], %[[VAL_164:.*]] = control_merge %[[VAL_165:.*]], %[[VAL_147]] : none
// CHECK: %[[VAL_152]]:6 = fork [6] %[[VAL_164]] : index
// CHECK: %[[VAL_166:.*]] = mux %[[VAL_152]]#0 {{\[}}%[[VAL_167:.*]], %[[VAL_148]]] : index, index
// CHECK: %[[VAL_168:.*]]:2 = fork [2] %[[VAL_166]] : index
// CHECK: %[[VAL_169:.*]] = arith.cmpi slt, %[[VAL_168]]#1, %[[VAL_154]]#1 : index
// CHECK: %[[VAL_170:.*]]:7 = fork [7] %[[VAL_169]] : i1
// CHECK: %[[VAL_171:.*]], %[[VAL_172:.*]] = cond_br %[[VAL_170]]#6, %[[VAL_154]]#0 : index
// CHECK: sink %[[VAL_172]] : index
// CHECK: %[[VAL_173:.*]], %[[VAL_174:.*]] = cond_br %[[VAL_170]]#5, %[[VAL_155]] : index
// CHECK: sink %[[VAL_174]] : index
// CHECK: %[[VAL_175:.*]], %[[VAL_176:.*]] = cond_br %[[VAL_170]]#4, %[[VAL_157]] : index
// CHECK: %[[VAL_177:.*]], %[[VAL_178:.*]] = cond_br %[[VAL_170]]#3, %[[VAL_159]] : index
// CHECK: %[[VAL_179:.*]], %[[VAL_180:.*]] = cond_br %[[VAL_170]]#2, %[[VAL_161]] : index
// CHECK: %[[VAL_181:.*]], %[[VAL_182:.*]] = cond_br %[[VAL_170]]#1, %[[VAL_163]] : none
// CHECK: %[[VAL_183:.*]], %[[VAL_184:.*]] = cond_br %[[VAL_170]]#0, %[[VAL_168]]#0 : index
// CHECK: sink %[[VAL_184]] : index
// CHECK: %[[VAL_185:.*]] = merge %[[VAL_183]] : index
// CHECK: %[[VAL_186:.*]] = merge %[[VAL_173]] : index
// CHECK: %[[VAL_187:.*]]:2 = fork [2] %[[VAL_186]] : index
// CHECK: %[[VAL_188:.*]] = merge %[[VAL_171]] : index
// CHECK: %[[VAL_189:.*]] = merge %[[VAL_175]] : index
// CHECK: %[[VAL_190:.*]] = merge %[[VAL_177]] : index
// CHECK: %[[VAL_191:.*]] = merge %[[VAL_179]] : index
// CHECK: %[[VAL_192:.*]], %[[VAL_193:.*]] = control_merge %[[VAL_181]] : none
// CHECK: sink %[[VAL_193]] : index
// CHECK: %[[VAL_194:.*]] = arith.addi %[[VAL_185]], %[[VAL_187]]#1 : index
// CHECK: %[[VAL_156]] = br %[[VAL_187]]#0 : index
// CHECK: %[[VAL_153]] = br %[[VAL_188]] : index
// CHECK: %[[VAL_158]] = br %[[VAL_189]] : index
// CHECK: %[[VAL_160]] = br %[[VAL_190]] : index
// CHECK: %[[VAL_162]] = br %[[VAL_191]] : index
// CHECK: %[[VAL_165]] = br %[[VAL_192]] : none
// CHECK: %[[VAL_167]] = br %[[VAL_194]] : index
// CHECK: %[[VAL_195:.*]] = merge %[[VAL_176]] : index
// CHECK: %[[VAL_196:.*]] = merge %[[VAL_178]] : index
// CHECK: %[[VAL_197:.*]] = merge %[[VAL_180]] : index
// CHECK: %[[VAL_198:.*]], %[[VAL_199:.*]] = control_merge %[[VAL_182]] : none
// CHECK: sink %[[VAL_199]] : index
// CHECK: %[[VAL_200:.*]] = br %[[VAL_195]] : index
// CHECK: %[[VAL_201:.*]] = br %[[VAL_196]] : index
// CHECK: %[[VAL_202:.*]] = br %[[VAL_197]] : index
// CHECK: %[[VAL_203:.*]] = br %[[VAL_198]] : none
// CHECK: %[[VAL_204:.*]] = mux %[[VAL_205:.*]]#2 {{\[}}%[[VAL_200]], %[[VAL_128]]] : index, index
// CHECK: %[[VAL_206:.*]] = mux %[[VAL_205]]#1 {{\[}}%[[VAL_201]], %[[VAL_130]]] : index, index
// CHECK: %[[VAL_207:.*]]:2 = fork [2] %[[VAL_206]] : index
// CHECK: %[[VAL_208:.*]] = mux %[[VAL_205]]#0 {{\[}}%[[VAL_202]], %[[VAL_132]]] : index, index
// CHECK: %[[VAL_209:.*]], %[[VAL_210:.*]] = control_merge %[[VAL_203]], %[[VAL_134]] : none
// CHECK: %[[VAL_205]]:3 = fork [3] %[[VAL_210]] : index
// CHECK: %[[VAL_211:.*]] = arith.addi %[[VAL_204]], %[[VAL_207]]#1 : index
// CHECK: %[[VAL_98]] = br %[[VAL_207]]#0 : index
// CHECK: %[[VAL_95]] = br %[[VAL_208]] : index
// CHECK: %[[VAL_101]] = br %[[VAL_209]] : none
// CHECK: %[[VAL_103]] = br %[[VAL_211]] : index
// CHECK: %[[VAL_212:.*]], %[[VAL_213:.*]] = control_merge %[[VAL_112]] : none
// CHECK: sink %[[VAL_213]] : index
// CHECK: return %[[VAL_212]] : none
// CHECK: }
// CHECK: }
func @if_for() {
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index
%1 = arith.muli %c-1, %c-1 : index

View File

@ -1,53 +1,49 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @multi_cond(%arg0: index, %arg1: index, %arg2: index, %arg3: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @multi_cond(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index, %[[VAL_4:.*]]: none, ...) -> none attributes {argNames = ["in0", "in1", "in2", "in3", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_5:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_6:.*]]:2 = "handshake.fork"(%[[VAL_5]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_7:.*]] = "handshake.merge"(%[[VAL_1]]) : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.merge"(%[[VAL_2]]) : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.merge"(%[[VAL_3]]) : (index) -> index
// CHECK: %[[VAL_10:.*]]:8 = "handshake.fork"(%[[VAL_4]]) {control = true} : (none) -> (none, none, none, none, none, none, none, none)
// CHECK: %[[VAL_11:.*]] = "handshake.constant"(%[[VAL_10]]#6) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_12:.*]]:6 = "handshake.fork"(%[[VAL_11]]) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_13:.*]] = "handshake.constant"(%[[VAL_10]]#5) {value = -1 : index} : (none) -> index
// CHECK: handshake.func @multi_cond(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index, %[[VAL_4:.*]]: none, ...) -> none attributes {argNames = ["in0", "in1", "in2", "in3", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_5:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_5]] : index
// CHECK: %[[VAL_7:.*]] = merge %[[VAL_1]] : index
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_2]] : index
// CHECK: %[[VAL_9:.*]] = merge %[[VAL_3]] : index
// CHECK: %[[VAL_10:.*]]:8 = fork [8] %[[VAL_4]] : none
// CHECK: %[[VAL_11:.*]] = constant %[[VAL_10]]#6 {value = 0 : index} : index
// CHECK: %[[VAL_12:.*]]:6 = fork [6] %[[VAL_11]] : index
// CHECK: %[[VAL_13:.*]] = constant %[[VAL_10]]#5 {value = -1 : index} : index
// CHECK: %[[VAL_14:.*]] = arith.muli %[[VAL_12]]#0, %[[VAL_13]] : index
// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_14]], %[[VAL_6]]#1 : index
// CHECK: %[[VAL_16:.*]] = "handshake.constant"(%[[VAL_10]]#4) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_16:.*]] = constant %[[VAL_10]]#4 {value = 1 : index} : index
// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_15]], %[[VAL_16]] : index
// CHECK: %[[VAL_18:.*]] = arith.cmpi sge, %[[VAL_17]], %[[VAL_12]]#1 : index
// CHECK: %[[VAL_19:.*]] = "handshake.constant"(%[[VAL_10]]#3) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_19:.*]] = constant %[[VAL_10]]#3 {value = -1 : index} : index
// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_6]]#0, %[[VAL_19]] : index
// CHECK: %[[VAL_21:.*]] = arith.cmpi sge, %[[VAL_20]], %[[VAL_12]]#2 : index
// CHECK: %[[VAL_22:.*]] = arith.andi %[[VAL_18]], %[[VAL_21]] : i1
// CHECK: %[[VAL_23:.*]] = "handshake.constant"(%[[VAL_10]]#2) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_23:.*]] = constant %[[VAL_10]]#2 {value = -1 : index} : index
// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_7]], %[[VAL_23]] : index
// CHECK: %[[VAL_25:.*]] = arith.cmpi sge, %[[VAL_24]], %[[VAL_12]]#3 : index
// CHECK: %[[VAL_26:.*]] = arith.andi %[[VAL_22]], %[[VAL_25]] : i1
// CHECK: %[[VAL_27:.*]] = "handshake.constant"(%[[VAL_10]]#1) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_27:.*]] = constant %[[VAL_10]]#1 {value = -1 : index} : index
// CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_8]], %[[VAL_27]] : index
// CHECK: %[[VAL_29:.*]] = arith.cmpi sge, %[[VAL_28]], %[[VAL_12]]#4 : index
// CHECK: %[[VAL_30:.*]] = arith.andi %[[VAL_26]], %[[VAL_29]] : i1
// CHECK: %[[VAL_31:.*]] = "handshake.constant"(%[[VAL_10]]#0) {value = -42 : index} : (none) -> index
// CHECK: %[[VAL_31:.*]] = constant %[[VAL_10]]#0 {value = -42 : index} : index
// CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_9]], %[[VAL_31]] : index
// CHECK: %[[VAL_33:.*]] = arith.cmpi eq, %[[VAL_32]], %[[VAL_12]]#5 : index
// CHECK: %[[VAL_34:.*]] = arith.andi %[[VAL_30]], %[[VAL_33]] : i1
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_34]], %[[VAL_10]]#7) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_37:.*]]:2 = "handshake.control_merge"(%[[VAL_35]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_37]]#1) : (index) -> ()
// CHECK: %[[VAL_38:.*]] = "handshake.branch"(%[[VAL_37]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_39:.*]]:2 = "handshake.control_merge"(%[[VAL_36]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_39]]#1) : (index) -> ()
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_39]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_41:.*]]:2 = "handshake.control_merge"(%[[VAL_40]], %[[VAL_38]]) {control = true} : (none, none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_41]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_41]]#0 : none
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = cond_br %[[VAL_34]], %[[VAL_10]]#7 : none
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = control_merge %[[VAL_35]] : none
// CHECK: sink %[[VAL_38]] : index
// CHECK: %[[VAL_39:.*]] = br %[[VAL_37]] : none
// CHECK: %[[VAL_40:.*]], %[[VAL_41:.*]] = control_merge %[[VAL_36]] : none
// CHECK: sink %[[VAL_41]] : index
// CHECK: %[[VAL_42:.*]] = br %[[VAL_40]] : none
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = control_merge %[[VAL_42]], %[[VAL_39]] : none
// CHECK: sink %[[VAL_44]] : index
// CHECK: return %[[VAL_43]] : none
// CHECK: }
// CHECK: }
func @multi_cond(%arg0: index, %arg1: index, %arg2: index, %arg3: index) {
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index
%1 = arith.muli %c0, %c-1 : index

View File

@ -1,58 +1,54 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @nested_ifs() {
// CHECK: module {
// CHECK-LABEL: handshake.func @nested_ifs(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]]:2 = fork [2] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#1 {value = -1 : index} : index
// CHECK: %[[VAL_5:.*]] = arith.muli %[[VAL_3]]#0, %[[VAL_4]] : index
// CHECK: %[[VAL_6:.*]]:2 = "handshake.fork"(%[[VAL_5]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 20 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_5]] : index
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_1]]#0 {value = 20 : index} : index
// CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_6]]#1, %[[VAL_7]] : index
// CHECK: %[[VAL_9:.*]] = arith.cmpi sge, %[[VAL_8]], %[[VAL_3]]#1 : index
// CHECK: %[[VAL_10:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (i1) -> (i1, i1)
// CHECK: %[[VAL_11:.*]], %[[VAL_12:.*]] = "handshake.conditional_branch"(%[[VAL_10]]#1, %[[VAL_1]]#3) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_13:.*]], %[[VAL_14:.*]] = "handshake.conditional_branch"(%[[VAL_10]]#0, %[[VAL_6]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.merge"(%[[VAL_13]]) : (index) -> index
// CHECK: %[[VAL_16:.*]]:2 = "handshake.control_merge"(%[[VAL_11]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_17:.*]]:3 = "handshake.fork"(%[[VAL_16]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_16]]#1) : (index) -> ()
// CHECK: %[[VAL_18:.*]] = "handshake.constant"(%[[VAL_17]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_19:.*]] = "handshake.constant"(%[[VAL_17]]#0) {value = -10 : index} : (none) -> index
// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_15]], %[[VAL_19]] : index
// CHECK: %[[VAL_21:.*]] = arith.cmpi sge, %[[VAL_20]], %[[VAL_18]] : index
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_21]], %[[VAL_17]]#2) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_24:.*]]:2 = "handshake.control_merge"(%[[VAL_22]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_24]]#1) : (index) -> ()
// CHECK: %[[VAL_25:.*]] = "handshake.branch"(%[[VAL_24]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_26:.*]]:2 = "handshake.control_merge"(%[[VAL_25]], %[[VAL_23]]) {control = true} : (none, none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_26]]#1) : (index) -> ()
// CHECK: %[[VAL_27:.*]] = "handshake.branch"(%[[VAL_26]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_28:.*]] = "handshake.merge"(%[[VAL_14]]) : (index) -> index
// CHECK: %[[VAL_29:.*]]:2 = "handshake.control_merge"(%[[VAL_12]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_30:.*]]:3 = "handshake.fork"(%[[VAL_29]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_29]]#1) : (index) -> ()
// CHECK: %[[VAL_31:.*]] = "handshake.constant"(%[[VAL_30]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_32:.*]] = "handshake.constant"(%[[VAL_30]]#0) {value = -10 : index} : (none) -> index
// CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_28]], %[[VAL_32]] : index
// CHECK: %[[VAL_34:.*]] = arith.cmpi sge, %[[VAL_33]], %[[VAL_31]] : index
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_34]], %[[VAL_30]]#2) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_37:.*]]:2 = "handshake.control_merge"(%[[VAL_35]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_37]]#1) : (index) -> ()
// CHECK: %[[VAL_38:.*]] = "handshake.branch"(%[[VAL_37]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_39:.*]]:2 = "handshake.control_merge"(%[[VAL_38]], %[[VAL_36]]) {control = true} : (none, none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_39]]#1) : (index) -> ()
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_39]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_41:.*]]:2 = "handshake.control_merge"(%[[VAL_40]], %[[VAL_27]]) {control = true} : (none, none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_41]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_41]]#0 : none
// CHECK: %[[VAL_10:.*]]:2 = fork [2] %[[VAL_9]] : i1
// CHECK: %[[VAL_11:.*]], %[[VAL_12:.*]] = cond_br %[[VAL_10]]#1, %[[VAL_1]]#3 : none
// CHECK: %[[VAL_13:.*]], %[[VAL_14:.*]] = cond_br %[[VAL_10]]#0, %[[VAL_6]]#0 : index
// CHECK: %[[VAL_15:.*]] = merge %[[VAL_13]] : index
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = control_merge %[[VAL_11]] : none
// CHECK: %[[VAL_18:.*]]:3 = fork [3] %[[VAL_16]] : none
// CHECK: sink %[[VAL_17]] : index
// CHECK: %[[VAL_19:.*]] = constant %[[VAL_18]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_20:.*]] = constant %[[VAL_18]]#0 {value = -10 : index} : index
// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_15]], %[[VAL_20]] : index
// CHECK: %[[VAL_22:.*]] = arith.cmpi sge, %[[VAL_21]], %[[VAL_19]] : index
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = cond_br %[[VAL_22]], %[[VAL_18]]#2 : none
// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]] = control_merge %[[VAL_23]] : none
// CHECK: sink %[[VAL_26]] : index
// CHECK: %[[VAL_27:.*]] = br %[[VAL_25]] : none
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = control_merge %[[VAL_27]], %[[VAL_24]] : none
// CHECK: sink %[[VAL_29]] : index
// CHECK: %[[VAL_30:.*]] = br %[[VAL_28]] : none
// CHECK: %[[VAL_31:.*]] = merge %[[VAL_14]] : index
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = control_merge %[[VAL_12]] : none
// CHECK: %[[VAL_34:.*]]:3 = fork [3] %[[VAL_32]] : none
// CHECK: sink %[[VAL_33]] : index
// CHECK: %[[VAL_35:.*]] = constant %[[VAL_34]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_36:.*]] = constant %[[VAL_34]]#0 {value = -10 : index} : index
// CHECK: %[[VAL_37:.*]] = arith.addi %[[VAL_31]], %[[VAL_36]] : index
// CHECK: %[[VAL_38:.*]] = arith.cmpi sge, %[[VAL_37]], %[[VAL_35]] : index
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = cond_br %[[VAL_38]], %[[VAL_34]]#2 : none
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = control_merge %[[VAL_39]] : none
// CHECK: sink %[[VAL_42]] : index
// CHECK: %[[VAL_43:.*]] = br %[[VAL_41]] : none
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = control_merge %[[VAL_43]], %[[VAL_40]] : none
// CHECK: sink %[[VAL_45]] : index
// CHECK: %[[VAL_46:.*]] = br %[[VAL_44]] : none
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge %[[VAL_46]], %[[VAL_30]] : none
// CHECK: sink %[[VAL_48]] : index
// CHECK: return %[[VAL_47]] : none
// CHECK: }
// CHECK: }
func @nested_ifs() {
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index
%1 = arith.muli %c0, %c-1 : index

View File

@ -1,31 +1,27 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @if_else() {
// CHECK: module {
// CHECK-LABEL: handshake.func @if_else(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]]:2 = fork [2] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#1 {value = -1 : index} : index
// CHECK: %[[VAL_5:.*]] = arith.muli %[[VAL_3]]#0, %[[VAL_4]] : index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 20 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_1]]#0 {value = 20 : index} : index
// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_5]], %[[VAL_6]] : index
// CHECK: %[[VAL_8:.*]] = arith.cmpi sge, %[[VAL_7]], %[[VAL_3]]#1 : index
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = "handshake.conditional_branch"(%[[VAL_8]], %[[VAL_1]]#3) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_11:.*]]:2 = "handshake.control_merge"(%[[VAL_9]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_11]]#1) : (index) -> ()
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_11]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_10]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_13]]#1) : (index) -> ()
// CHECK: %[[VAL_14:.*]] = "handshake.branch"(%[[VAL_13]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_15:.*]]:2 = "handshake.control_merge"(%[[VAL_14]], %[[VAL_12]]) {control = true} : (none, none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_15]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_15]]#0 : none
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = cond_br %[[VAL_8]], %[[VAL_1]]#3 : none
// CHECK: %[[VAL_11:.*]], %[[VAL_12:.*]] = control_merge %[[VAL_9]] : none
// CHECK: sink %[[VAL_12]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_11]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_10]] : none
// CHECK: sink %[[VAL_15]] : index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_14]] : none
// CHECK: %[[VAL_17:.*]], %[[VAL_18:.*]] = control_merge %[[VAL_16]], %[[VAL_13]] : none
// CHECK: sink %[[VAL_18]] : index
// CHECK: return %[[VAL_17]] : none
// CHECK: }
// CHECK: }
func @if_else() {
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index
%1 = arith.muli %c0, %c-1 : index

View File

@ -1,28 +1,24 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @if_only() {
// CHECK: module {
// CHECK-LABEL: handshake.func @if_only(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:4 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_1]]#1) {value = -1 : index} : (none) -> index
// CHECK: %[[VAL_1:.*]]:4 = fork [4] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_3:.*]]:2 = fork [2] %[[VAL_2]] : index
// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]]#1 {value = -1 : index} : index
// CHECK: %[[VAL_5:.*]] = arith.muli %[[VAL_3]]#0, %[[VAL_4]] : index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 20 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_1]]#0 {value = 20 : index} : index
// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_5]], %[[VAL_6]] : index
// CHECK: %[[VAL_8:.*]] = arith.cmpi sge, %[[VAL_7]], %[[VAL_3]]#1 : index
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = "handshake.conditional_branch"(%[[VAL_8]], %[[VAL_1]]#3) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_11:.*]]:2 = "handshake.control_merge"(%[[VAL_9]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_11]]#1) : (index) -> ()
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_11]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_12]], %[[VAL_10]]) {control = true} : (none, none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_13]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_13]]#0 : none
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = cond_br %[[VAL_8]], %[[VAL_1]]#3 : none
// CHECK: %[[VAL_11:.*]], %[[VAL_12:.*]] = control_merge %[[VAL_9]] : none
// CHECK: sink %[[VAL_12]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_11]] : none
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_13]], %[[VAL_10]] : none
// CHECK: sink %[[VAL_15]] : index
// CHECK: return %[[VAL_14]] : none
// CHECK: }
// CHECK: }
func @if_only() {
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index
%1 = arith.muli %c0, %c-1 : index

View File

@ -1,48 +1,44 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @simple_loop() {
// CHECK: module {
// CHECK-LABEL: handshake.func @simple_loop(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = "handshake.branch"(%[[VAL_0]]) {control = true} : (none) -> none
// CHECK: %[[VAL_2:.*]]:2 = "handshake.control_merge"(%[[VAL_1]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_2]]#1) : (index) -> ()
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_4]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_3]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_5]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_5]]#1) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.mux"(%[[VAL_10:.*]]#1, %[[VAL_11:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_14:.*]], %[[VAL_6]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_10]]:2 = "handshake.fork"(%[[VAL_13]]#1) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.mux"(%[[VAL_10]]#0, %[[VAL_16:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_15]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_17]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_19:.*]]:3 = "handshake.fork"(%[[VAL_18]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#2, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_21]]) : (index) -> ()
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#1, %[[VAL_13]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#0, %[[VAL_17]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_27:.*]] = "handshake.merge"(%[[VAL_20]]) : (index) -> index
// CHECK: %[[VAL_28:.*]]:2 = "handshake.control_merge"(%[[VAL_22]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_29:.*]]:2 = "handshake.fork"(%[[VAL_28]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_28]]#1) : (index) -> ()
// CHECK: %[[VAL_30:.*]] = "handshake.constant"(%[[VAL_29]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_31:.*]] = arith.addi %[[VAL_26]], %[[VAL_30]] : index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_27]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_29]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_31]]) {control = false} : (index) -> index
// CHECK: %[[VAL_32:.*]]:2 = "handshake.control_merge"(%[[VAL_23]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_32]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_32]]#0 : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:2 = fork [2] %[[VAL_2]] : none
// CHECK: sink %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_5]] : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_4]]#1 : none
// CHECK: %[[VAL_8:.*]] = br %[[VAL_6]]#0 : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_6]]#1 : index
// CHECK: %[[VAL_10:.*]] = mux %[[VAL_11:.*]]#1 {{\[}}%[[VAL_12:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_13:.*]]:2 = fork [2] %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_16:.*]], %[[VAL_7]] : none
// CHECK: %[[VAL_11]]:2 = fork [2] %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]] = mux %[[VAL_11]]#0 {{\[}}%[[VAL_18:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_19:.*]]:2 = fork [2] %[[VAL_17]] : index
// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_19]]#1, %[[VAL_13]]#1 : index
// CHECK: %[[VAL_21:.*]]:3 = fork [3] %[[VAL_20]] : i1
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = cond_br %[[VAL_21]]#2, %[[VAL_13]]#0 : index
// CHECK: sink %[[VAL_23]] : index
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = cond_br %[[VAL_21]]#1, %[[VAL_14]] : none
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_21]]#0, %[[VAL_19]]#0 : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_29:.*]] = merge %[[VAL_22]] : index
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_24]] : none
// CHECK: %[[VAL_32:.*]]:2 = fork [2] %[[VAL_30]] : none
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_33:.*]] = constant %[[VAL_32]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_34:.*]] = arith.addi %[[VAL_28]], %[[VAL_33]] : index
// CHECK: %[[VAL_12]] = br %[[VAL_29]] : index
// CHECK: %[[VAL_16]] = br %[[VAL_32]]#1 : none
// CHECK: %[[VAL_18]] = br %[[VAL_34]] : index
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = control_merge %[[VAL_25]] : none
// CHECK: sink %[[VAL_36]] : index
// CHECK: return %[[VAL_35]] : none
// CHECK: }
// CHECK: }
func @simple_loop() {
^bb0:
br ^bb1
^bb1: // pred: ^bb0

View File

@ -1,76 +1,72 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_load(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_load(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:3 = "handshake.memory"(%[[VAL_3:.*]]#0, %[[VAL_3]]#1, %[[VAL_4:.*]]) {id = 1 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_2]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_6:.*]]:2 = "handshake.memory"(%[[VAL_7:.*]]) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 0 : i32, type = memref<10xf32>} : (index) -> (f32, none)
// CHECK: %[[VAL_8:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_9:.*]]:4 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_10:.*]] = "handshake.constant"(%[[VAL_9]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_11:.*]] = "handshake.constant"(%[[VAL_9]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.constant"(%[[VAL_9]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14:.*]] = "handshake.branch"(%[[VAL_9]]#3) {control = true} : (none) -> none
// CHECK: %[[VAL_15:.*]] = "handshake.branch"(%[[VAL_10]]) {control = false} : (index) -> index
// CHECK: %[[VAL_16:.*]] = "handshake.branch"(%[[VAL_11]]) {control = false} : (index) -> index
// CHECK: %[[VAL_17:.*]] = "handshake.branch"(%[[VAL_12]]) {control = false} : (index) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.mux"(%[[VAL_19:.*]]#3, %[[VAL_20:.*]], %[[VAL_16]]) : (index, index, index) -> index
// CHECK: %[[VAL_21:.*]]:2 = "handshake.fork"(%[[VAL_18]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_22:.*]] = "handshake.mux"(%[[VAL_19]]#2, %[[VAL_23:.*]], %[[VAL_13]]) : (index, index, index) -> index
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_19]]#1, %[[VAL_25:.*]], %[[VAL_17]]) : (index, index, index) -> index
// CHECK: %[[VAL_26:.*]]:2 = "handshake.control_merge"(%[[VAL_27:.*]], %[[VAL_14]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_19]]:4 = "handshake.fork"(%[[VAL_26]]#1) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_19]]#0, %[[VAL_29:.*]], %[[VAL_15]]) : (index, index, index) -> index
// CHECK: %[[VAL_30:.*]]:2 = "handshake.fork"(%[[VAL_28]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_31:.*]] = arith.cmpi slt, %[[VAL_30]]#1, %[[VAL_21]]#1 : index
// CHECK: %[[VAL_32:.*]]:5 = "handshake.fork"(%[[VAL_31]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1)
// CHECK: %[[VAL_33:.*]], %[[VAL_34:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#4, %[[VAL_21]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_34]]) : (index) -> ()
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#3, %[[VAL_22]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_36]]) : (index) -> ()
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#2, %[[VAL_24]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_38]]) : (index) -> ()
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#1, %[[VAL_26]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = "handshake.conditional_branch"(%[[VAL_32]]#0, %[[VAL_30]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_42]]) : (index) -> ()
// CHECK: %[[VAL_43:.*]] = "handshake.merge"(%[[VAL_41]]) : (index) -> index
// CHECK: %[[VAL_44:.*]]:2 = "handshake.fork"(%[[VAL_43]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_45:.*]] = "handshake.merge"(%[[VAL_35]]) : (index) -> index
// CHECK: %[[VAL_46:.*]]:2 = "handshake.fork"(%[[VAL_45]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_47:.*]] = "handshake.merge"(%[[VAL_37]]) : (index) -> index
// CHECK: %[[VAL_48:.*]]:2 = "handshake.fork"(%[[VAL_47]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_49:.*]] = "handshake.merge"(%[[VAL_33]]) : (index) -> index
// CHECK: %[[VAL_50:.*]]:2 = "handshake.control_merge"(%[[VAL_39]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_51:.*]]:4 = "handshake.fork"(%[[VAL_50]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_52:.*]]:2 = "handshake.fork"(%[[VAL_51]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_53:.*]] = "handshake.join"(%[[VAL_52]]#1, %[[VAL_6]]#1, %[[VAL_5]]#1, %[[VAL_2]]#1) {control = true} : (none, none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_50]]#1) : (index) -> ()
// CHECK: %[[VAL_54:.*]] = arith.addi %[[VAL_44]]#1, %[[VAL_46]]#1 : index
// CHECK: %[[VAL_55:.*]] = "handshake.constant"(%[[VAL_52]]#0) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_56:.*]] = arith.addi %[[VAL_54]], %[[VAL_55]] : index
// CHECK: %[[VAL_57:.*]]:3 = "handshake.fork"(%[[VAL_56]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_58:.*]], %[[VAL_7]] = "handshake.load"(%[[VAL_57]]#2, %[[VAL_6]]#0, %[[VAL_51]]#2) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_59:.*]] = arith.addi %[[VAL_44]]#0, %[[VAL_48]]#1 : index
// CHECK: %[[VAL_60:.*]], %[[VAL_4]] = "handshake.load"(%[[VAL_57]]#1, %[[VAL_2]]#0, %[[VAL_51]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_61:.*]] = arith.addf %[[VAL_58]], %[[VAL_60]] : f32
// CHECK: %[[VAL_62:.*]] = "handshake.join"(%[[VAL_51]]#0, %[[VAL_5]]#0) {control = true} : (none, none) -> none
// CHECK: %[[VAL_3]]:2 = "handshake.store"(%[[VAL_61]], %[[VAL_57]]#0, %[[VAL_62]]) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_23]] = "handshake.branch"(%[[VAL_46]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_25]] = "handshake.branch"(%[[VAL_48]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_20]] = "handshake.branch"(%[[VAL_49]]) {control = false} : (index) -> index
// CHECK: %[[VAL_27]] = "handshake.branch"(%[[VAL_53]]) {control = true} : (none) -> none
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_59]]) {control = false} : (index) -> index
// CHECK: %[[VAL_63:.*]]:2 = "handshake.control_merge"(%[[VAL_40]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_63]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_63]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_3:.*]], %[[VAL_4:.*]], %[[VAL_5:.*]]) {id = 1 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_2]]#2 : none
// CHECK: %[[VAL_7:.*]]:2 = memory[ld = 1, st = 0] (%[[VAL_8:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (index) -> (f32, none)
// CHECK: %[[VAL_9:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_10:.*]]:4 = fork [4] %[[VAL_1]] : none
// CHECK: %[[VAL_11:.*]] = constant %[[VAL_10]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_12:.*]] = constant %[[VAL_10]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_13:.*]] = constant %[[VAL_10]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_14:.*]] = br %[[VAL_9]] : index
// CHECK: %[[VAL_15:.*]] = br %[[VAL_10]]#3 : none
// CHECK: %[[VAL_16:.*]] = br %[[VAL_11]] : index
// CHECK: %[[VAL_17:.*]] = br %[[VAL_12]] : index
// CHECK: %[[VAL_18:.*]] = br %[[VAL_13]] : index
// CHECK: %[[VAL_19:.*]] = mux %[[VAL_20:.*]]#3 {{\[}}%[[VAL_21:.*]], %[[VAL_17]]] : index, index
// CHECK: %[[VAL_22:.*]]:2 = fork [2] %[[VAL_19]] : index
// CHECK: %[[VAL_23:.*]] = mux %[[VAL_20]]#2 {{\[}}%[[VAL_24:.*]], %[[VAL_14]]] : index, index
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_20]]#1 {{\[}}%[[VAL_26:.*]], %[[VAL_18]]] : index, index
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = control_merge %[[VAL_29:.*]], %[[VAL_15]] : none
// CHECK: %[[VAL_20]]:4 = fork [4] %[[VAL_28]] : index
// CHECK: %[[VAL_30:.*]] = mux %[[VAL_20]]#0 {{\[}}%[[VAL_31:.*]], %[[VAL_16]]] : index, index
// CHECK: %[[VAL_32:.*]]:2 = fork [2] %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]] = arith.cmpi slt, %[[VAL_32]]#1, %[[VAL_22]]#1 : index
// CHECK: %[[VAL_34:.*]]:5 = fork [5] %[[VAL_33]] : i1
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = cond_br %[[VAL_34]]#4, %[[VAL_22]]#0 : index
// CHECK: sink %[[VAL_36]] : index
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = cond_br %[[VAL_34]]#3, %[[VAL_23]] : index
// CHECK: sink %[[VAL_38]] : index
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = cond_br %[[VAL_34]]#2, %[[VAL_25]] : index
// CHECK: sink %[[VAL_40]] : index
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = cond_br %[[VAL_34]]#1, %[[VAL_27]] : none
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = cond_br %[[VAL_34]]#0, %[[VAL_32]]#0 : index
// CHECK: sink %[[VAL_44]] : index
// CHECK: %[[VAL_45:.*]] = merge %[[VAL_43]] : index
// CHECK: %[[VAL_46:.*]]:2 = fork [2] %[[VAL_45]] : index
// CHECK: %[[VAL_47:.*]] = merge %[[VAL_37]] : index
// CHECK: %[[VAL_48:.*]]:2 = fork [2] %[[VAL_47]] : index
// CHECK: %[[VAL_49:.*]] = merge %[[VAL_39]] : index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_49]] : index
// CHECK: %[[VAL_51:.*]] = merge %[[VAL_35]] : index
// CHECK: %[[VAL_52:.*]], %[[VAL_53:.*]] = control_merge %[[VAL_41]] : none
// CHECK: %[[VAL_54:.*]]:4 = fork [4] %[[VAL_52]] : none
// CHECK: %[[VAL_55:.*]]:2 = fork [2] %[[VAL_54]]#3 : none
// CHECK: %[[VAL_56:.*]] = join %[[VAL_55]]#1, %[[VAL_7]]#1, %[[VAL_6]]#1, %[[VAL_2]]#1 : none
// CHECK: sink %[[VAL_53]] : index
// CHECK: %[[VAL_57:.*]] = arith.addi %[[VAL_46]]#1, %[[VAL_48]]#1 : index
// CHECK: %[[VAL_58:.*]] = constant %[[VAL_55]]#0 {value = 7 : index} : index
// CHECK: %[[VAL_59:.*]] = arith.addi %[[VAL_57]], %[[VAL_58]] : index
// CHECK: %[[VAL_60:.*]]:3 = fork [3] %[[VAL_59]] : index
// CHECK: %[[VAL_61:.*]], %[[VAL_8]] = load {{\[}}%[[VAL_60]]#2] %[[VAL_7]]#0, %[[VAL_54]]#2 : index, f32
// CHECK: %[[VAL_62:.*]] = arith.addi %[[VAL_46]]#0, %[[VAL_50]]#1 : index
// CHECK: %[[VAL_63:.*]], %[[VAL_5]] = load {{\[}}%[[VAL_60]]#1] %[[VAL_2]]#0, %[[VAL_54]]#1 : index, f32
// CHECK: %[[VAL_64:.*]] = arith.addf %[[VAL_61]], %[[VAL_63]] : f32
// CHECK: %[[VAL_65:.*]] = join %[[VAL_54]]#0, %[[VAL_6]]#0 : none
// CHECK: %[[VAL_3]], %[[VAL_4]] = store {{\[}}%[[VAL_60]]#0] %[[VAL_64]], %[[VAL_65]] : index, f32
// CHECK: %[[VAL_24]] = br %[[VAL_48]]#0 : index
// CHECK: %[[VAL_26]] = br %[[VAL_50]]#0 : index
// CHECK: %[[VAL_21]] = br %[[VAL_51]] : index
// CHECK: %[[VAL_29]] = br %[[VAL_56]] : none
// CHECK: %[[VAL_31]] = br %[[VAL_62]] : index
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = control_merge %[[VAL_42]] : none
// CHECK: sink %[[VAL_67]] : index
// CHECK: return %[[VAL_66]] : none
// CHECK: }
// CHECK: }
func @affine_load(%arg0: index) {
%0 = memref.alloc() : memref<10xf32>
%10 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index

View File

@ -5,35 +5,20 @@
// CHECK-SAME: %[[VAL_0:.*]]: memref<4xi32>,
// CHECK-SAME: %[[VAL_1:.*]]: index,
// CHECK-SAME: %[[VAL_2:.*]]: none, ...) -> none attributes {argNames = ["in0", "in1", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[LDDATA_STNONE_LDNONE:.+]]:3 = handshake.extmemory[ld = 1, st = 1] (%[[VAL_0]] : memref<4xi32>) (%[[STDATA_STIDX0:.+]]#0, %[[STDATA_STIDX0:.+]]#1, %[[LDIDX0:.+]]) {id = 0 : i32} : (i32, index, index) -> (i32, none, none)
// CHECK: %[[STNONE_STNONE:.+]]:2 = "handshake.fork"(%[[LDDATA_STNONE_LDNONE:.+]]#1) {control = true} : (none) -> (none, none)
// Fork index0 and index1 to load and store operation.
// CHECK: %[[IDX0:.+]] = "handshake.merge"(%[[VAL_1]]) : (index) -> index
// CHECK: %[[IDX0_IDX0:.+]]:2 = "handshake.fork"(%[[IDX0:.+]]) {control = false} : (index) -> (index, index)
// Fork input control signal.
// CHECK: %[[CTRL_CTRL_CTRL:.+]]:3 = "handshake.fork"(%[[VAL_2]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[CTRL_CTRL:.+]]:2 = "handshake.fork"(%[[CTRL_CTRL_CTRL:.+]]#2) {control = true} : (none) -> (none, none)
// This indicates the completion of all operations.
// CHECK: %[[STLDNONE_AND_CTRL:.+]] = "handshake.join"(%[[CTRL_CTRL:.+]]#1, %[[STNONE_STNONE:.+]]#1, %[[LDDATA_STNONE_LDNONE:.+]]#2) {control = true} : (none, none, none) -> none
// Store operation logic.
// CHECK: %[[C1_I32:.+]] = "handshake.constant"(%[[CTRL_CTRL:.+]]#0) {value = 11 : i32} : (none) -> i32
// CHECK: %[[STDATA_STIDX0:.+]]:2 = "handshake.store"(%[[C1_I32:.+]], %[[IDX0_IDX0:.+]]#1, %[[CTRL_CTRL_CTRL:.+]]#1) : (i32, index, none) -> (i32, index)
// This indicates the completion of store operation.
// CHECK: %[[STNONE_AND_CTRL:.+]] = "handshake.join"(%[[CTRL_CTRL_CTRL:.+]]#0, %[[STNONE_STNONE:.+]]#0) {control = true} : (none, none) -> none
// Load operation logic.
// CHECK: %[[LDDATA:.+]], %[[LDIDX0:.+]] = "handshake.load"(%[[IDX0_IDX0:.+]]#0, %[[LDDATA_STNONE_LDNONE:.+]]#0, %[[STNONE_AND_CTRL:.+]]) : (index, i32, none) -> (i32, index)
// Result of load operation is sinked.
// CHECK: "handshake.sink"(%[[LDDATA:.+]]) : (i32) -> ()
// CHECK: handshake.return %[[STLDNONE_AND_CTRL:.+]] : none
// CHECK: }
// CHECK: %[[VAL_3:.*]]:3 = extmemory[ld = 1, st = 1] (%[[VAL_0]] : memref<4xi32>) (%[[VAL_4:.*]], %[[VAL_5:.*]], %[[VAL_6:.*]]) {id = 0 : i32} : (i32, index, index) -> (i32, none, none)
// CHECK: %[[VAL_7:.*]]:2 = fork [2] %[[VAL_3]]#1 : none
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_1]] : index
// CHECK: %[[VAL_9:.*]]:2 = fork [2] %[[VAL_8]] : index
// CHECK: %[[VAL_10:.*]]:3 = fork [3] %[[VAL_2]] : none
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_10]]#2 : none
// CHECK: %[[VAL_12:.*]] = join %[[VAL_11]]#1, %[[VAL_7]]#1, %[[VAL_3]]#2 : none
// CHECK: %[[VAL_13:.*]] = constant %[[VAL_11]]#0 {value = 11 : i32} : i32
// CHECK: %[[VAL_4]], %[[VAL_5]] = store {{\[}}%[[VAL_9]]#1] %[[VAL_13]], %[[VAL_10]]#1 : index, i32
// CHECK: %[[VAL_14:.*]] = join %[[VAL_10]]#0, %[[VAL_7]]#0 : none
// CHECK: %[[VAL_15:.*]], %[[VAL_6]] = load {{\[}}%[[VAL_9]]#0] %[[VAL_3]]#0, %[[VAL_14]] : index, i32
// CHECK: sink %[[VAL_15]] : i32
// CHECK: return %[[VAL_12]] : none
// CHECK: }
func @load_store(%0 : memref<4xi32>, %1 : index) {
%c1 = arith.constant 11 : i32
memref.store %c1, %0[%1] : memref<4xi32>

View File

@ -1,148 +1,144 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @more_imperfectly_nested_loops() {
// CHECK: module {
// CHECK-LABEL: handshake.func @more_imperfectly_nested_loops(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = "handshake.branch"(%[[VAL_0]]) {control = true} : (none) -> none
// CHECK: %[[VAL_2:.*]]:2 = "handshake.control_merge"(%[[VAL_1]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_3:.*]]:3 = "handshake.fork"(%[[VAL_2]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_2]]#1) : (index) -> ()
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_3]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_7:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.mux"(%[[VAL_10:.*]]#1, %[[VAL_11:.*]], %[[VAL_8]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_9]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_14:.*]], %[[VAL_6]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_10]]:2 = "handshake.fork"(%[[VAL_13]]#1) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.mux"(%[[VAL_10]]#0, %[[VAL_16:.*]], %[[VAL_7]]) : (index, index, index) -> index
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_15]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_17]]#1, %[[VAL_12]]#1 : index
// CHECK: %[[VAL_19:.*]]:3 = "handshake.fork"(%[[VAL_18]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#2, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_21]]) : (index) -> ()
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#1, %[[VAL_13]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_19]]#0, %[[VAL_17]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_27:.*]] = "handshake.merge"(%[[VAL_20]]) : (index) -> index
// CHECK: %[[VAL_28:.*]]:2 = "handshake.control_merge"(%[[VAL_22]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_28]]#1) : (index) -> ()
// CHECK: %[[VAL_29:.*]] = "handshake.branch"(%[[VAL_26]]) {control = false} : (index) -> index
// CHECK: %[[VAL_30:.*]] = "handshake.branch"(%[[VAL_27]]) {control = false} : (index) -> index
// CHECK: %[[VAL_31:.*]] = "handshake.branch"(%[[VAL_28]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_32:.*]] = "handshake.merge"(%[[VAL_29]]) : (index) -> index
// CHECK: %[[VAL_33:.*]] = "handshake.merge"(%[[VAL_30]]) : (index) -> index
// CHECK: %[[VAL_34:.*]]:2 = "handshake.control_merge"(%[[VAL_31]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_35:.*]]:3 = "handshake.fork"(%[[VAL_34]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_34]]#1) : (index) -> ()
// CHECK: %[[VAL_36:.*]] = "handshake.constant"(%[[VAL_35]]#1) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_37:.*]] = "handshake.constant"(%[[VAL_35]]#0) {value = 56 : index} : (none) -> index
// CHECK: %[[VAL_38:.*]] = "handshake.branch"(%[[VAL_32]]) {control = false} : (index) -> index
// CHECK: %[[VAL_39:.*]] = "handshake.branch"(%[[VAL_33]]) {control = false} : (index) -> index
// CHECK: %[[VAL_40:.*]] = "handshake.branch"(%[[VAL_35]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_41:.*]] = "handshake.branch"(%[[VAL_36]]) {control = false} : (index) -> index
// CHECK: %[[VAL_42:.*]] = "handshake.branch"(%[[VAL_37]]) {control = false} : (index) -> index
// CHECK: %[[VAL_43:.*]] = "handshake.mux"(%[[VAL_44:.*]]#3, %[[VAL_45:.*]], %[[VAL_42]]) : (index, index, index) -> index
// CHECK: %[[VAL_46:.*]]:2 = "handshake.fork"(%[[VAL_43]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_47:.*]] = "handshake.mux"(%[[VAL_44]]#2, %[[VAL_48:.*]], %[[VAL_38]]) : (index, index, index) -> index
// CHECK: %[[VAL_49:.*]] = "handshake.mux"(%[[VAL_44]]#1, %[[VAL_50:.*]], %[[VAL_39]]) : (index, index, index) -> index
// CHECK: %[[VAL_51:.*]]:2 = "handshake.control_merge"(%[[VAL_52:.*]], %[[VAL_40]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_44]]:4 = "handshake.fork"(%[[VAL_51]]#1) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_53:.*]] = "handshake.mux"(%[[VAL_44]]#0, %[[VAL_54:.*]], %[[VAL_41]]) : (index, index, index) -> index
// CHECK: %[[VAL_55:.*]]:2 = "handshake.fork"(%[[VAL_53]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_56:.*]] = arith.cmpi slt, %[[VAL_55]]#1, %[[VAL_46]]#1 : index
// CHECK: %[[VAL_57:.*]]:5 = "handshake.fork"(%[[VAL_56]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1)
// CHECK: %[[VAL_58:.*]], %[[VAL_59:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#4, %[[VAL_46]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_59]]) : (index) -> ()
// CHECK: %[[VAL_60:.*]], %[[VAL_61:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#3, %[[VAL_47]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_62:.*]], %[[VAL_63:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#2, %[[VAL_49]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#1, %[[VAL_51]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_66:.*]], %[[VAL_67:.*]] = "handshake.conditional_branch"(%[[VAL_57]]#0, %[[VAL_55]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_67]]) : (index) -> ()
// CHECK: %[[VAL_68:.*]] = "handshake.merge"(%[[VAL_66]]) : (index) -> index
// CHECK: %[[VAL_69:.*]] = "handshake.merge"(%[[VAL_58]]) : (index) -> index
// CHECK: %[[VAL_70:.*]] = "handshake.merge"(%[[VAL_60]]) : (index) -> index
// CHECK: %[[VAL_71:.*]] = "handshake.merge"(%[[VAL_62]]) : (index) -> index
// CHECK: %[[VAL_72:.*]]:2 = "handshake.control_merge"(%[[VAL_64]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_73:.*]]:2 = "handshake.fork"(%[[VAL_72]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_72]]#1) : (index) -> ()
// CHECK: %[[VAL_74:.*]] = "handshake.constant"(%[[VAL_73]]#0) {value = 2 : index} : (none) -> index
// CHECK: %[[VAL_75:.*]] = arith.addi %[[VAL_68]], %[[VAL_74]] : index
// CHECK: %[[VAL_45]] = "handshake.branch"(%[[VAL_69]]) {control = false} : (index) -> index
// CHECK: %[[VAL_48]] = "handshake.branch"(%[[VAL_70]]) {control = false} : (index) -> index
// CHECK: %[[VAL_50]] = "handshake.branch"(%[[VAL_71]]) {control = false} : (index) -> index
// CHECK: %[[VAL_52]] = "handshake.branch"(%[[VAL_73]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_54]] = "handshake.branch"(%[[VAL_75]]) {control = false} : (index) -> index
// CHECK: %[[VAL_76:.*]] = "handshake.merge"(%[[VAL_61]]) : (index) -> index
// CHECK: %[[VAL_77:.*]] = "handshake.merge"(%[[VAL_63]]) : (index) -> index
// CHECK: %[[VAL_78:.*]]:2 = "handshake.control_merge"(%[[VAL_65]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_78]]#1) : (index) -> ()
// CHECK: %[[VAL_79:.*]] = "handshake.branch"(%[[VAL_76]]) {control = false} : (index) -> index
// CHECK: %[[VAL_80:.*]] = "handshake.branch"(%[[VAL_77]]) {control = false} : (index) -> index
// CHECK: %[[VAL_81:.*]] = "handshake.branch"(%[[VAL_78]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_82:.*]] = "handshake.merge"(%[[VAL_79]]) : (index) -> index
// CHECK: %[[VAL_83:.*]] = "handshake.merge"(%[[VAL_80]]) : (index) -> index
// CHECK: %[[VAL_84:.*]]:2 = "handshake.control_merge"(%[[VAL_81]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_85:.*]]:3 = "handshake.fork"(%[[VAL_84]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_84]]#1) : (index) -> ()
// CHECK: %[[VAL_86:.*]] = "handshake.constant"(%[[VAL_85]]#1) {value = 18 : index} : (none) -> index
// CHECK: %[[VAL_87:.*]] = "handshake.constant"(%[[VAL_85]]#0) {value = 37 : index} : (none) -> index
// CHECK: %[[VAL_88:.*]] = "handshake.branch"(%[[VAL_82]]) {control = false} : (index) -> index
// CHECK: %[[VAL_89:.*]] = "handshake.branch"(%[[VAL_83]]) {control = false} : (index) -> index
// CHECK: %[[VAL_90:.*]] = "handshake.branch"(%[[VAL_85]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_91:.*]] = "handshake.branch"(%[[VAL_86]]) {control = false} : (index) -> index
// CHECK: %[[VAL_92:.*]] = "handshake.branch"(%[[VAL_87]]) {control = false} : (index) -> index
// CHECK: %[[VAL_93:.*]] = "handshake.mux"(%[[VAL_94:.*]]#3, %[[VAL_95:.*]], %[[VAL_92]]) : (index, index, index) -> index
// CHECK: %[[VAL_96:.*]]:2 = "handshake.fork"(%[[VAL_93]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_97:.*]] = "handshake.mux"(%[[VAL_94]]#2, %[[VAL_98:.*]], %[[VAL_88]]) : (index, index, index) -> index
// CHECK: %[[VAL_99:.*]] = "handshake.mux"(%[[VAL_94]]#1, %[[VAL_100:.*]], %[[VAL_89]]) : (index, index, index) -> index
// CHECK: %[[VAL_101:.*]]:2 = "handshake.control_merge"(%[[VAL_102:.*]], %[[VAL_90]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_94]]:4 = "handshake.fork"(%[[VAL_101]]#1) {control = false} : (index) -> (index, index, index, index)
// CHECK: %[[VAL_103:.*]] = "handshake.mux"(%[[VAL_94]]#0, %[[VAL_104:.*]], %[[VAL_91]]) : (index, index, index) -> index
// CHECK: %[[VAL_105:.*]]:2 = "handshake.fork"(%[[VAL_103]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_106:.*]] = arith.cmpi slt, %[[VAL_105]]#1, %[[VAL_96]]#1 : index
// CHECK: %[[VAL_107:.*]]:5 = "handshake.fork"(%[[VAL_106]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1)
// CHECK: %[[VAL_108:.*]], %[[VAL_109:.*]] = "handshake.conditional_branch"(%[[VAL_107]]#4, %[[VAL_96]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_109]]) : (index) -> ()
// CHECK: %[[VAL_110:.*]], %[[VAL_111:.*]] = "handshake.conditional_branch"(%[[VAL_107]]#3, %[[VAL_97]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_112:.*]], %[[VAL_113:.*]] = "handshake.conditional_branch"(%[[VAL_107]]#2, %[[VAL_99]]) {control = false} : (i1, index) -> (index, index)
// CHECK: %[[VAL_114:.*]], %[[VAL_115:.*]] = "handshake.conditional_branch"(%[[VAL_107]]#1, %[[VAL_101]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_116:.*]], %[[VAL_117:.*]] = "handshake.conditional_branch"(%[[VAL_107]]#0, %[[VAL_105]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_117]]) : (index) -> ()
// CHECK: %[[VAL_118:.*]] = "handshake.merge"(%[[VAL_116]]) : (index) -> index
// CHECK: %[[VAL_119:.*]] = "handshake.merge"(%[[VAL_108]]) : (index) -> index
// CHECK: %[[VAL_120:.*]] = "handshake.merge"(%[[VAL_110]]) : (index) -> index
// CHECK: %[[VAL_121:.*]] = "handshake.merge"(%[[VAL_112]]) : (index) -> index
// CHECK: %[[VAL_122:.*]]:2 = "handshake.control_merge"(%[[VAL_114]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_123:.*]]:2 = "handshake.fork"(%[[VAL_122]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_122]]#1) : (index) -> ()
// CHECK: %[[VAL_124:.*]] = "handshake.constant"(%[[VAL_123]]#0) {value = 3 : index} : (none) -> index
// CHECK: %[[VAL_125:.*]] = arith.addi %[[VAL_118]], %[[VAL_124]] : index
// CHECK: %[[VAL_95]] = "handshake.branch"(%[[VAL_119]]) {control = false} : (index) -> index
// CHECK: %[[VAL_98]] = "handshake.branch"(%[[VAL_120]]) {control = false} : (index) -> index
// CHECK: %[[VAL_100]] = "handshake.branch"(%[[VAL_121]]) {control = false} : (index) -> index
// CHECK: %[[VAL_102]] = "handshake.branch"(%[[VAL_123]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_104]] = "handshake.branch"(%[[VAL_125]]) {control = false} : (index) -> index
// CHECK: %[[VAL_126:.*]] = "handshake.merge"(%[[VAL_111]]) : (index) -> index
// CHECK: %[[VAL_127:.*]] = "handshake.merge"(%[[VAL_113]]) : (index) -> index
// CHECK: %[[VAL_128:.*]]:2 = "handshake.control_merge"(%[[VAL_115]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_129:.*]]:2 = "handshake.fork"(%[[VAL_128]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_128]]#1) : (index) -> ()
// CHECK: %[[VAL_130:.*]] = "handshake.constant"(%[[VAL_129]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_131:.*]] = arith.addi %[[VAL_126]], %[[VAL_130]] : index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_127]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14]] = "handshake.branch"(%[[VAL_129]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_16]] = "handshake.branch"(%[[VAL_131]]) {control = false} : (index) -> index
// CHECK: %[[VAL_132:.*]]:2 = "handshake.control_merge"(%[[VAL_23]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_132]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_132]]#0 : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:3 = fork [3] %[[VAL_2]] : none
// CHECK: sink %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_4]]#0 {value = 42 : index} : index
// CHECK: %[[VAL_7:.*]] = br %[[VAL_4]]#2 : none
// CHECK: %[[VAL_8:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_6]] : index
// CHECK: %[[VAL_10:.*]] = mux %[[VAL_11:.*]]#1 {{\[}}%[[VAL_12:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_13:.*]]:2 = fork [2] %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_16:.*]], %[[VAL_7]] : none
// CHECK: %[[VAL_11]]:2 = fork [2] %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]] = mux %[[VAL_11]]#0 {{\[}}%[[VAL_18:.*]], %[[VAL_8]]] : index, index
// CHECK: %[[VAL_19:.*]]:2 = fork [2] %[[VAL_17]] : index
// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_19]]#1, %[[VAL_13]]#1 : index
// CHECK: %[[VAL_21:.*]]:3 = fork [3] %[[VAL_20]] : i1
// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = cond_br %[[VAL_21]]#2, %[[VAL_13]]#0 : index
// CHECK: sink %[[VAL_23]] : index
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = cond_br %[[VAL_21]]#1, %[[VAL_14]] : none
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_21]]#0, %[[VAL_19]]#0 : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_29:.*]] = merge %[[VAL_22]] : index
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_24]] : none
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]] = br %[[VAL_28]] : index
// CHECK: %[[VAL_33:.*]] = br %[[VAL_29]] : index
// CHECK: %[[VAL_34:.*]] = br %[[VAL_30]] : none
// CHECK: %[[VAL_35:.*]] = merge %[[VAL_32]] : index
// CHECK: %[[VAL_36:.*]] = merge %[[VAL_33]] : index
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = control_merge %[[VAL_34]] : none
// CHECK: %[[VAL_39:.*]]:3 = fork [3] %[[VAL_37]] : none
// CHECK: sink %[[VAL_38]] : index
// CHECK: %[[VAL_40:.*]] = constant %[[VAL_39]]#1 {value = 7 : index} : index
// CHECK: %[[VAL_41:.*]] = constant %[[VAL_39]]#0 {value = 56 : index} : index
// CHECK: %[[VAL_42:.*]] = br %[[VAL_35]] : index
// CHECK: %[[VAL_43:.*]] = br %[[VAL_36]] : index
// CHECK: %[[VAL_44:.*]] = br %[[VAL_39]]#2 : none
// CHECK: %[[VAL_45:.*]] = br %[[VAL_40]] : index
// CHECK: %[[VAL_46:.*]] = br %[[VAL_41]] : index
// CHECK: %[[VAL_47:.*]] = mux %[[VAL_48:.*]]#3 {{\[}}%[[VAL_49:.*]], %[[VAL_46]]] : index, index
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_47]] : index
// CHECK: %[[VAL_51:.*]] = mux %[[VAL_48]]#2 {{\[}}%[[VAL_52:.*]], %[[VAL_42]]] : index, index
// CHECK: %[[VAL_53:.*]] = mux %[[VAL_48]]#1 {{\[}}%[[VAL_54:.*]], %[[VAL_43]]] : index, index
// CHECK: %[[VAL_55:.*]], %[[VAL_56:.*]] = control_merge %[[VAL_57:.*]], %[[VAL_44]] : none
// CHECK: %[[VAL_48]]:4 = fork [4] %[[VAL_56]] : index
// CHECK: %[[VAL_58:.*]] = mux %[[VAL_48]]#0 {{\[}}%[[VAL_59:.*]], %[[VAL_45]]] : index, index
// CHECK: %[[VAL_60:.*]]:2 = fork [2] %[[VAL_58]] : index
// CHECK: %[[VAL_61:.*]] = arith.cmpi slt, %[[VAL_60]]#1, %[[VAL_50]]#1 : index
// CHECK: %[[VAL_62:.*]]:5 = fork [5] %[[VAL_61]] : i1
// CHECK: %[[VAL_63:.*]], %[[VAL_64:.*]] = cond_br %[[VAL_62]]#4, %[[VAL_50]]#0 : index
// CHECK: sink %[[VAL_64]] : index
// CHECK: %[[VAL_65:.*]], %[[VAL_66:.*]] = cond_br %[[VAL_62]]#3, %[[VAL_51]] : index
// CHECK: %[[VAL_67:.*]], %[[VAL_68:.*]] = cond_br %[[VAL_62]]#2, %[[VAL_53]] : index
// CHECK: %[[VAL_69:.*]], %[[VAL_70:.*]] = cond_br %[[VAL_62]]#1, %[[VAL_55]] : none
// CHECK: %[[VAL_71:.*]], %[[VAL_72:.*]] = cond_br %[[VAL_62]]#0, %[[VAL_60]]#0 : index
// CHECK: sink %[[VAL_72]] : index
// CHECK: %[[VAL_73:.*]] = merge %[[VAL_71]] : index
// CHECK: %[[VAL_74:.*]] = merge %[[VAL_63]] : index
// CHECK: %[[VAL_75:.*]] = merge %[[VAL_65]] : index
// CHECK: %[[VAL_76:.*]] = merge %[[VAL_67]] : index
// CHECK: %[[VAL_77:.*]], %[[VAL_78:.*]] = control_merge %[[VAL_69]] : none
// CHECK: %[[VAL_79:.*]]:2 = fork [2] %[[VAL_77]] : none
// CHECK: sink %[[VAL_78]] : index
// CHECK: %[[VAL_80:.*]] = constant %[[VAL_79]]#0 {value = 2 : index} : index
// CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_73]], %[[VAL_80]] : index
// CHECK: %[[VAL_49]] = br %[[VAL_74]] : index
// CHECK: %[[VAL_52]] = br %[[VAL_75]] : index
// CHECK: %[[VAL_54]] = br %[[VAL_76]] : index
// CHECK: %[[VAL_57]] = br %[[VAL_79]]#1 : none
// CHECK: %[[VAL_59]] = br %[[VAL_81]] : index
// CHECK: %[[VAL_82:.*]] = merge %[[VAL_66]] : index
// CHECK: %[[VAL_83:.*]] = merge %[[VAL_68]] : index
// CHECK: %[[VAL_84:.*]], %[[VAL_85:.*]] = control_merge %[[VAL_70]] : none
// CHECK: sink %[[VAL_85]] : index
// CHECK: %[[VAL_86:.*]] = br %[[VAL_82]] : index
// CHECK: %[[VAL_87:.*]] = br %[[VAL_83]] : index
// CHECK: %[[VAL_88:.*]] = br %[[VAL_84]] : none
// CHECK: %[[VAL_89:.*]] = merge %[[VAL_86]] : index
// CHECK: %[[VAL_90:.*]] = merge %[[VAL_87]] : index
// CHECK: %[[VAL_91:.*]], %[[VAL_92:.*]] = control_merge %[[VAL_88]] : none
// CHECK: %[[VAL_93:.*]]:3 = fork [3] %[[VAL_91]] : none
// CHECK: sink %[[VAL_92]] : index
// CHECK: %[[VAL_94:.*]] = constant %[[VAL_93]]#1 {value = 18 : index} : index
// CHECK: %[[VAL_95:.*]] = constant %[[VAL_93]]#0 {value = 37 : index} : index
// CHECK: %[[VAL_96:.*]] = br %[[VAL_89]] : index
// CHECK: %[[VAL_97:.*]] = br %[[VAL_90]] : index
// CHECK: %[[VAL_98:.*]] = br %[[VAL_93]]#2 : none
// CHECK: %[[VAL_99:.*]] = br %[[VAL_94]] : index
// CHECK: %[[VAL_100:.*]] = br %[[VAL_95]] : index
// CHECK: %[[VAL_101:.*]] = mux %[[VAL_102:.*]]#3 {{\[}}%[[VAL_103:.*]], %[[VAL_100]]] : index, index
// CHECK: %[[VAL_104:.*]]:2 = fork [2] %[[VAL_101]] : index
// CHECK: %[[VAL_105:.*]] = mux %[[VAL_102]]#2 {{\[}}%[[VAL_106:.*]], %[[VAL_96]]] : index, index
// CHECK: %[[VAL_107:.*]] = mux %[[VAL_102]]#1 {{\[}}%[[VAL_108:.*]], %[[VAL_97]]] : index, index
// CHECK: %[[VAL_109:.*]], %[[VAL_110:.*]] = control_merge %[[VAL_111:.*]], %[[VAL_98]] : none
// CHECK: %[[VAL_102]]:4 = fork [4] %[[VAL_110]] : index
// CHECK: %[[VAL_112:.*]] = mux %[[VAL_102]]#0 {{\[}}%[[VAL_113:.*]], %[[VAL_99]]] : index, index
// CHECK: %[[VAL_114:.*]]:2 = fork [2] %[[VAL_112]] : index
// CHECK: %[[VAL_115:.*]] = arith.cmpi slt, %[[VAL_114]]#1, %[[VAL_104]]#1 : index
// CHECK: %[[VAL_116:.*]]:5 = fork [5] %[[VAL_115]] : i1
// CHECK: %[[VAL_117:.*]], %[[VAL_118:.*]] = cond_br %[[VAL_116]]#4, %[[VAL_104]]#0 : index
// CHECK: sink %[[VAL_118]] : index
// CHECK: %[[VAL_119:.*]], %[[VAL_120:.*]] = cond_br %[[VAL_116]]#3, %[[VAL_105]] : index
// CHECK: %[[VAL_121:.*]], %[[VAL_122:.*]] = cond_br %[[VAL_116]]#2, %[[VAL_107]] : index
// CHECK: %[[VAL_123:.*]], %[[VAL_124:.*]] = cond_br %[[VAL_116]]#1, %[[VAL_109]] : none
// CHECK: %[[VAL_125:.*]], %[[VAL_126:.*]] = cond_br %[[VAL_116]]#0, %[[VAL_114]]#0 : index
// CHECK: sink %[[VAL_126]] : index
// CHECK: %[[VAL_127:.*]] = merge %[[VAL_125]] : index
// CHECK: %[[VAL_128:.*]] = merge %[[VAL_117]] : index
// CHECK: %[[VAL_129:.*]] = merge %[[VAL_119]] : index
// CHECK: %[[VAL_130:.*]] = merge %[[VAL_121]] : index
// CHECK: %[[VAL_131:.*]], %[[VAL_132:.*]] = control_merge %[[VAL_123]] : none
// CHECK: %[[VAL_133:.*]]:2 = fork [2] %[[VAL_131]] : none
// CHECK: sink %[[VAL_132]] : index
// CHECK: %[[VAL_134:.*]] = constant %[[VAL_133]]#0 {value = 3 : index} : index
// CHECK: %[[VAL_135:.*]] = arith.addi %[[VAL_127]], %[[VAL_134]] : index
// CHECK: %[[VAL_103]] = br %[[VAL_128]] : index
// CHECK: %[[VAL_106]] = br %[[VAL_129]] : index
// CHECK: %[[VAL_108]] = br %[[VAL_130]] : index
// CHECK: %[[VAL_111]] = br %[[VAL_133]]#1 : none
// CHECK: %[[VAL_113]] = br %[[VAL_135]] : index
// CHECK: %[[VAL_136:.*]] = merge %[[VAL_120]] : index
// CHECK: %[[VAL_137:.*]] = merge %[[VAL_122]] : index
// CHECK: %[[VAL_138:.*]], %[[VAL_139:.*]] = control_merge %[[VAL_124]] : none
// CHECK: %[[VAL_140:.*]]:2 = fork [2] %[[VAL_138]] : none
// CHECK: sink %[[VAL_139]] : index
// CHECK: %[[VAL_141:.*]] = constant %[[VAL_140]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_142:.*]] = arith.addi %[[VAL_136]], %[[VAL_141]] : index
// CHECK: %[[VAL_12]] = br %[[VAL_137]] : index
// CHECK: %[[VAL_16]] = br %[[VAL_140]]#1 : none
// CHECK: %[[VAL_18]] = br %[[VAL_142]] : index
// CHECK: %[[VAL_143:.*]], %[[VAL_144:.*]] = control_merge %[[VAL_25]] : none
// CHECK: sink %[[VAL_144]] : index
// CHECK: return %[[VAL_143]] : none
// CHECK: }
// CHECK: }
func @more_imperfectly_nested_loops() {
^bb0:
br ^bb1
^bb1: // pred: ^bb0

View File

@ -1,88 +1,85 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_load(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_load(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:7 = "handshake.memory"(%[[VAL_3:.*]]#0, %[[VAL_3]]#1, %[[VAL_4:.*]], %[[VAL_5:.*]], %[[VAL_6:.*]]) {id = 0 : i32, ld_count = 3 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index, index, index) -> (f32, f32, f32, none, none, none, none)
// CHECK: %[[VAL_7:.*]]:2 = "handshake.fork"(%[[VAL_2]]#6) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_8:.*]]:2 = "handshake.fork"(%[[VAL_2]]#5) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_9:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_10:.*]]:2 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_11:.*]]:4 = "handshake.fork"(%[[VAL_10]]#1) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_12:.*]] = "handshake.join"(%[[VAL_11]]#3, %[[VAL_2]]#4) {control = true} : (none, none) -> none
// CHECK: %[[VAL_13:.*]] = "handshake.constant"(%[[VAL_11]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_14:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.constant"(%[[VAL_11]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_16:.*]], %[[VAL_4]] = "handshake.load"(%[[VAL_14]]#0, %[[VAL_2]]#0, %[[VAL_10]]#0) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_17:.*]] = "handshake.constant"(%[[VAL_11]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_19:.*]] = "handshake.branch"(%[[VAL_12]]) {control = true} : (none) -> none
// CHECK: %[[VAL_20:.*]] = "handshake.branch"(%[[VAL_14]]#1) {control = false} : (index) -> index
// CHECK: %[[VAL_21:.*]] = "handshake.branch"(%[[VAL_15]]) {control = false} : (index) -> index
// CHECK: %[[VAL_22:.*]] = "handshake.branch"(%[[VAL_16]]) {control = false} : (f32) -> f32
// CHECK: %[[VAL_23:.*]] = "handshake.branch"(%[[VAL_17]]) {control = false} : (index) -> index
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_25:.*]]#4, %[[VAL_26:.*]], %[[VAL_21]]) : (index, index, index) -> index
// CHECK: %[[VAL_27:.*]]:2 = "handshake.fork"(%[[VAL_24]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_25]]#3, %[[VAL_29:.*]], %[[VAL_18]]) : (index, index, index) -> index
// CHECK: %[[VAL_30:.*]] = "handshake.mux"(%[[VAL_25]]#2, %[[VAL_31:.*]], %[[VAL_23]]) : (index, index, index) -> index
// CHECK: %[[VAL_32:.*]] = "handshake.mux"(%[[VAL_25]]#1, %[[VAL_33:.*]], %[[VAL_22]]) : (index, f32, f32) -> f32
// CHECK: %[[VAL_34:.*]]:2 = "handshake.control_merge"(%[[VAL_35:.*]], %[[VAL_19]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_25]]:5 = "handshake.fork"(%[[VAL_34]]#1) {control = false} : (index) -> (index, index, index, index, index)
// CHECK: %[[VAL_36:.*]] = "handshake.mux"(%[[VAL_25]]#0, %[[VAL_37:.*]], %[[VAL_20]]) : (index, index, index) -> index
// CHECK: %[[VAL_38:.*]]:2 = "handshake.fork"(%[[VAL_36]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_39:.*]] = arith.cmpi slt, %[[VAL_38]]#1, %[[VAL_27]]#1 : index
// CHECK: %[[VAL_40:.*]]:6 = "handshake.fork"(%[[VAL_39]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#5, %[[VAL_27]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_42]]) : (index) -> ()
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#4, %[[VAL_28]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_44]]) : (index) -> ()
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#3, %[[VAL_30]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_46]]) : (index) -> ()
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#2, %[[VAL_32]]) {control = false} : (i1, f32) -> (f32, f32)
// CHECK: "handshake.sink"(%[[VAL_48]]) : (f32) -> ()
// CHECK: %[[VAL_49:.*]], %[[VAL_50:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#1, %[[VAL_34]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_51:.*]], %[[VAL_52:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#0, %[[VAL_38]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_52]]) : (index) -> ()
// CHECK: %[[VAL_53:.*]] = "handshake.merge"(%[[VAL_51]]) : (index) -> index
// CHECK: %[[VAL_54:.*]]:2 = "handshake.fork"(%[[VAL_53]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_55:.*]] = "handshake.merge"(%[[VAL_43]]) : (index) -> index
// CHECK: %[[VAL_56:.*]]:2 = "handshake.fork"(%[[VAL_55]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_57:.*]] = "handshake.merge"(%[[VAL_45]]) : (index) -> index
// CHECK: %[[VAL_58:.*]]:2 = "handshake.fork"(%[[VAL_57]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_59:.*]] = "handshake.merge"(%[[VAL_47]]) : (f32) -> f32
// CHECK: %[[VAL_60:.*]]:3 = "handshake.fork"(%[[VAL_59]]) {control = false} : (f32) -> (f32, f32, f32)
// CHECK: %[[VAL_61:.*]] = "handshake.merge"(%[[VAL_41]]) : (index) -> index
// CHECK: %[[VAL_62:.*]]:2 = "handshake.control_merge"(%[[VAL_49]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_63:.*]]:4 = "handshake.fork"(%[[VAL_62]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_64:.*]]:2 = "handshake.fork"(%[[VAL_63]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_65:.*]] = "handshake.join"(%[[VAL_64]]#1, %[[VAL_8]]#1, %[[VAL_7]]#1, %[[VAL_2]]#3) {control = true} : (none, none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_62]]#1) : (index) -> ()
// CHECK: %[[VAL_66:.*]] = arith.addi %[[VAL_54]]#1, %[[VAL_56]]#1 : index
// CHECK: %[[VAL_67:.*]] = "handshake.constant"(%[[VAL_64]]#0) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_68:.*]] = arith.addi %[[VAL_66]], %[[VAL_67]] : index
// CHECK: %[[VAL_69:.*]]:3 = "handshake.fork"(%[[VAL_68]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_70:.*]], %[[VAL_5]] = "handshake.load"(%[[VAL_69]]#2, %[[VAL_2]]#1, %[[VAL_63]]#2) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_71:.*]] = arith.addi %[[VAL_54]]#0, %[[VAL_58]]#1 : index
// CHECK: %[[VAL_72:.*]], %[[VAL_6]] = "handshake.load"(%[[VAL_69]]#1, %[[VAL_2]]#2, %[[VAL_63]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_73:.*]] = arith.addf %[[VAL_70]], %[[VAL_72]] : f32
// CHECK: %[[VAL_74:.*]] = arith.addf %[[VAL_60]]#1, %[[VAL_60]]#2 : f32
// CHECK: "handshake.sink"(%[[VAL_74]]) : (f32) -> ()
// CHECK: %[[VAL_75:.*]] = "handshake.join"(%[[VAL_63]]#0, %[[VAL_8]]#0, %[[VAL_7]]#0) {control = true} : (none, none, none) -> none
// CHECK: %[[VAL_3]]:2 = "handshake.store"(%[[VAL_73]], %[[VAL_69]]#0, %[[VAL_75]]) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_56]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_31]] = "handshake.branch"(%[[VAL_58]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_33]] = "handshake.branch"(%[[VAL_60]]#0) {control = false} : (f32) -> f32
// CHECK: %[[VAL_26]] = "handshake.branch"(%[[VAL_61]]) {control = false} : (index) -> index
// CHECK: %[[VAL_35]] = "handshake.branch"(%[[VAL_65]]) {control = true} : (none) -> none
// CHECK: %[[VAL_37]] = "handshake.branch"(%[[VAL_71]]) {control = false} : (index) -> index
// CHECK: %[[VAL_76:.*]]:2 = "handshake.control_merge"(%[[VAL_50]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_76]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_76]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:7 = memory[ld = 3, st = 1] (%[[VAL_3:.*]], %[[VAL_4:.*]], %[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_7:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index, index, index) -> (f32, f32, f32, none, none, none, none)
// CHECK: %[[VAL_8:.*]]:2 = fork [2] %[[VAL_2]]#6 : none
// CHECK: %[[VAL_9:.*]]:2 = fork [2] %[[VAL_2]]#5 : none
// CHECK: %[[VAL_10:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_1]] : none
// CHECK: %[[VAL_12:.*]]:4 = fork [4] %[[VAL_11]]#1 : none
// CHECK: %[[VAL_13:.*]] = join %[[VAL_12]]#3, %[[VAL_2]]#4 : none
// CHECK: %[[VAL_14:.*]] = constant %[[VAL_12]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_15:.*]]:2 = fork [2] %[[VAL_14]] : index
// CHECK: %[[VAL_16:.*]] = constant %[[VAL_12]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_17:.*]], %[[VAL_5]] = load {{\[}}%[[VAL_15]]#0] %[[VAL_2]]#0, %[[VAL_11]]#0 : index, f32
// CHECK: %[[VAL_18:.*]] = constant %[[VAL_12]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_20:.*]] = br %[[VAL_13]] : none
// CHECK: %[[VAL_21:.*]] = br %[[VAL_15]]#1 : index
// CHECK: %[[VAL_22:.*]] = br %[[VAL_16]] : index
// CHECK: %[[VAL_23:.*]] = br %[[VAL_17]] : f32
// CHECK: %[[VAL_24:.*]] = br %[[VAL_18]] : index
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_26:.*]]#4 {{\[}}%[[VAL_27:.*]], %[[VAL_22]]] : index, index
// CHECK: %[[VAL_28:.*]]:2 = fork [2] %[[VAL_25]] : index
// CHECK: %[[VAL_29:.*]] = mux %[[VAL_26]]#3 {{\[}}%[[VAL_30:.*]], %[[VAL_19]]] : index, index
// CHECK: %[[VAL_31:.*]] = mux %[[VAL_26]]#2 {{\[}}%[[VAL_32:.*]], %[[VAL_24]]] : index, index
// CHECK: %[[VAL_33:.*]] = mux %[[VAL_26]]#1 {{\[}}%[[VAL_34:.*]], %[[VAL_23]]] : index, f32
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = control_merge %[[VAL_37:.*]], %[[VAL_20]] : none
// CHECK: %[[VAL_26]]:5 = fork [5] %[[VAL_36]] : index
// CHECK: %[[VAL_38:.*]] = mux %[[VAL_26]]#0 {{\[}}%[[VAL_39:.*]], %[[VAL_21]]] : index, index
// CHECK: %[[VAL_40:.*]]:2 = fork [2] %[[VAL_38]] : index
// CHECK: %[[VAL_41:.*]] = arith.cmpi slt, %[[VAL_40]]#1, %[[VAL_28]]#1 : index
// CHECK: %[[VAL_42:.*]]:6 = fork [6] %[[VAL_41]] : i1
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = cond_br %[[VAL_42]]#5, %[[VAL_28]]#0 : index
// CHECK: sink %[[VAL_44]] : index
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = cond_br %[[VAL_42]]#4, %[[VAL_29]] : index
// CHECK: sink %[[VAL_46]] : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = cond_br %[[VAL_42]]#3, %[[VAL_31]] : index
// CHECK: sink %[[VAL_48]] : index
// CHECK: %[[VAL_49:.*]], %[[VAL_50:.*]] = cond_br %[[VAL_42]]#2, %[[VAL_33]] : f32
// CHECK: sink %[[VAL_50]] : f32
// CHECK: %[[VAL_51:.*]], %[[VAL_52:.*]] = cond_br %[[VAL_42]]#1, %[[VAL_35]] : none
// CHECK: %[[VAL_53:.*]], %[[VAL_54:.*]] = cond_br %[[VAL_42]]#0, %[[VAL_40]]#0 : index
// CHECK: sink %[[VAL_54]] : index
// CHECK: %[[VAL_55:.*]] = merge %[[VAL_53]] : index
// CHECK: %[[VAL_56:.*]]:2 = fork [2] %[[VAL_55]] : index
// CHECK: %[[VAL_57:.*]] = merge %[[VAL_45]] : index
// CHECK: %[[VAL_58:.*]]:2 = fork [2] %[[VAL_57]] : index
// CHECK: %[[VAL_59:.*]] = merge %[[VAL_47]] : index
// CHECK: %[[VAL_60:.*]]:2 = fork [2] %[[VAL_59]] : index
// CHECK: %[[VAL_61:.*]] = merge %[[VAL_49]] : f32
// CHECK: %[[VAL_62:.*]]:3 = fork [3] %[[VAL_61]] : f32
// CHECK: %[[VAL_63:.*]] = merge %[[VAL_43]] : index
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = control_merge %[[VAL_51]] : none
// CHECK: %[[VAL_66:.*]]:4 = fork [4] %[[VAL_64]] : none
// CHECK: %[[VAL_67:.*]]:2 = fork [2] %[[VAL_66]]#3 : none
// CHECK: %[[VAL_68:.*]] = join %[[VAL_67]]#1, %[[VAL_9]]#1, %[[VAL_8]]#1, %[[VAL_2]]#3 : none
// CHECK: sink %[[VAL_65]] : index
// CHECK: %[[VAL_69:.*]] = arith.addi %[[VAL_56]]#1, %[[VAL_58]]#1 : index
// CHECK: %[[VAL_70:.*]] = constant %[[VAL_67]]#0 {value = 7 : index} : index
// CHECK: %[[VAL_71:.*]] = arith.addi %[[VAL_69]], %[[VAL_70]] : index
// CHECK: %[[VAL_72:.*]]:3 = fork [3] %[[VAL_71]] : index
// CHECK: %[[VAL_73:.*]], %[[VAL_6]] = load {{\[}}%[[VAL_72]]#2] %[[VAL_2]]#1, %[[VAL_66]]#2 : index, f32
// CHECK: %[[VAL_74:.*]] = arith.addi %[[VAL_56]]#0, %[[VAL_60]]#1 : index
// CHECK: %[[VAL_75:.*]], %[[VAL_7]] = load {{\[}}%[[VAL_72]]#1] %[[VAL_2]]#2, %[[VAL_66]]#1 : index, f32
// CHECK: %[[VAL_76:.*]] = arith.addf %[[VAL_73]], %[[VAL_75]] : f32
// CHECK: %[[VAL_77:.*]] = arith.addf %[[VAL_62]]#1, %[[VAL_62]]#2 : f32
// CHECK: sink %[[VAL_77]] : f32
// CHECK: %[[VAL_78:.*]] = join %[[VAL_66]]#0, %[[VAL_9]]#0, %[[VAL_8]]#0 : none
// CHECK: %[[VAL_3]], %[[VAL_4]] = store {{\[}}%[[VAL_72]]#0] %[[VAL_76]], %[[VAL_78]] : index, f32
// CHECK: %[[VAL_30]] = br %[[VAL_58]]#0 : index
// CHECK: %[[VAL_32]] = br %[[VAL_60]]#0 : index
// CHECK: %[[VAL_34]] = br %[[VAL_62]]#0 : f32
// CHECK: %[[VAL_27]] = br %[[VAL_63]] : index
// CHECK: %[[VAL_37]] = br %[[VAL_68]] : none
// CHECK: %[[VAL_39]] = br %[[VAL_74]] : index
// CHECK: %[[VAL_79:.*]], %[[VAL_80:.*]] = control_merge %[[VAL_52]] : none
// CHECK: sink %[[VAL_80]] : index
// CHECK: return %[[VAL_79]] : none
// CHECK: }
// CHECK: }
func @affine_load(%arg0: index) {
%0 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%c10 = arith.constant 10 : index

View File

@ -1,88 +1,85 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_load(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_load(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:3 = "handshake.memory"(%[[VAL_3:.*]]#0, %[[VAL_3]]#1, %[[VAL_4:.*]]) {id = 1 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_2]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_6:.*]]:4 = "handshake.memory"(%[[VAL_7:.*]], %[[VAL_8:.*]]) {id = 0 : i32, ld_count = 2 : i32, lsq = false, st_count = 0 : i32, type = memref<10xf32>} : (index, index) -> (f32, f32, none, none)
// CHECK: %[[VAL_9:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_10:.*]]:2 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_11:.*]]:4 = "handshake.fork"(%[[VAL_10]]#1) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_12:.*]] = "handshake.join"(%[[VAL_11]]#3, %[[VAL_6]]#2) {control = true} : (none, none) -> none
// CHECK: %[[VAL_13:.*]] = "handshake.constant"(%[[VAL_11]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_14:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_15:.*]] = "handshake.constant"(%[[VAL_11]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_16:.*]], %[[VAL_7]] = "handshake.load"(%[[VAL_14]]#0, %[[VAL_6]]#0, %[[VAL_10]]#0) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_17:.*]] = "handshake.constant"(%[[VAL_11]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_19:.*]] = "handshake.branch"(%[[VAL_12]]) {control = true} : (none) -> none
// CHECK: %[[VAL_20:.*]] = "handshake.branch"(%[[VAL_14]]#1) {control = false} : (index) -> index
// CHECK: %[[VAL_21:.*]] = "handshake.branch"(%[[VAL_15]]) {control = false} : (index) -> index
// CHECK: %[[VAL_22:.*]] = "handshake.branch"(%[[VAL_16]]) {control = false} : (f32) -> f32
// CHECK: %[[VAL_23:.*]] = "handshake.branch"(%[[VAL_17]]) {control = false} : (index) -> index
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_25:.*]]#4, %[[VAL_26:.*]], %[[VAL_21]]) : (index, index, index) -> index
// CHECK: %[[VAL_27:.*]]:2 = "handshake.fork"(%[[VAL_24]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_28:.*]] = "handshake.mux"(%[[VAL_25]]#3, %[[VAL_29:.*]], %[[VAL_18]]) : (index, index, index) -> index
// CHECK: %[[VAL_30:.*]] = "handshake.mux"(%[[VAL_25]]#2, %[[VAL_31:.*]], %[[VAL_23]]) : (index, index, index) -> index
// CHECK: %[[VAL_32:.*]] = "handshake.mux"(%[[VAL_25]]#1, %[[VAL_33:.*]], %[[VAL_22]]) : (index, f32, f32) -> f32
// CHECK: %[[VAL_34:.*]]:2 = "handshake.control_merge"(%[[VAL_35:.*]], %[[VAL_19]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_25]]:5 = "handshake.fork"(%[[VAL_34]]#1) {control = false} : (index) -> (index, index, index, index, index)
// CHECK: %[[VAL_36:.*]] = "handshake.mux"(%[[VAL_25]]#0, %[[VAL_37:.*]], %[[VAL_20]]) : (index, index, index) -> index
// CHECK: %[[VAL_38:.*]]:2 = "handshake.fork"(%[[VAL_36]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_39:.*]] = arith.cmpi slt, %[[VAL_38]]#1, %[[VAL_27]]#1 : index
// CHECK: %[[VAL_40:.*]]:6 = "handshake.fork"(%[[VAL_39]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#5, %[[VAL_27]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_42]]) : (index) -> ()
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#4, %[[VAL_28]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_44]]) : (index) -> ()
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#3, %[[VAL_30]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_46]]) : (index) -> ()
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#2, %[[VAL_32]]) {control = false} : (i1, f32) -> (f32, f32)
// CHECK: "handshake.sink"(%[[VAL_48]]) : (f32) -> ()
// CHECK: %[[VAL_49:.*]], %[[VAL_50:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#1, %[[VAL_34]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_51:.*]], %[[VAL_52:.*]] = "handshake.conditional_branch"(%[[VAL_40]]#0, %[[VAL_38]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_52]]) : (index) -> ()
// CHECK: %[[VAL_53:.*]] = "handshake.merge"(%[[VAL_51]]) : (index) -> index
// CHECK: %[[VAL_54:.*]]:2 = "handshake.fork"(%[[VAL_53]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_55:.*]] = "handshake.merge"(%[[VAL_43]]) : (index) -> index
// CHECK: %[[VAL_56:.*]]:2 = "handshake.fork"(%[[VAL_55]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_57:.*]] = "handshake.merge"(%[[VAL_45]]) : (index) -> index
// CHECK: %[[VAL_58:.*]]:2 = "handshake.fork"(%[[VAL_57]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_59:.*]] = "handshake.merge"(%[[VAL_47]]) : (f32) -> f32
// CHECK: %[[VAL_60:.*]]:3 = "handshake.fork"(%[[VAL_59]]) {control = false} : (f32) -> (f32, f32, f32)
// CHECK: %[[VAL_61:.*]] = "handshake.merge"(%[[VAL_41]]) : (index) -> index
// CHECK: %[[VAL_62:.*]]:2 = "handshake.control_merge"(%[[VAL_49]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_63:.*]]:4 = "handshake.fork"(%[[VAL_62]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_64:.*]]:2 = "handshake.fork"(%[[VAL_63]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_65:.*]] = "handshake.join"(%[[VAL_64]]#1, %[[VAL_6]]#3, %[[VAL_5]]#1, %[[VAL_2]]#1) {control = true} : (none, none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_62]]#1) : (index) -> ()
// CHECK: %[[VAL_66:.*]] = arith.addi %[[VAL_54]]#1, %[[VAL_56]]#1 : index
// CHECK: %[[VAL_67:.*]] = "handshake.constant"(%[[VAL_64]]#0) {value = 7 : index} : (none) -> index
// CHECK: %[[VAL_68:.*]] = arith.addi %[[VAL_66]], %[[VAL_67]] : index
// CHECK: %[[VAL_69:.*]]:3 = "handshake.fork"(%[[VAL_68]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_70:.*]], %[[VAL_8]] = "handshake.load"(%[[VAL_69]]#2, %[[VAL_6]]#1, %[[VAL_63]]#2) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_71:.*]] = arith.addi %[[VAL_54]]#0, %[[VAL_58]]#1 : index
// CHECK: %[[VAL_72:.*]], %[[VAL_4]] = "handshake.load"(%[[VAL_69]]#1, %[[VAL_2]]#0, %[[VAL_63]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_73:.*]] = arith.addf %[[VAL_70]], %[[VAL_72]] : f32
// CHECK: %[[VAL_74:.*]] = arith.addf %[[VAL_60]]#1, %[[VAL_60]]#2 : f32
// CHECK: "handshake.sink"(%[[VAL_74]]) : (f32) -> ()
// CHECK: %[[VAL_75:.*]] = "handshake.join"(%[[VAL_63]]#0, %[[VAL_5]]#0) {control = true} : (none, none) -> none
// CHECK: %[[VAL_3]]:2 = "handshake.store"(%[[VAL_73]], %[[VAL_69]]#0, %[[VAL_75]]) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_56]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_31]] = "handshake.branch"(%[[VAL_58]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_33]] = "handshake.branch"(%[[VAL_60]]#0) {control = false} : (f32) -> f32
// CHECK: %[[VAL_26]] = "handshake.branch"(%[[VAL_61]]) {control = false} : (index) -> index
// CHECK: %[[VAL_35]] = "handshake.branch"(%[[VAL_65]]) {control = true} : (none) -> none
// CHECK: %[[VAL_37]] = "handshake.branch"(%[[VAL_71]]) {control = false} : (index) -> index
// CHECK: %[[VAL_76:.*]]:2 = "handshake.control_merge"(%[[VAL_50]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_76]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_76]]#0 : none
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_3:.*]], %[[VAL_4:.*]], %[[VAL_5:.*]]) {id = 1 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_2]]#2 : none
// CHECK: %[[VAL_7:.*]]:4 = memory[ld = 2, st = 0] (%[[VAL_8:.*]], %[[VAL_9:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (index, index) -> (f32, f32, none, none)
// CHECK: %[[VAL_10:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_1]] : none
// CHECK: %[[VAL_12:.*]]:4 = fork [4] %[[VAL_11]]#1 : none
// CHECK: %[[VAL_13:.*]] = join %[[VAL_12]]#3, %[[VAL_7]]#2 : none
// CHECK: %[[VAL_14:.*]] = constant %[[VAL_12]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_15:.*]]:2 = fork [2] %[[VAL_14]] : index
// CHECK: %[[VAL_16:.*]] = constant %[[VAL_12]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_17:.*]], %[[VAL_8]] = load {{\[}}%[[VAL_15]]#0] %[[VAL_7]]#0, %[[VAL_11]]#0 : index, f32
// CHECK: %[[VAL_18:.*]] = constant %[[VAL_12]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_20:.*]] = br %[[VAL_13]] : none
// CHECK: %[[VAL_21:.*]] = br %[[VAL_15]]#1 : index
// CHECK: %[[VAL_22:.*]] = br %[[VAL_16]] : index
// CHECK: %[[VAL_23:.*]] = br %[[VAL_17]] : f32
// CHECK: %[[VAL_24:.*]] = br %[[VAL_18]] : index
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_26:.*]]#4 {{\[}}%[[VAL_27:.*]], %[[VAL_22]]] : index, index
// CHECK: %[[VAL_28:.*]]:2 = fork [2] %[[VAL_25]] : index
// CHECK: %[[VAL_29:.*]] = mux %[[VAL_26]]#3 {{\[}}%[[VAL_30:.*]], %[[VAL_19]]] : index, index
// CHECK: %[[VAL_31:.*]] = mux %[[VAL_26]]#2 {{\[}}%[[VAL_32:.*]], %[[VAL_24]]] : index, index
// CHECK: %[[VAL_33:.*]] = mux %[[VAL_26]]#1 {{\[}}%[[VAL_34:.*]], %[[VAL_23]]] : index, f32
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = control_merge %[[VAL_37:.*]], %[[VAL_20]] : none
// CHECK: %[[VAL_26]]:5 = fork [5] %[[VAL_36]] : index
// CHECK: %[[VAL_38:.*]] = mux %[[VAL_26]]#0 {{\[}}%[[VAL_39:.*]], %[[VAL_21]]] : index, index
// CHECK: %[[VAL_40:.*]]:2 = fork [2] %[[VAL_38]] : index
// CHECK: %[[VAL_41:.*]] = arith.cmpi slt, %[[VAL_40]]#1, %[[VAL_28]]#1 : index
// CHECK: %[[VAL_42:.*]]:6 = fork [6] %[[VAL_41]] : i1
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = cond_br %[[VAL_42]]#5, %[[VAL_28]]#0 : index
// CHECK: sink %[[VAL_44]] : index
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = cond_br %[[VAL_42]]#4, %[[VAL_29]] : index
// CHECK: sink %[[VAL_46]] : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = cond_br %[[VAL_42]]#3, %[[VAL_31]] : index
// CHECK: sink %[[VAL_48]] : index
// CHECK: %[[VAL_49:.*]], %[[VAL_50:.*]] = cond_br %[[VAL_42]]#2, %[[VAL_33]] : f32
// CHECK: sink %[[VAL_50]] : f32
// CHECK: %[[VAL_51:.*]], %[[VAL_52:.*]] = cond_br %[[VAL_42]]#1, %[[VAL_35]] : none
// CHECK: %[[VAL_53:.*]], %[[VAL_54:.*]] = cond_br %[[VAL_42]]#0, %[[VAL_40]]#0 : index
// CHECK: sink %[[VAL_54]] : index
// CHECK: %[[VAL_55:.*]] = merge %[[VAL_53]] : index
// CHECK: %[[VAL_56:.*]]:2 = fork [2] %[[VAL_55]] : index
// CHECK: %[[VAL_57:.*]] = merge %[[VAL_45]] : index
// CHECK: %[[VAL_58:.*]]:2 = fork [2] %[[VAL_57]] : index
// CHECK: %[[VAL_59:.*]] = merge %[[VAL_47]] : index
// CHECK: %[[VAL_60:.*]]:2 = fork [2] %[[VAL_59]] : index
// CHECK: %[[VAL_61:.*]] = merge %[[VAL_49]] : f32
// CHECK: %[[VAL_62:.*]]:3 = fork [3] %[[VAL_61]] : f32
// CHECK: %[[VAL_63:.*]] = merge %[[VAL_43]] : index
// CHECK: %[[VAL_64:.*]], %[[VAL_65:.*]] = control_merge %[[VAL_51]] : none
// CHECK: %[[VAL_66:.*]]:4 = fork [4] %[[VAL_64]] : none
// CHECK: %[[VAL_67:.*]]:2 = fork [2] %[[VAL_66]]#3 : none
// CHECK: %[[VAL_68:.*]] = join %[[VAL_67]]#1, %[[VAL_7]]#3, %[[VAL_6]]#1, %[[VAL_2]]#1 : none
// CHECK: sink %[[VAL_65]] : index
// CHECK: %[[VAL_69:.*]] = arith.addi %[[VAL_56]]#1, %[[VAL_58]]#1 : index
// CHECK: %[[VAL_70:.*]] = constant %[[VAL_67]]#0 {value = 7 : index} : index
// CHECK: %[[VAL_71:.*]] = arith.addi %[[VAL_69]], %[[VAL_70]] : index
// CHECK: %[[VAL_72:.*]]:3 = fork [3] %[[VAL_71]] : index
// CHECK: %[[VAL_73:.*]], %[[VAL_9]] = load {{\[}}%[[VAL_72]]#2] %[[VAL_7]]#1, %[[VAL_66]]#2 : index, f32
// CHECK: %[[VAL_74:.*]] = arith.addi %[[VAL_56]]#0, %[[VAL_60]]#1 : index
// CHECK: %[[VAL_75:.*]], %[[VAL_5]] = load {{\[}}%[[VAL_72]]#1] %[[VAL_2]]#0, %[[VAL_66]]#1 : index, f32
// CHECK: %[[VAL_76:.*]] = arith.addf %[[VAL_73]], %[[VAL_75]] : f32
// CHECK: %[[VAL_77:.*]] = arith.addf %[[VAL_62]]#1, %[[VAL_62]]#2 : f32
// CHECK: sink %[[VAL_77]] : f32
// CHECK: %[[VAL_78:.*]] = join %[[VAL_66]]#0, %[[VAL_6]]#0 : none
// CHECK: %[[VAL_3]], %[[VAL_4]] = store {{\[}}%[[VAL_72]]#0] %[[VAL_76]], %[[VAL_78]] : index, f32
// CHECK: %[[VAL_30]] = br %[[VAL_58]]#0 : index
// CHECK: %[[VAL_32]] = br %[[VAL_60]]#0 : index
// CHECK: %[[VAL_34]] = br %[[VAL_62]]#0 : f32
// CHECK: %[[VAL_27]] = br %[[VAL_63]] : index
// CHECK: %[[VAL_37]] = br %[[VAL_68]] : none
// CHECK: %[[VAL_39]] = br %[[VAL_74]] : index
// CHECK: %[[VAL_79:.*]], %[[VAL_80:.*]] = control_merge %[[VAL_52]] : none
// CHECK: sink %[[VAL_80]] : index
// CHECK: return %[[VAL_79]] : none
// CHECK: }
// CHECK: }
func @affine_load(%arg0: index) {
%0 = memref.alloc() : memref<10xf32>
%10 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index

View File

@ -1,65 +1,61 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @test() {
// CHECK: module {
// CHECK-LABEL: handshake.func @test(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:5 = "handshake.memory"(%[[VAL_2:.*]]#0, %[[VAL_2]]#1, %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, ld_count = 2 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index, index) -> (f32, f32, none, none, none)
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_1]]#4) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_6:.*]]:2 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_6]]#1) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_8:.*]] = "handshake.join"(%[[VAL_7]]#2, %[[VAL_1]]#3) {control = true} : (none, none) -> none
// CHECK: %[[VAL_9:.*]] = "handshake.constant"(%[[VAL_7]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.constant"(%[[VAL_7]]#0) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_11:.*]]:2 = "handshake.fork"(%[[VAL_10]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_12:.*]], %[[VAL_3]] = "handshake.load"(%[[VAL_11]]#0, %[[VAL_1]]#0, %[[VAL_6]]#0) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_13:.*]] = "handshake.branch"(%[[VAL_8]]) {control = true} : (none) -> none
// CHECK: %[[VAL_14:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_15:.*]] = "handshake.branch"(%[[VAL_11]]#1) {control = false} : (index) -> index
// CHECK: %[[VAL_16:.*]] = "handshake.branch"(%[[VAL_12]]) {control = false} : (f32) -> f32
// CHECK: %[[VAL_17:.*]] = "handshake.mux"(%[[VAL_18:.*]]#2, %[[VAL_19:.*]], %[[VAL_15]]) : (index, index, index) -> index
// CHECK: %[[VAL_20:.*]]:2 = "handshake.fork"(%[[VAL_17]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_21:.*]] = "handshake.mux"(%[[VAL_18]]#1, %[[VAL_22:.*]], %[[VAL_16]]) : (index, f32, f32) -> f32
// CHECK: %[[VAL_23:.*]]:2 = "handshake.control_merge"(%[[VAL_24:.*]], %[[VAL_13]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_18]]:3 = "handshake.fork"(%[[VAL_23]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_25:.*]] = "handshake.mux"(%[[VAL_18]]#0, %[[VAL_26:.*]], %[[VAL_14]]) : (index, index, index) -> index
// CHECK: %[[VAL_27:.*]]:2 = "handshake.fork"(%[[VAL_25]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_28:.*]] = arith.cmpi slt, %[[VAL_27]]#1, %[[VAL_20]]#1 : index
// CHECK: %[[VAL_29:.*]]:4 = "handshake.fork"(%[[VAL_28]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = "handshake.conditional_branch"(%[[VAL_29]]#3, %[[VAL_20]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_31]]) : (index) -> ()
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = "handshake.conditional_branch"(%[[VAL_29]]#2, %[[VAL_21]]) {control = false} : (i1, f32) -> (f32, f32)
// CHECK: "handshake.sink"(%[[VAL_33]]) : (f32) -> ()
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = "handshake.conditional_branch"(%[[VAL_29]]#1, %[[VAL_23]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = "handshake.conditional_branch"(%[[VAL_29]]#0, %[[VAL_27]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_37]]) : (index) -> ()
// CHECK: %[[VAL_38:.*]] = "handshake.merge"(%[[VAL_36]]) : (index) -> index
// CHECK: %[[VAL_39:.*]] = "handshake.merge"(%[[VAL_32]]) : (f32) -> f32
// CHECK: %[[VAL_40:.*]]:2 = "handshake.fork"(%[[VAL_39]]) {control = false} : (f32) -> (f32, f32)
// CHECK: %[[VAL_41:.*]] = "handshake.merge"(%[[VAL_30]]) : (index) -> index
// CHECK: %[[VAL_42:.*]]:2 = "handshake.control_merge"(%[[VAL_34]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_43:.*]]:3 = "handshake.fork"(%[[VAL_42]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_44:.*]]:2 = "handshake.fork"(%[[VAL_43]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_45:.*]] = "handshake.join"(%[[VAL_44]]#1, %[[VAL_5]]#1, %[[VAL_1]]#2) {control = true} : (none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_42]]#1) : (index) -> ()
// CHECK: %[[VAL_46:.*]] = "handshake.constant"(%[[VAL_44]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_47:.*]] = arith.addi %[[VAL_38]], %[[VAL_46]] : index
// CHECK: %[[VAL_48:.*]]:3 = "handshake.fork"(%[[VAL_47]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_49:.*]], %[[VAL_4]] = "handshake.load"(%[[VAL_48]]#2, %[[VAL_1]]#1, %[[VAL_43]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_50:.*]] = arith.addf %[[VAL_40]]#1, %[[VAL_49]] : f32
// CHECK: %[[VAL_51:.*]] = "handshake.join"(%[[VAL_43]]#0, %[[VAL_5]]#0) {control = true} : (none, none) -> none
// CHECK: %[[VAL_2]]:2 = "handshake.store"(%[[VAL_50]], %[[VAL_48]]#1, %[[VAL_51]]) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_22]] = "handshake.branch"(%[[VAL_40]]#0) {control = false} : (f32) -> f32
// CHECK: %[[VAL_19]] = "handshake.branch"(%[[VAL_41]]) {control = false} : (index) -> index
// CHECK: %[[VAL_24]] = "handshake.branch"(%[[VAL_45]]) {control = true} : (none) -> none
// CHECK: %[[VAL_26]] = "handshake.branch"(%[[VAL_48]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_52:.*]]:2 = "handshake.control_merge"(%[[VAL_35]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_52]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_52]]#0 : none
// CHECK: %[[VAL_1:.*]]:5 = memory[ld = 2, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]], %[[VAL_5:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index, index) -> (f32, f32, none, none, none)
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_1]]#4 : none
// CHECK: %[[VAL_7:.*]]:2 = fork [2] %[[VAL_0]] : none
// CHECK: %[[VAL_8:.*]]:3 = fork [3] %[[VAL_7]]#1 : none
// CHECK: %[[VAL_9:.*]] = join %[[VAL_8]]#2, %[[VAL_1]]#3 : none
// CHECK: %[[VAL_10:.*]] = constant %[[VAL_8]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_11:.*]] = constant %[[VAL_8]]#0 {value = 10 : index} : index
// CHECK: %[[VAL_12:.*]]:2 = fork [2] %[[VAL_11]] : index
// CHECK: %[[VAL_13:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_12]]#0] %[[VAL_1]]#0, %[[VAL_7]]#0 : index, f32
// CHECK: %[[VAL_14:.*]] = br %[[VAL_9]] : none
// CHECK: %[[VAL_15:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_16:.*]] = br %[[VAL_12]]#1 : index
// CHECK: %[[VAL_17:.*]] = br %[[VAL_13]] : f32
// CHECK: %[[VAL_18:.*]] = mux %[[VAL_19:.*]]#2 {{\[}}%[[VAL_20:.*]], %[[VAL_16]]] : index, index
// CHECK: %[[VAL_21:.*]]:2 = fork [2] %[[VAL_18]] : index
// CHECK: %[[VAL_22:.*]] = mux %[[VAL_19]]#1 {{\[}}%[[VAL_23:.*]], %[[VAL_17]]] : index, f32
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = control_merge %[[VAL_26:.*]], %[[VAL_14]] : none
// CHECK: %[[VAL_19]]:3 = fork [3] %[[VAL_25]] : index
// CHECK: %[[VAL_27:.*]] = mux %[[VAL_19]]#0 {{\[}}%[[VAL_28:.*]], %[[VAL_15]]] : index, index
// CHECK: %[[VAL_29:.*]]:2 = fork [2] %[[VAL_27]] : index
// CHECK: %[[VAL_30:.*]] = arith.cmpi slt, %[[VAL_29]]#1, %[[VAL_21]]#1 : index
// CHECK: %[[VAL_31:.*]]:4 = fork [4] %[[VAL_30]] : i1
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = cond_br %[[VAL_31]]#3, %[[VAL_21]]#0 : index
// CHECK: sink %[[VAL_33]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = cond_br %[[VAL_31]]#2, %[[VAL_22]] : f32
// CHECK: sink %[[VAL_35]] : f32
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = cond_br %[[VAL_31]]#1, %[[VAL_24]] : none
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = cond_br %[[VAL_31]]#0, %[[VAL_29]]#0 : index
// CHECK: sink %[[VAL_39]] : index
// CHECK: %[[VAL_40:.*]] = merge %[[VAL_38]] : index
// CHECK: %[[VAL_41:.*]] = merge %[[VAL_34]] : f32
// CHECK: %[[VAL_42:.*]]:2 = fork [2] %[[VAL_41]] : f32
// CHECK: %[[VAL_43:.*]] = merge %[[VAL_32]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = control_merge %[[VAL_36]] : none
// CHECK: %[[VAL_46:.*]]:3 = fork [3] %[[VAL_44]] : none
// CHECK: %[[VAL_47:.*]]:2 = fork [2] %[[VAL_46]]#2 : none
// CHECK: %[[VAL_48:.*]] = join %[[VAL_47]]#1, %[[VAL_6]]#1, %[[VAL_1]]#2 : none
// CHECK: sink %[[VAL_45]] : index
// CHECK: %[[VAL_49:.*]] = constant %[[VAL_47]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_40]], %[[VAL_49]] : index
// CHECK: %[[VAL_51:.*]]:3 = fork [3] %[[VAL_50]] : index
// CHECK: %[[VAL_52:.*]], %[[VAL_5]] = load {{\[}}%[[VAL_51]]#2] %[[VAL_1]]#1, %[[VAL_46]]#1 : index, f32
// CHECK: %[[VAL_53:.*]] = arith.addf %[[VAL_42]]#1, %[[VAL_52]] : f32
// CHECK: %[[VAL_54:.*]] = join %[[VAL_46]]#0, %[[VAL_6]]#0 : none
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_51]]#1] %[[VAL_53]], %[[VAL_54]] : index, f32
// CHECK: %[[VAL_23]] = br %[[VAL_42]]#0 : f32
// CHECK: %[[VAL_20]] = br %[[VAL_43]] : index
// CHECK: %[[VAL_26]] = br %[[VAL_48]] : none
// CHECK: %[[VAL_28]] = br %[[VAL_51]]#0 : index
// CHECK: %[[VAL_55:.*]], %[[VAL_56:.*]] = control_merge %[[VAL_37]] : none
// CHECK: sink %[[VAL_56]] : index
// CHECK: return %[[VAL_55]] : none
// CHECK: }
// CHECK: }
func @test() {
%10 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%c10 = arith.constant 10 : index

View File

@ -1,57 +1,53 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @test() {
// CHECK: module {
// CHECK-LABEL: handshake.func @test(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:5 = "handshake.memory"(%[[VAL_2:.*]]#0, %[[VAL_2]]#1, %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, ld_count = 2 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index, index) -> (f32, f32, none, none, none)
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_1]]#4) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_6:.*]]:2 = "handshake.fork"(%[[VAL_1]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_7]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.constant"(%[[VAL_7]]#0) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.branch"(%[[VAL_7]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_11:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.mux"(%[[VAL_14:.*]]#1, %[[VAL_15:.*]], %[[VAL_12]]) : (index, index, index) -> index
// CHECK: %[[VAL_16:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_17:.*]]:2 = "handshake.control_merge"(%[[VAL_18:.*]], %[[VAL_10]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_14]]:2 = "handshake.fork"(%[[VAL_17]]#1) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_19:.*]] = "handshake.mux"(%[[VAL_14]]#0, %[[VAL_20:.*]], %[[VAL_11]]) : (index, index, index) -> index
// CHECK: %[[VAL_21:.*]]:2 = "handshake.fork"(%[[VAL_19]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_21]]#1, %[[VAL_16]]#1 : index
// CHECK: %[[VAL_23:.*]]:3 = "handshake.fork"(%[[VAL_22]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_23]]#2, %[[VAL_16]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = "handshake.conditional_branch"(%[[VAL_23]]#1, %[[VAL_17]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = "handshake.conditional_branch"(%[[VAL_23]]#0, %[[VAL_21]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_29]]) : (index) -> ()
// CHECK: %[[VAL_30:.*]] = "handshake.merge"(%[[VAL_28]]) : (index) -> index
// CHECK: %[[VAL_31:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_32:.*]]:2 = "handshake.control_merge"(%[[VAL_26]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_33:.*]]:4 = "handshake.fork"(%[[VAL_32]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_34:.*]]:2 = "handshake.fork"(%[[VAL_33]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_35:.*]] = "handshake.join"(%[[VAL_34]]#1, %[[VAL_6]]#1, %[[VAL_5]]#1, %[[VAL_1]]#2) {control = true} : (none, none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_32]]#1) : (index) -> ()
// CHECK: %[[VAL_36:.*]] = "handshake.constant"(%[[VAL_34]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_37:.*]]:2 = "handshake.fork"(%[[VAL_36]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_38:.*]], %[[VAL_3]] = "handshake.load"(%[[VAL_37]]#1, %[[VAL_1]]#0, %[[VAL_33]]#2) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_39:.*]] = arith.addi %[[VAL_30]], %[[VAL_37]]#0 : index
// CHECK: %[[VAL_40:.*]]:3 = "handshake.fork"(%[[VAL_39]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_41:.*]], %[[VAL_4]] = "handshake.load"(%[[VAL_40]]#2, %[[VAL_1]]#1, %[[VAL_33]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_42:.*]] = arith.addf %[[VAL_38]], %[[VAL_41]] : f32
// CHECK: %[[VAL_43:.*]] = "handshake.join"(%[[VAL_33]]#0, %[[VAL_6]]#0, %[[VAL_5]]#0) {control = true} : (none, none, none) -> none
// CHECK: %[[VAL_2]]:2 = "handshake.store"(%[[VAL_42]], %[[VAL_40]]#1, %[[VAL_43]]) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_15]] = "handshake.branch"(%[[VAL_31]]) {control = false} : (index) -> index
// CHECK: %[[VAL_18]] = "handshake.branch"(%[[VAL_35]]) {control = true} : (none) -> none
// CHECK: %[[VAL_20]] = "handshake.branch"(%[[VAL_40]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_44:.*]]:2 = "handshake.control_merge"(%[[VAL_27]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_44]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_44]]#0 : none
// CHECK: %[[VAL_1:.*]]:5 = memory[ld = 2, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]], %[[VAL_5:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index, index) -> (f32, f32, none, none, none)
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_1]]#4 : none
// CHECK: %[[VAL_7:.*]]:2 = fork [2] %[[VAL_1]]#3 : none
// CHECK: %[[VAL_8:.*]]:3 = fork [3] %[[VAL_0]] : none
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_8]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_10:.*]] = constant %[[VAL_8]]#0 {value = 10 : index} : index
// CHECK: %[[VAL_11:.*]] = br %[[VAL_8]]#2 : none
// CHECK: %[[VAL_12:.*]] = br %[[VAL_9]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]] = mux %[[VAL_15:.*]]#1 {{\[}}%[[VAL_16:.*]], %[[VAL_13]]] : index, index
// CHECK: %[[VAL_17:.*]]:2 = fork [2] %[[VAL_14]] : index
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = control_merge %[[VAL_20:.*]], %[[VAL_11]] : none
// CHECK: %[[VAL_15]]:2 = fork [2] %[[VAL_19]] : index
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_15]]#0 {{\[}}%[[VAL_22:.*]], %[[VAL_12]]] : index, index
// CHECK: %[[VAL_23:.*]]:2 = fork [2] %[[VAL_21]] : index
// CHECK: %[[VAL_24:.*]] = arith.cmpi slt, %[[VAL_23]]#1, %[[VAL_17]]#1 : index
// CHECK: %[[VAL_25:.*]]:3 = fork [3] %[[VAL_24]] : i1
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_25]]#2, %[[VAL_17]]#0 : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = cond_br %[[VAL_25]]#1, %[[VAL_18]] : none
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = cond_br %[[VAL_25]]#0, %[[VAL_23]]#0 : index
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_28]] : none
// CHECK: %[[VAL_36:.*]]:4 = fork [4] %[[VAL_34]] : none
// CHECK: %[[VAL_37:.*]]:2 = fork [2] %[[VAL_36]]#3 : none
// CHECK: %[[VAL_38:.*]] = join %[[VAL_37]]#1, %[[VAL_7]]#1, %[[VAL_6]]#1, %[[VAL_1]]#2 : none
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_39:.*]] = constant %[[VAL_37]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_40:.*]]:2 = fork [2] %[[VAL_39]] : index
// CHECK: %[[VAL_41:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_40]]#1] %[[VAL_1]]#0, %[[VAL_36]]#2 : index, f32
// CHECK: %[[VAL_42:.*]] = arith.addi %[[VAL_32]], %[[VAL_40]]#0 : index
// CHECK: %[[VAL_43:.*]]:3 = fork [3] %[[VAL_42]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_5]] = load {{\[}}%[[VAL_43]]#2] %[[VAL_1]]#1, %[[VAL_36]]#1 : index, f32
// CHECK: %[[VAL_45:.*]] = arith.addf %[[VAL_41]], %[[VAL_44]] : f32
// CHECK: %[[VAL_46:.*]] = join %[[VAL_36]]#0, %[[VAL_7]]#0, %[[VAL_6]]#0 : none
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_43]]#1] %[[VAL_45]], %[[VAL_46]] : index, f32
// CHECK: %[[VAL_16]] = br %[[VAL_33]] : index
// CHECK: %[[VAL_20]] = br %[[VAL_38]] : none
// CHECK: %[[VAL_22]] = br %[[VAL_43]]#0 : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge %[[VAL_29]] : none
// CHECK: sink %[[VAL_48]] : index
// CHECK: return %[[VAL_47]] : none
// CHECK: }
// CHECK: }
func @test() {
%10 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%c10 = arith.constant 10 : index

View File

@ -1,60 +1,56 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @test() {
// CHECK: module {
// CHECK-LABEL: handshake.func @test(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:5 = "handshake.memory"(%[[VAL_2:.*]]#0, %[[VAL_2]]#1, %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 0 : i32, ld_count = 2 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index, index) -> (f32, f32, none, none, none)
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_1]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_6:.*]]:2 = "handshake.fork"(%[[VAL_1]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_7]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.constant"(%[[VAL_7]]#0) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.branch"(%[[VAL_7]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_11:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_9]]) {control = false} : (index) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.mux"(%[[VAL_14:.*]]#1, %[[VAL_15:.*]], %[[VAL_12]]) : (index, index, index) -> index
// CHECK: %[[VAL_16:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_17:.*]]:2 = "handshake.control_merge"(%[[VAL_18:.*]], %[[VAL_10]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_14]]:2 = "handshake.fork"(%[[VAL_17]]#1) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_19:.*]] = "handshake.mux"(%[[VAL_14]]#0, %[[VAL_20:.*]], %[[VAL_11]]) : (index, index, index) -> index
// CHECK: %[[VAL_21:.*]]:2 = "handshake.fork"(%[[VAL_19]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_21]]#1, %[[VAL_16]]#1 : index
// CHECK: %[[VAL_23:.*]]:3 = "handshake.fork"(%[[VAL_22]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = "handshake.conditional_branch"(%[[VAL_23]]#2, %[[VAL_16]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_25]]) : (index) -> ()
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = "handshake.conditional_branch"(%[[VAL_23]]#1, %[[VAL_17]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = "handshake.conditional_branch"(%[[VAL_23]]#0, %[[VAL_21]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_29]]) : (index) -> ()
// CHECK: %[[VAL_30:.*]] = "handshake.merge"(%[[VAL_28]]) : (index) -> index
// CHECK: %[[VAL_31:.*]] = "handshake.merge"(%[[VAL_24]]) : (index) -> index
// CHECK: %[[VAL_32:.*]]:2 = "handshake.control_merge"(%[[VAL_26]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_33:.*]]:4 = "handshake.fork"(%[[VAL_32]]#0) {control = true} : (none) -> (none, none, none, none)
// CHECK: %[[VAL_34:.*]]:2 = "handshake.fork"(%[[VAL_33]]#3) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_35:.*]] = "handshake.join"(%[[VAL_34]]#1, %[[VAL_5]]#1, %[[VAL_6]]#1, %[[VAL_1]]#4) {control = true} : (none, none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_32]]#1) : (index) -> ()
// CHECK: %[[VAL_36:.*]] = "handshake.constant"(%[[VAL_34]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_37:.*]]:2 = "handshake.fork"(%[[VAL_36]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_38:.*]] = arith.addi %[[VAL_30]], %[[VAL_37]]#0 : index
// CHECK: %[[VAL_39:.*]]:3 = "handshake.fork"(%[[VAL_38]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_40:.*]], %[[VAL_3]] = "handshake.load"(%[[VAL_39]]#2, %[[VAL_1]]#0, %[[VAL_33]]#2) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_41:.*]]:2 = "handshake.fork"(%[[VAL_40]]) {control = false} : (f32) -> (f32, f32)
// CHECK: %[[VAL_42:.*]] = arith.addf %[[VAL_41]]#0, %[[VAL_41]]#1 : f32
// CHECK: %[[VAL_43:.*]] = "handshake.join"(%[[VAL_33]]#1, %[[VAL_5]]#0) {control = true} : (none, none) -> none
// CHECK: %[[VAL_2]]:2 = "handshake.store"(%[[VAL_42]], %[[VAL_39]]#1, %[[VAL_43]]) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_44:.*]] = "handshake.join"(%[[VAL_33]]#0, %[[VAL_6]]#0) {control = true} : (none, none) -> none
// CHECK: %[[VAL_45:.*]], %[[VAL_4]] = "handshake.load"(%[[VAL_37]]#1, %[[VAL_1]]#1, %[[VAL_44]]) : (index, f32, none) -> (f32, index)
// CHECK: "handshake.sink"(%[[VAL_45]]) : (f32) -> ()
// CHECK: %[[VAL_15]] = "handshake.branch"(%[[VAL_31]]) {control = false} : (index) -> index
// CHECK: %[[VAL_18]] = "handshake.branch"(%[[VAL_35]]) {control = true} : (none) -> none
// CHECK: %[[VAL_20]] = "handshake.branch"(%[[VAL_39]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_46:.*]]:2 = "handshake.control_merge"(%[[VAL_27]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_46]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_46]]#0 : none
// CHECK: %[[VAL_1:.*]]:5 = memory[ld = 2, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]], %[[VAL_5:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index, index) -> (f32, f32, none, none, none)
// CHECK: %[[VAL_6:.*]]:2 = fork [2] %[[VAL_1]]#3 : none
// CHECK: %[[VAL_7:.*]]:2 = fork [2] %[[VAL_1]]#2 : none
// CHECK: %[[VAL_8:.*]]:3 = fork [3] %[[VAL_0]] : none
// CHECK: %[[VAL_9:.*]] = constant %[[VAL_8]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_10:.*]] = constant %[[VAL_8]]#0 {value = 10 : index} : index
// CHECK: %[[VAL_11:.*]] = br %[[VAL_8]]#2 : none
// CHECK: %[[VAL_12:.*]] = br %[[VAL_9]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_10]] : index
// CHECK: %[[VAL_14:.*]] = mux %[[VAL_15:.*]]#1 {{\[}}%[[VAL_16:.*]], %[[VAL_13]]] : index, index
// CHECK: %[[VAL_17:.*]]:2 = fork [2] %[[VAL_14]] : index
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = control_merge %[[VAL_20:.*]], %[[VAL_11]] : none
// CHECK: %[[VAL_15]]:2 = fork [2] %[[VAL_19]] : index
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_15]]#0 {{\[}}%[[VAL_22:.*]], %[[VAL_12]]] : index, index
// CHECK: %[[VAL_23:.*]]:2 = fork [2] %[[VAL_21]] : index
// CHECK: %[[VAL_24:.*]] = arith.cmpi slt, %[[VAL_23]]#1, %[[VAL_17]]#1 : index
// CHECK: %[[VAL_25:.*]]:3 = fork [3] %[[VAL_24]] : i1
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = cond_br %[[VAL_25]]#2, %[[VAL_17]]#0 : index
// CHECK: sink %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = cond_br %[[VAL_25]]#1, %[[VAL_18]] : none
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = cond_br %[[VAL_25]]#0, %[[VAL_23]]#0 : index
// CHECK: sink %[[VAL_31]] : index
// CHECK: %[[VAL_32:.*]] = merge %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]] = merge %[[VAL_26]] : index
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = control_merge %[[VAL_28]] : none
// CHECK: %[[VAL_36:.*]]:4 = fork [4] %[[VAL_34]] : none
// CHECK: %[[VAL_37:.*]]:2 = fork [2] %[[VAL_36]]#3 : none
// CHECK: %[[VAL_38:.*]] = join %[[VAL_37]]#1, %[[VAL_6]]#1, %[[VAL_7]]#1, %[[VAL_1]]#4 : none
// CHECK: sink %[[VAL_35]] : index
// CHECK: %[[VAL_39:.*]] = constant %[[VAL_37]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_40:.*]]:2 = fork [2] %[[VAL_39]] : index
// CHECK: %[[VAL_41:.*]] = arith.addi %[[VAL_32]], %[[VAL_40]]#0 : index
// CHECK: %[[VAL_42:.*]]:3 = fork [3] %[[VAL_41]] : index
// CHECK: %[[VAL_43:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_42]]#2] %[[VAL_1]]#0, %[[VAL_36]]#2 : index, f32
// CHECK: %[[VAL_44:.*]]:2 = fork [2] %[[VAL_43]] : f32
// CHECK: %[[VAL_45:.*]] = arith.addf %[[VAL_44]]#0, %[[VAL_44]]#1 : f32
// CHECK: %[[VAL_46:.*]] = join %[[VAL_36]]#1, %[[VAL_6]]#0 : none
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_42]]#1] %[[VAL_45]], %[[VAL_46]] : index, f32
// CHECK: %[[VAL_47:.*]] = join %[[VAL_36]]#0, %[[VAL_7]]#0 : none
// CHECK: %[[VAL_48:.*]], %[[VAL_5]] = load {{\[}}%[[VAL_40]]#1] %[[VAL_1]]#1, %[[VAL_47]] : index, f32
// CHECK: sink %[[VAL_48]] : f32
// CHECK: %[[VAL_16]] = br %[[VAL_33]] : index
// CHECK: %[[VAL_20]] = br %[[VAL_38]] : none
// CHECK: %[[VAL_22]] = br %[[VAL_42]]#0 : index
// CHECK: %[[VAL_49:.*]], %[[VAL_50:.*]] = control_merge %[[VAL_29]] : none
// CHECK: sink %[[VAL_50]] : index
// CHECK: return %[[VAL_49]] : none
// CHECK: }
// CHECK: }
func @test() {
%10 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%c10 = arith.constant 10 : index

View File

@ -1,66 +1,62 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @test() {
// CHECK: module {
// CHECK-LABEL: handshake.func @test(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:3 = "handshake.memory"(%[[VAL_2:.*]]#0, %[[VAL_2]]#1, %[[VAL_3:.*]]) {id = 1 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_4:.*]]:3 = "handshake.memory"(%[[VAL_5:.*]]#0, %[[VAL_5]]#1, %[[VAL_6:.*]]) {id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32, type = memref<10xf32>} : (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_8:.*]]:3 = "handshake.fork"(%[[VAL_7]]#2) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_9:.*]] = "handshake.join"(%[[VAL_8]]#2, %[[VAL_4]]#2, %[[VAL_1]]#1) {control = true} : (none, none, none) -> none
// CHECK: %[[VAL_10:.*]] = "handshake.constant"(%[[VAL_8]]#1) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_11:.*]] = "handshake.constant"(%[[VAL_8]]#0) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_12:.*]]:3 = "handshake.fork"(%[[VAL_11]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_13:.*]], %[[VAL_6]] = "handshake.load"(%[[VAL_12]]#0, %[[VAL_4]]#0, %[[VAL_7]]#1) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_14:.*]]:2 = "handshake.fork"(%[[VAL_13]]) {control = false} : (f32) -> (f32, f32)
// CHECK: %[[VAL_2]]:2 = "handshake.store"(%[[VAL_14]]#1, %[[VAL_12]]#1, %[[VAL_7]]#0) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_15:.*]] = "handshake.branch"(%[[VAL_9]]) {control = true} : (none) -> none
// CHECK: %[[VAL_16:.*]] = "handshake.branch"(%[[VAL_10]]) {control = false} : (index) -> index
// CHECK: %[[VAL_17:.*]] = "handshake.branch"(%[[VAL_12]]#2) {control = false} : (index) -> index
// CHECK: %[[VAL_18:.*]] = "handshake.branch"(%[[VAL_14]]#0) {control = false} : (f32) -> f32
// CHECK: %[[VAL_19:.*]] = "handshake.mux"(%[[VAL_20:.*]]#2, %[[VAL_21:.*]], %[[VAL_17]]) : (index, index, index) -> index
// CHECK: %[[VAL_22:.*]]:2 = "handshake.fork"(%[[VAL_19]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_23:.*]] = "handshake.mux"(%[[VAL_20]]#1, %[[VAL_24:.*]], %[[VAL_18]]) : (index, f32, f32) -> f32
// CHECK: %[[VAL_25:.*]]:2 = "handshake.control_merge"(%[[VAL_26:.*]], %[[VAL_15]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_20]]:3 = "handshake.fork"(%[[VAL_25]]#1) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_27:.*]] = "handshake.mux"(%[[VAL_20]]#0, %[[VAL_28:.*]], %[[VAL_16]]) : (index, index, index) -> index
// CHECK: %[[VAL_29:.*]]:2 = "handshake.fork"(%[[VAL_27]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_30:.*]] = arith.cmpi slt, %[[VAL_29]]#1, %[[VAL_22]]#1 : index
// CHECK: %[[VAL_31:.*]]:4 = "handshake.fork"(%[[VAL_30]]) {control = false} : (i1) -> (i1, i1, i1, i1)
// CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = "handshake.conditional_branch"(%[[VAL_31]]#3, %[[VAL_22]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_33]]) : (index) -> ()
// CHECK: %[[VAL_34:.*]], %[[VAL_35:.*]] = "handshake.conditional_branch"(%[[VAL_31]]#2, %[[VAL_23]]) {control = false} : (i1, f32) -> (f32, f32)
// CHECK: "handshake.sink"(%[[VAL_35]]) : (f32) -> ()
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = "handshake.conditional_branch"(%[[VAL_31]]#1, %[[VAL_25]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = "handshake.conditional_branch"(%[[VAL_31]]#0, %[[VAL_29]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_39]]) : (index) -> ()
// CHECK: %[[VAL_40:.*]] = "handshake.merge"(%[[VAL_38]]) : (index) -> index
// CHECK: %[[VAL_41:.*]] = "handshake.merge"(%[[VAL_34]]) : (f32) -> f32
// CHECK: %[[VAL_42:.*]]:2 = "handshake.fork"(%[[VAL_41]]) {control = false} : (f32) -> (f32, f32)
// CHECK: %[[VAL_43:.*]] = "handshake.merge"(%[[VAL_32]]) : (index) -> index
// CHECK: %[[VAL_44:.*]]:2 = "handshake.control_merge"(%[[VAL_36]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_45:.*]]:3 = "handshake.fork"(%[[VAL_44]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: %[[VAL_46:.*]]:2 = "handshake.fork"(%[[VAL_45]]#2) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_47:.*]] = "handshake.join"(%[[VAL_46]]#1, %[[VAL_4]]#1, %[[VAL_1]]#2) {control = true} : (none, none, none) -> none
// CHECK: "handshake.sink"(%[[VAL_44]]#1) : (index) -> ()
// CHECK: %[[VAL_48:.*]] = "handshake.constant"(%[[VAL_46]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_40]], %[[VAL_48]] : index
// CHECK: %[[VAL_50:.*]]:3 = "handshake.fork"(%[[VAL_49]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_51:.*]], %[[VAL_3]] = "handshake.load"(%[[VAL_50]]#2, %[[VAL_1]]#0, %[[VAL_45]]#0) : (index, f32, none) -> (f32, index)
// CHECK: %[[VAL_52:.*]] = arith.addf %[[VAL_42]]#1, %[[VAL_51]] : f32
// CHECK: %[[VAL_5]]:2 = "handshake.store"(%[[VAL_52]], %[[VAL_50]]#1, %[[VAL_45]]#1) : (f32, index, none) -> (f32, index)
// CHECK: %[[VAL_24]] = "handshake.branch"(%[[VAL_42]]#0) {control = false} : (f32) -> f32
// CHECK: %[[VAL_21]] = "handshake.branch"(%[[VAL_43]]) {control = false} : (index) -> index
// CHECK: %[[VAL_26]] = "handshake.branch"(%[[VAL_47]]) {control = true} : (none) -> none
// CHECK: %[[VAL_28]] = "handshake.branch"(%[[VAL_50]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_53:.*]]:2 = "handshake.control_merge"(%[[VAL_37]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_53]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_53]]#0 : none
// CHECK: %[[VAL_1:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_2:.*]], %[[VAL_3:.*]], %[[VAL_4:.*]]) {id = 1 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_5:.*]]:3 = memory[ld = 1, st = 1] (%[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]]) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
// CHECK: %[[VAL_9:.*]]:3 = fork [3] %[[VAL_0]] : none
// CHECK: %[[VAL_10:.*]]:3 = fork [3] %[[VAL_9]]#2 : none
// CHECK: %[[VAL_11:.*]] = join %[[VAL_10]]#2, %[[VAL_5]]#2, %[[VAL_1]]#1 : none
// CHECK: %[[VAL_12:.*]] = constant %[[VAL_10]]#1 {value = 0 : index} : index
// CHECK: %[[VAL_13:.*]] = constant %[[VAL_10]]#0 {value = 10 : index} : index
// CHECK: %[[VAL_14:.*]]:3 = fork [3] %[[VAL_13]] : index
// CHECK: %[[VAL_15:.*]], %[[VAL_8]] = load {{\[}}%[[VAL_14]]#0] %[[VAL_5]]#0, %[[VAL_9]]#1 : index, f32
// CHECK: %[[VAL_16:.*]]:2 = fork [2] %[[VAL_15]] : f32
// CHECK: %[[VAL_2]], %[[VAL_3]] = store {{\[}}%[[VAL_14]]#1] %[[VAL_16]]#1, %[[VAL_9]]#0 : index, f32
// CHECK: %[[VAL_17:.*]] = br %[[VAL_11]] : none
// CHECK: %[[VAL_18:.*]] = br %[[VAL_12]] : index
// CHECK: %[[VAL_19:.*]] = br %[[VAL_14]]#2 : index
// CHECK: %[[VAL_20:.*]] = br %[[VAL_16]]#0 : f32
// CHECK: %[[VAL_21:.*]] = mux %[[VAL_22:.*]]#2 {{\[}}%[[VAL_23:.*]], %[[VAL_19]]] : index, index
// CHECK: %[[VAL_24:.*]]:2 = fork [2] %[[VAL_21]] : index
// CHECK: %[[VAL_25:.*]] = mux %[[VAL_22]]#1 {{\[}}%[[VAL_26:.*]], %[[VAL_20]]] : index, f32
// CHECK: %[[VAL_27:.*]], %[[VAL_28:.*]] = control_merge %[[VAL_29:.*]], %[[VAL_17]] : none
// CHECK: %[[VAL_22]]:3 = fork [3] %[[VAL_28]] : index
// CHECK: %[[VAL_30:.*]] = mux %[[VAL_22]]#0 {{\[}}%[[VAL_31:.*]], %[[VAL_18]]] : index, index
// CHECK: %[[VAL_32:.*]]:2 = fork [2] %[[VAL_30]] : index
// CHECK: %[[VAL_33:.*]] = arith.cmpi slt, %[[VAL_32]]#1, %[[VAL_24]]#1 : index
// CHECK: %[[VAL_34:.*]]:4 = fork [4] %[[VAL_33]] : i1
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = cond_br %[[VAL_34]]#3, %[[VAL_24]]#0 : index
// CHECK: sink %[[VAL_36]] : index
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = cond_br %[[VAL_34]]#2, %[[VAL_25]] : f32
// CHECK: sink %[[VAL_38]] : f32
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = cond_br %[[VAL_34]]#1, %[[VAL_27]] : none
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = cond_br %[[VAL_34]]#0, %[[VAL_32]]#0 : index
// CHECK: sink %[[VAL_42]] : index
// CHECK: %[[VAL_43:.*]] = merge %[[VAL_41]] : index
// CHECK: %[[VAL_44:.*]] = merge %[[VAL_37]] : f32
// CHECK: %[[VAL_45:.*]]:2 = fork [2] %[[VAL_44]] : f32
// CHECK: %[[VAL_46:.*]] = merge %[[VAL_35]] : index
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge %[[VAL_39]] : none
// CHECK: %[[VAL_49:.*]]:3 = fork [3] %[[VAL_47]] : none
// CHECK: %[[VAL_50:.*]]:2 = fork [2] %[[VAL_49]]#2 : none
// CHECK: %[[VAL_51:.*]] = join %[[VAL_50]]#1, %[[VAL_5]]#1, %[[VAL_1]]#2 : none
// CHECK: sink %[[VAL_48]] : index
// CHECK: %[[VAL_52:.*]] = constant %[[VAL_50]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_43]], %[[VAL_52]] : index
// CHECK: %[[VAL_54:.*]]:3 = fork [3] %[[VAL_53]] : index
// CHECK: %[[VAL_55:.*]], %[[VAL_4]] = load {{\[}}%[[VAL_54]]#2] %[[VAL_1]]#0, %[[VAL_49]]#0 : index, f32
// CHECK: %[[VAL_56:.*]] = arith.addf %[[VAL_45]]#1, %[[VAL_55]] : f32
// CHECK: %[[VAL_6]], %[[VAL_7]] = store {{\[}}%[[VAL_54]]#1] %[[VAL_56]], %[[VAL_49]]#1 : index, f32
// CHECK: %[[VAL_26]] = br %[[VAL_45]]#0 : f32
// CHECK: %[[VAL_23]] = br %[[VAL_46]] : index
// CHECK: %[[VAL_29]] = br %[[VAL_51]] : none
// CHECK: %[[VAL_31]] = br %[[VAL_54]]#0 : index
// CHECK: %[[VAL_57:.*]], %[[VAL_58:.*]] = control_merge %[[VAL_40]] : none
// CHECK: sink %[[VAL_58]] : index
// CHECK: return %[[VAL_57]] : none
// CHECK: }
// CHECK: }
func @test() {
%10 = memref.alloc() : memref<10xf32>
%11 = memref.alloca() : memref<10xf32>
%c0 = arith.constant 0 : index

View File

@ -1,44 +1,40 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @ops(f32, f32, i32, i32) -> (f32, i32) {
// CHECK: module {
// CHECK-LABEL: handshake.func @ops(
// CHECK-SAME: %[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i32, %[[VAL_4:.*]]: none, ...) -> (f32, i32, none) attributes {argNames = ["in0", "in1", "in2", "in3", "inCtrl"], resNames = ["out0", "out1", "outCtrl"]} {
// CHECK: %[[VAL_5:.*]] = "handshake.merge"(%[[VAL_0]]) : (f32) -> f32
// CHECK: %[[VAL_6:.*]]:3 = "handshake.fork"(%[[VAL_5]]) {control = false} : (f32) -> (f32, f32, f32)
// CHECK: %[[VAL_7:.*]] = "handshake.merge"(%[[VAL_1]]) : (f32) -> f32
// CHECK: %[[VAL_8:.*]]:3 = "handshake.fork"(%[[VAL_7]]) {control = false} : (f32) -> (f32, f32, f32)
// CHECK: %[[VAL_9:.*]] = "handshake.merge"(%[[VAL_2]]) : (i32) -> i32
// CHECK: %[[VAL_10:.*]]:10 = "handshake.fork"(%[[VAL_9]]) {control = false} : (i32) -> (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)
// CHECK: %[[VAL_11:.*]] = "handshake.merge"(%[[VAL_3]]) : (i32) -> i32
// CHECK: %[[VAL_12:.*]]:9 = "handshake.fork"(%[[VAL_11]]) {control = false} : (i32) -> (i32, i32, i32, i32, i32, i32, i32, i32, i32)
// CHECK: handshake.func @ops(%[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i32, %[[VAL_4:.*]]: none, ...) -> (f32, i32, none) attributes {argNames = ["in0", "in1", "in2", "in3", "inCtrl"], resNames = ["out0", "out1", "outCtrl"]} {
// CHECK: %[[VAL_5:.*]] = merge %[[VAL_0]] : f32
// CHECK: %[[VAL_6:.*]]:3 = fork [3] %[[VAL_5]] : f32
// CHECK: %[[VAL_7:.*]] = merge %[[VAL_1]] : f32
// CHECK: %[[VAL_8:.*]]:3 = fork [3] %[[VAL_7]] : f32
// CHECK: %[[VAL_9:.*]] = merge %[[VAL_2]] : i32
// CHECK: %[[VAL_10:.*]]:10 = fork [10] %[[VAL_9]] : i32
// CHECK: %[[VAL_11:.*]] = merge %[[VAL_3]] : i32
// CHECK: %[[VAL_12:.*]]:9 = fork [9] %[[VAL_11]] : i32
// CHECK: %[[VAL_13:.*]] = arith.subf %[[VAL_6]]#2, %[[VAL_8]]#2 : f32
// CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_10]]#9, %[[VAL_12]]#8 : i32
// CHECK: %[[VAL_15:.*]] = arith.cmpi slt, %[[VAL_10]]#8, %[[VAL_14]] : i32
// CHECK: %[[VAL_16:.*]] = arith.divsi %[[VAL_10]]#7, %[[VAL_12]]#7 : i32
// CHECK: %[[VAL_17:.*]] = arith.divui %[[VAL_10]]#6, %[[VAL_12]]#6 : i32
// CHECK: "handshake.sink"(%[[VAL_17]]) : (i32) -> ()
// CHECK: sink %[[VAL_17]] : i32
// CHECK: %[[VAL_18:.*]] = arith.remsi %[[VAL_10]]#5, %[[VAL_12]]#5 : i32
// CHECK: "handshake.sink"(%[[VAL_18]]) : (i32) -> ()
// CHECK: sink %[[VAL_18]] : i32
// CHECK: %[[VAL_19:.*]] = arith.remui %[[VAL_10]]#4, %[[VAL_12]]#4 : i32
// CHECK: "handshake.sink"(%[[VAL_19]]) : (i32) -> ()
// CHECK: %[[VAL_20:.*]] = select %[[VAL_15]], %[[VAL_10]]#3, %[[VAL_12]]#3 : i32
// CHECK: "handshake.sink"(%[[VAL_20]]) : (i32) -> ()
// CHECK: sink %[[VAL_19]] : i32
// CHECK: %[[VAL_20:.*]] = std.select %[[VAL_15]], %[[VAL_10]]#3, %[[VAL_12]]#3 : i32
// CHECK: sink %[[VAL_20]] : i32
// CHECK: %[[VAL_21:.*]] = arith.divf %[[VAL_6]]#1, %[[VAL_8]]#1 : f32
// CHECK: "handshake.sink"(%[[VAL_21]]) : (f32) -> ()
// CHECK: sink %[[VAL_21]] : f32
// CHECK: %[[VAL_22:.*]] = arith.remf %[[VAL_6]]#0, %[[VAL_8]]#0 : f32
// CHECK: "handshake.sink"(%[[VAL_22]]) : (f32) -> ()
// CHECK: sink %[[VAL_22]] : f32
// CHECK: %[[VAL_23:.*]] = arith.andi %[[VAL_10]]#2, %[[VAL_12]]#2 : i32
// CHECK: "handshake.sink"(%[[VAL_23]]) : (i32) -> ()
// CHECK: sink %[[VAL_23]] : i32
// CHECK: %[[VAL_24:.*]] = arith.ori %[[VAL_10]]#1, %[[VAL_12]]#1 : i32
// CHECK: "handshake.sink"(%[[VAL_24]]) : (i32) -> ()
// CHECK: sink %[[VAL_24]] : i32
// CHECK: %[[VAL_25:.*]] = arith.xori %[[VAL_10]]#0, %[[VAL_12]]#0 : i32
// CHECK: "handshake.sink"(%[[VAL_25]]) : (i32) -> ()
// CHECK: handshake.return %[[VAL_13]], %[[VAL_16]], %[[VAL_4]] : f32, i32, none
// CHECK: sink %[[VAL_25]] : i32
// CHECK: return %[[VAL_13]], %[[VAL_16]], %[[VAL_4]] : f32, i32, none
// CHECK: }
// CHECK: }
func @ops(f32, f32, i32, i32) -> (f32, i32) {
^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32):
%0 = arith.subf %arg0, %arg1: f32
%1 = arith.subi %arg2, %arg3: i32

View File

@ -1,31 +1,27 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @dfs_block_order() -> (i32) {
// CHECK: module {
// CHECK-LABEL: handshake.func @dfs_block_order(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> (i32, none) attributes {argNames = ["inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:2 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_2:.*]] = "handshake.constant"(%[[VAL_1]]#0) {value = 42 : i32} : (none) -> i32
// CHECK: %[[VAL_3:.*]] = "handshake.branch"(%[[VAL_1]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_4:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (i32) -> i32
// CHECK: %[[VAL_5:.*]] = "handshake.merge"(%[[VAL_6:.*]]) : (i32) -> i32
// CHECK: %[[VAL_7:.*]] = "handshake.merge"(%[[VAL_8:.*]]) : (i32) -> i32
// CHECK: %[[VAL_9:.*]]:2 = "handshake.control_merge"(%[[VAL_10:.*]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_9]]#1) : (index) -> ()
// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_5]], %[[VAL_7]] : i32
// CHECK: %[[VAL_12:.*]] = "handshake.merge"(%[[VAL_4]]) : (i32) -> i32
// CHECK: %[[VAL_13:.*]]:2 = "handshake.control_merge"(%[[VAL_3]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_14:.*]]:2 = "handshake.fork"(%[[VAL_13]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_13]]#1) : (index) -> ()
// CHECK: %[[VAL_15:.*]] = "handshake.constant"(%[[VAL_14]]#0) {value = 55 : i32} : (none) -> i32
// CHECK: %[[VAL_6]] = "handshake.branch"(%[[VAL_12]]) {control = false} : (i32) -> i32
// CHECK: %[[VAL_10]] = "handshake.branch"(%[[VAL_14]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_8]] = "handshake.branch"(%[[VAL_15]]) {control = false} : (i32) -> i32
// CHECK: handshake.return %[[VAL_11]], %[[VAL_9]]#0 : i32, none
// CHECK: %[[VAL_1:.*]]:2 = fork [2] %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]]#0 {value = 42 : i32} : i32
// CHECK: %[[VAL_3:.*]] = br %[[VAL_1]]#1 : none
// CHECK: %[[VAL_4:.*]] = br %[[VAL_2]] : i32
// CHECK: %[[VAL_5:.*]] = merge %[[VAL_6:.*]] : i32
// CHECK: %[[VAL_7:.*]] = merge %[[VAL_8:.*]] : i32
// CHECK: %[[VAL_9:.*]], %[[VAL_10:.*]] = control_merge %[[VAL_11:.*]] : none
// CHECK: sink %[[VAL_10]] : index
// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_5]], %[[VAL_7]] : i32
// CHECK: %[[VAL_13:.*]] = merge %[[VAL_4]] : i32
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = control_merge %[[VAL_3]] : none
// CHECK: %[[VAL_16:.*]]:2 = fork [2] %[[VAL_14]] : none
// CHECK: sink %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]] = constant %[[VAL_16]]#0 {value = 55 : i32} : i32
// CHECK: %[[VAL_6]] = br %[[VAL_13]] : i32
// CHECK: %[[VAL_11]] = br %[[VAL_16]]#1 : none
// CHECK: %[[VAL_8]] = br %[[VAL_17]] : i32
// CHECK: return %[[VAL_12]], %[[VAL_9]] : i32, none
// CHECK: }
// CHECK: }
func @dfs_block_order() -> (i32) {
%0 = arith.constant 42 : i32
br ^bb2
^bb1:

View File

@ -1,46 +1,42 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @ops(f32, f32, i32, i32) -> (f32, i32) {
// CHECK: module {
// CHECK-LABEL: handshake.func @ops(
// CHECK-SAME: %[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i32, %[[VAL_4:.*]]: none, ...) -> (f32, i32, none) attributes {argNames = ["in0", "in1", "in2", "in3", "inCtrl"], resNames = ["out0", "out1", "outCtrl"]} {
// CHECK: %[[VAL_5:.*]] = "handshake.merge"(%[[VAL_0]]) : (f32) -> f32
// CHECK: %[[VAL_6:.*]] = "handshake.merge"(%[[VAL_1]]) : (f32) -> f32
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_6]]) {control = false} : (f32) -> (f32, f32, f32)
// CHECK: %[[VAL_8:.*]] = "handshake.merge"(%[[VAL_2]]) : (i32) -> i32
// CHECK: %[[VAL_9:.*]]:9 = "handshake.fork"(%[[VAL_8]]) {control = false} : (i32) -> (i32, i32, i32, i32, i32, i32, i32, i32, i32)
// CHECK: %[[VAL_10:.*]] = "handshake.merge"(%[[VAL_3]]) : (i32) -> i32
// CHECK: %[[VAL_11:.*]]:8 = "handshake.fork"(%[[VAL_10]]) {control = false} : (i32) -> (i32, i32, i32, i32, i32, i32, i32, i32)
// CHECK: handshake.func @ops(%[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i32, %[[VAL_4:.*]]: none, ...) -> (f32, i32, none) attributes {argNames = ["in0", "in1", "in2", "in3", "inCtrl"], resNames = ["out0", "out1", "outCtrl"]} {
// CHECK: %[[VAL_5:.*]] = merge %[[VAL_0]] : f32
// CHECK: %[[VAL_6:.*]] = merge %[[VAL_1]] : f32
// CHECK: %[[VAL_7:.*]]:3 = fork [3] %[[VAL_6]] : f32
// CHECK: %[[VAL_8:.*]] = merge %[[VAL_2]] : i32
// CHECK: %[[VAL_9:.*]]:9 = fork [9] %[[VAL_8]] : i32
// CHECK: %[[VAL_10:.*]] = merge %[[VAL_3]] : i32
// CHECK: %[[VAL_11:.*]]:8 = fork [8] %[[VAL_10]] : i32
// CHECK: %[[VAL_12:.*]] = arith.subf %[[VAL_5]], %[[VAL_7]]#2 : f32
// CHECK: %[[VAL_13:.*]]:3 = "handshake.fork"(%[[VAL_12]]) {control = false} : (f32) -> (f32, f32, f32)
// CHECK: %[[VAL_13:.*]]:3 = fork [3] %[[VAL_12]] : f32
// CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_9]]#8, %[[VAL_11]]#7 : i32
// CHECK: %[[VAL_15:.*]]:2 = "handshake.fork"(%[[VAL_14]]) {control = false} : (i32) -> (i32, i32)
// CHECK: %[[VAL_15:.*]]:2 = fork [2] %[[VAL_14]] : i32
// CHECK: %[[VAL_16:.*]] = arith.cmpi slt, %[[VAL_9]]#7, %[[VAL_15]]#1 : i32
// CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_9]]#6, %[[VAL_11]]#6 : i32
// CHECK: %[[VAL_18:.*]]:2 = "handshake.fork"(%[[VAL_17]]) {control = false} : (i32) -> (i32, i32)
// CHECK: %[[VAL_18:.*]]:2 = fork [2] %[[VAL_17]] : i32
// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_15]]#0, %[[VAL_18]]#1 : i32
// CHECK: "handshake.sink"(%[[VAL_19]]) : (i32) -> ()
// CHECK: sink %[[VAL_19]] : i32
// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_9]]#5, %[[VAL_11]]#5 : i32
// CHECK: "handshake.sink"(%[[VAL_20]]) : (i32) -> ()
// CHECK: sink %[[VAL_20]] : i32
// CHECK: %[[VAL_21:.*]] = arith.remui %[[VAL_9]]#4, %[[VAL_11]]#4 : i32
// CHECK: "handshake.sink"(%[[VAL_21]]) : (i32) -> ()
// CHECK: %[[VAL_22:.*]] = select %[[VAL_16]], %[[VAL_9]]#3, %[[VAL_11]]#3 : i32
// CHECK: "handshake.sink"(%[[VAL_22]]) : (i32) -> ()
// CHECK: sink %[[VAL_21]] : i32
// CHECK: %[[VAL_22:.*]] = std.select %[[VAL_16]], %[[VAL_9]]#3, %[[VAL_11]]#3 : i32
// CHECK: sink %[[VAL_22]] : i32
// CHECK: %[[VAL_23:.*]] = arith.divf %[[VAL_13]]#2, %[[VAL_7]]#1 : f32
// CHECK: "handshake.sink"(%[[VAL_23]]) : (f32) -> ()
// CHECK: sink %[[VAL_23]] : f32
// CHECK: %[[VAL_24:.*]] = arith.remf %[[VAL_13]]#1, %[[VAL_7]]#0 : f32
// CHECK: "handshake.sink"(%[[VAL_24]]) : (f32) -> ()
// CHECK: sink %[[VAL_24]] : f32
// CHECK: %[[VAL_25:.*]] = arith.andi %[[VAL_9]]#2, %[[VAL_11]]#2 : i32
// CHECK: "handshake.sink"(%[[VAL_25]]) : (i32) -> ()
// CHECK: sink %[[VAL_25]] : i32
// CHECK: %[[VAL_26:.*]] = arith.ori %[[VAL_9]]#1, %[[VAL_11]]#1 : i32
// CHECK: "handshake.sink"(%[[VAL_26]]) : (i32) -> ()
// CHECK: sink %[[VAL_26]] : i32
// CHECK: %[[VAL_27:.*]] = arith.xori %[[VAL_9]]#0, %[[VAL_11]]#0 : i32
// CHECK: "handshake.sink"(%[[VAL_27]]) : (i32) -> ()
// CHECK: handshake.return %[[VAL_13]]#0, %[[VAL_18]]#0, %[[VAL_4]] : f32, i32, none
// CHECK: sink %[[VAL_27]] : i32
// CHECK: return %[[VAL_13]]#0, %[[VAL_18]]#0, %[[VAL_4]] : f32, i32, none
// CHECK: }
// CHECK: }
func @ops(f32, f32, i32, i32) -> (f32, i32) {
^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32):
%0 = arith.subf %arg0, %arg1: f32
%1 = arith.subi %arg2, %arg3: i32

View File

@ -1,41 +1,37 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @simple_loop() {
// CHECK: module {
// CHECK-LABEL: handshake.func @simple_loop(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = "handshake.branch"(%[[VAL_0]]) {control = true} : (none) -> none
// CHECK: %[[VAL_2:.*]]:2 = "handshake.control_merge"(%[[VAL_1]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_2]]#1) : (index) -> ()
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.branch"(%[[VAL_3]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_7:.*]]:2 = "handshake.control_merge"(%[[VAL_8:.*]], %[[VAL_5]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_9:.*]]:2 = "handshake.fork"(%[[VAL_7]]#0) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_10:.*]] = "handshake.mux"(%[[VAL_7]]#1, %[[VAL_11:.*]], %[[VAL_6]]) : (index, index, index) -> index
// CHECK: %[[VAL_12:.*]]:2 = "handshake.fork"(%[[VAL_10]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_13:.*]] = "handshake.constant"(%[[VAL_9]]#0) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_14:.*]] = arith.cmpi slt, %[[VAL_12]]#1, %[[VAL_13]] : index
// CHECK: %[[VAL_15:.*]]:2 = "handshake.fork"(%[[VAL_14]]) {control = false} : (i1) -> (i1, i1)
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = "handshake.conditional_branch"(%[[VAL_15]]#1, %[[VAL_9]]#1) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = "handshake.conditional_branch"(%[[VAL_15]]#0, %[[VAL_12]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_19]]) : (index) -> ()
// CHECK: %[[VAL_20:.*]] = "handshake.merge"(%[[VAL_18]]) : (index) -> index
// CHECK: %[[VAL_21:.*]]:2 = "handshake.control_merge"(%[[VAL_16]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_22:.*]]:2 = "handshake.fork"(%[[VAL_21]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_21]]#1) : (index) -> ()
// CHECK: %[[VAL_23:.*]] = "handshake.constant"(%[[VAL_22]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_20]], %[[VAL_23]] : index
// CHECK: %[[VAL_8]] = "handshake.branch"(%[[VAL_22]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_24]]) {control = false} : (index) -> index
// CHECK: %[[VAL_25:.*]]:2 = "handshake.control_merge"(%[[VAL_17]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_25]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_25]]#0 : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:2 = fork [2] %[[VAL_2]] : none
// CHECK: sink %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_6:.*]] = br %[[VAL_4]]#1 : none
// CHECK: %[[VAL_7:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_8:.*]], %[[VAL_9:.*]] = control_merge %[[VAL_10:.*]], %[[VAL_6]] : none
// CHECK: %[[VAL_11:.*]]:2 = fork [2] %[[VAL_8]] : none
// CHECK: %[[VAL_12:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_13:.*]], %[[VAL_7]]] : index, index
// CHECK: %[[VAL_14:.*]]:2 = fork [2] %[[VAL_12]] : index
// CHECK: %[[VAL_15:.*]] = constant %[[VAL_11]]#0 {value = 42 : index} : index
// CHECK: %[[VAL_16:.*]] = arith.cmpi slt, %[[VAL_14]]#1, %[[VAL_15]] : index
// CHECK: %[[VAL_17:.*]]:2 = fork [2] %[[VAL_16]] : i1
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = cond_br %[[VAL_17]]#1, %[[VAL_11]]#1 : none
// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = cond_br %[[VAL_17]]#0, %[[VAL_14]]#0 : index
// CHECK: sink %[[VAL_21]] : index
// CHECK: %[[VAL_22:.*]] = merge %[[VAL_20]] : index
// CHECK: %[[VAL_23:.*]], %[[VAL_24:.*]] = control_merge %[[VAL_18]] : none
// CHECK: %[[VAL_25:.*]]:2 = fork [2] %[[VAL_23]] : none
// CHECK: sink %[[VAL_24]] : index
// CHECK: %[[VAL_26:.*]] = constant %[[VAL_25]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_22]], %[[VAL_26]] : index
// CHECK: %[[VAL_10]] = br %[[VAL_25]]#1 : none
// CHECK: %[[VAL_13]] = br %[[VAL_27]] : index
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = control_merge %[[VAL_19]] : none
// CHECK: sink %[[VAL_29]] : index
// CHECK: return %[[VAL_28]] : none
// CHECK: }
// CHECK: }
func @simple_loop() {
^bb0:
br ^bb1
^bb1: // pred: ^bb0

View File

@ -1,41 +1,37 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @simple_loop() {
// CHECK: module {
// CHECK-LABEL: handshake.func @simple_loop(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = "handshake.branch"(%[[VAL_0]]) {control = true} : (none) -> none
// CHECK: %[[VAL_2:.*]]:2 = "handshake.control_merge"(%[[VAL_1]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_2]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_2]]#1) : (index) -> ()
// CHECK: %[[VAL_4:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 42 : index} : (none) -> index
// CHECK: %[[VAL_5:.*]] = "handshake.branch"(%[[VAL_3]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_6:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (index) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.mux"(%[[VAL_8:.*]]#1, %[[VAL_9:.*]], %[[VAL_6]]) : (index, index, index) -> index
// CHECK: %[[VAL_10:.*]]:3 = "handshake.fork"(%[[VAL_7]]) {control = false} : (index) -> (index, index, index)
// CHECK: %[[VAL_8]]:2 = "handshake.control_merge"(%[[VAL_11:.*]], %[[VAL_5]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_12:.*]] = arith.cmpi slt, %[[VAL_10]]#1, %[[VAL_10]]#2 : index
// CHECK: %[[VAL_13:.*]]:2 = "handshake.fork"(%[[VAL_12]]) {control = false} : (i1) -> (i1, i1)
// CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = "handshake.conditional_branch"(%[[VAL_13]]#1, %[[VAL_10]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_15]]) : (index) -> ()
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = "handshake.conditional_branch"(%[[VAL_13]]#0, %[[VAL_8]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_18:.*]] = "handshake.merge"(%[[VAL_14]]) : (index) -> index
// CHECK: %[[VAL_19:.*]]:2 = "handshake.control_merge"(%[[VAL_16]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_20:.*]]:3 = "handshake.fork"(%[[VAL_19]]#0) {control = true} : (none) -> (none, none, none)
// CHECK: "handshake.sink"(%[[VAL_19]]#1) : (index) -> ()
// CHECK: %[[VAL_21:.*]] = "handshake.constant"(%[[VAL_20]]#1) {value = 52 : index} : (none) -> index
// CHECK: "handshake.sink"(%[[VAL_21]]) : (index) -> ()
// CHECK: %[[VAL_22:.*]] = "handshake.constant"(%[[VAL_20]]#0) {value = 62 : index} : (none) -> index
// CHECK: "handshake.sink"(%[[VAL_22]]) : (index) -> ()
// CHECK: %[[VAL_9]] = "handshake.branch"(%[[VAL_18]]) {control = false} : (index) -> index
// CHECK: %[[VAL_11]] = "handshake.branch"(%[[VAL_20]]#2) {control = true} : (none) -> none
// CHECK: %[[VAL_23:.*]]:2 = "handshake.control_merge"(%[[VAL_17]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_23]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_23]]#0 : none
// CHECK: %[[VAL_1:.*]] = br %[[VAL_0]] : none
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = control_merge %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:2 = fork [2] %[[VAL_2]] : none
// CHECK: sink %[[VAL_3]] : index
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_4]]#0 {value = 42 : index} : index
// CHECK: %[[VAL_6:.*]] = br %[[VAL_4]]#1 : none
// CHECK: %[[VAL_7:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_8:.*]] = mux %[[VAL_9:.*]] {{\[}}%[[VAL_10:.*]], %[[VAL_7]]] : index, index
// CHECK: %[[VAL_11:.*]]:3 = fork [3] %[[VAL_8]] : index
// CHECK: %[[VAL_12:.*]], %[[VAL_9]] = control_merge %[[VAL_13:.*]], %[[VAL_6]] : none
// CHECK: %[[VAL_14:.*]] = arith.cmpi slt, %[[VAL_11]]#1, %[[VAL_11]]#2 : index
// CHECK: %[[VAL_15:.*]]:2 = fork [2] %[[VAL_14]] : i1
// CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = cond_br %[[VAL_15]]#1, %[[VAL_11]]#0 : index
// CHECK: sink %[[VAL_17]] : index
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = cond_br %[[VAL_15]]#0, %[[VAL_12]] : none
// CHECK: %[[VAL_20:.*]] = merge %[[VAL_16]] : index
// CHECK: %[[VAL_21:.*]], %[[VAL_22:.*]] = control_merge %[[VAL_18]] : none
// CHECK: %[[VAL_23:.*]]:3 = fork [3] %[[VAL_21]] : none
// CHECK: sink %[[VAL_22]] : index
// CHECK: %[[VAL_24:.*]] = constant %[[VAL_23]]#1 {value = 52 : index} : index
// CHECK: sink %[[VAL_24]] : index
// CHECK: %[[VAL_25:.*]] = constant %[[VAL_23]]#0 {value = 62 : index} : index
// CHECK: sink %[[VAL_25]] : index
// CHECK: %[[VAL_10]] = br %[[VAL_20]] : index
// CHECK: %[[VAL_13]] = br %[[VAL_23]]#2 : none
// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = control_merge %[[VAL_19]] : none
// CHECK: sink %[[VAL_27]] : index
// CHECK: return %[[VAL_26]] : none
// CHECK: }
// CHECK: }
func @simple_loop() {
^bb0:
br ^bb1
^bb1: // pred: ^bb0

View File

@ -1,81 +1,78 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
// RUN: circt-opt -lower-std-to-handshake %s | FileCheck %s
func @affine_dma_wait(%arg0: index) {
// CHECK: module {
// CHECK-LABEL: handshake.func @affine_dma_wait(
// CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (index) -> index
// CHECK: %[[VAL_3:.*]]:5 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none, none, none, none)
// CHECK-SAME: %[[VAL_0:.*]]: index,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : index
// CHECK: %[[VAL_3:.*]]:5 = fork [5] %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]] = memref.alloc() : memref<1xi32>
// CHECK: %[[VAL_5:.*]] = "handshake.constant"(%[[VAL_3]]#3) {value = 64 : index} : (none) -> index
// CHECK: %[[VAL_6:.*]] = "handshake.constant"(%[[VAL_3]]#2) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_3]]#1) {value = 10 : index} : (none) -> index
// CHECK: %[[VAL_8:.*]] = "handshake.constant"(%[[VAL_3]]#0) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_9:.*]] = "handshake.branch"(%[[VAL_2]]) {control = false} : (index) -> index
// CHECK: %[[VAL_10:.*]] = "handshake.branch"(%[[VAL_3]]#4) {control = true} : (none) -> none
// CHECK: %[[VAL_11:.*]] = "handshake.branch"(%[[VAL_4]]) {control = false} : (memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_12:.*]] = "handshake.branch"(%[[VAL_5]]) {control = false} : (index) -> index
// CHECK: %[[VAL_13:.*]] = "handshake.branch"(%[[VAL_6]]) {control = false} : (index) -> index
// CHECK: %[[VAL_14:.*]] = "handshake.branch"(%[[VAL_7]]) {control = false} : (index) -> index
// CHECK: %[[VAL_15:.*]] = "handshake.branch"(%[[VAL_8]]) {control = false} : (index) -> index
// CHECK: %[[VAL_16:.*]] = "handshake.mux"(%[[VAL_17:.*]]#5, %[[VAL_18:.*]], %[[VAL_14]]) : (index, index, index) -> index
// CHECK: %[[VAL_19:.*]]:2 = "handshake.fork"(%[[VAL_16]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_20:.*]] = "handshake.mux"(%[[VAL_17]]#4, %[[VAL_21:.*]], %[[VAL_9]]) : (index, index, index) -> index
// CHECK: %[[VAL_22:.*]] = "handshake.mux"(%[[VAL_17]]#3, %[[VAL_23:.*]], %[[VAL_11]]) : (index, memref<1xi32>, memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_24:.*]] = "handshake.mux"(%[[VAL_17]]#2, %[[VAL_25:.*]], %[[VAL_12]]) : (index, index, index) -> index
// CHECK: %[[VAL_26:.*]] = "handshake.mux"(%[[VAL_17]]#1, %[[VAL_27:.*]], %[[VAL_15]]) : (index, index, index) -> index
// CHECK: %[[VAL_28:.*]]:2 = "handshake.control_merge"(%[[VAL_29:.*]], %[[VAL_10]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_17]]:6 = "handshake.fork"(%[[VAL_28]]#1) {control = false} : (index) -> (index, index, index, index, index, index)
// CHECK: %[[VAL_30:.*]] = "handshake.mux"(%[[VAL_17]]#0, %[[VAL_31:.*]], %[[VAL_13]]) : (index, index, index) -> index
// CHECK: %[[VAL_32:.*]]:2 = "handshake.fork"(%[[VAL_30]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_33:.*]] = arith.cmpi slt, %[[VAL_32]]#1, %[[VAL_19]]#1 : index
// CHECK: %[[VAL_34:.*]]:7 = "handshake.fork"(%[[VAL_33]]) {control = false} : (i1) -> (i1, i1, i1, i1, i1, i1, i1)
// CHECK: %[[VAL_35:.*]], %[[VAL_36:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#6, %[[VAL_19]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_36]]) : (index) -> ()
// CHECK: %[[VAL_37:.*]], %[[VAL_38:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#5, %[[VAL_20]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_38]]) : (index) -> ()
// CHECK: %[[VAL_39:.*]], %[[VAL_40:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#4, %[[VAL_22]]) {control = false} : (i1, memref<1xi32>) -> (memref<1xi32>, memref<1xi32>)
// CHECK: "handshake.sink"(%[[VAL_40]]) : (memref<1xi32>) -> ()
// CHECK: %[[VAL_41:.*]], %[[VAL_42:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#3, %[[VAL_24]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_42]]) : (index) -> ()
// CHECK: %[[VAL_43:.*]], %[[VAL_44:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#2, %[[VAL_26]]) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_44]]) : (index) -> ()
// CHECK: %[[VAL_45:.*]], %[[VAL_46:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#1, %[[VAL_28]]#0) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = "handshake.conditional_branch"(%[[VAL_34]]#0, %[[VAL_32]]#0) {control = false} : (i1, index) -> (index, index)
// CHECK: "handshake.sink"(%[[VAL_48]]) : (index) -> ()
// CHECK: %[[VAL_49:.*]] = "handshake.merge"(%[[VAL_47]]) : (index) -> index
// CHECK: %[[VAL_50:.*]]:2 = "handshake.fork"(%[[VAL_49]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_51:.*]] = "handshake.merge"(%[[VAL_37]]) : (index) -> index
// CHECK: %[[VAL_52:.*]]:2 = "handshake.fork"(%[[VAL_51]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_53:.*]] = "handshake.merge"(%[[VAL_39]]) : (memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_54:.*]]:2 = "handshake.fork"(%[[VAL_53]]) {control = false} : (memref<1xi32>) -> (memref<1xi32>, memref<1xi32>)
// CHECK: %[[VAL_55:.*]] = "handshake.merge"(%[[VAL_41]]) : (index) -> index
// CHECK: %[[VAL_56:.*]]:2 = "handshake.fork"(%[[VAL_55]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_57:.*]] = "handshake.merge"(%[[VAL_43]]) : (index) -> index
// CHECK: %[[VAL_58:.*]]:2 = "handshake.fork"(%[[VAL_57]]) {control = false} : (index) -> (index, index)
// CHECK: %[[VAL_59:.*]] = "handshake.merge"(%[[VAL_35]]) : (index) -> index
// CHECK: %[[VAL_60:.*]]:2 = "handshake.control_merge"(%[[VAL_45]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_61:.*]]:2 = "handshake.fork"(%[[VAL_60]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_60]]#1) : (index) -> ()
// CHECK: %[[VAL_62:.*]] = arith.addi %[[VAL_50]]#1, %[[VAL_52]]#1 : index
// CHECK: %[[VAL_63:.*]] = "handshake.constant"(%[[VAL_61]]#0) {value = 17 : index} : (none) -> index
// CHECK: %[[VAL_64:.*]] = arith.addi %[[VAL_62]], %[[VAL_63]] : index
// CHECK: memref.dma_wait %[[VAL_54]]#1{{\[}}%[[VAL_64]]], %[[VAL_56]]#1 : memref<1xi32>
// CHECK: %[[VAL_65:.*]] = arith.addi %[[VAL_50]]#0, %[[VAL_58]]#1 : index
// CHECK: %[[VAL_21]] = "handshake.branch"(%[[VAL_52]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_23]] = "handshake.branch"(%[[VAL_54]]#0) {control = false} : (memref<1xi32>) -> memref<1xi32>
// CHECK: %[[VAL_25]] = "handshake.branch"(%[[VAL_56]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_27]] = "handshake.branch"(%[[VAL_58]]#0) {control = false} : (index) -> index
// CHECK: %[[VAL_18]] = "handshake.branch"(%[[VAL_59]]) {control = false} : (index) -> index
// CHECK: %[[VAL_29]] = "handshake.branch"(%[[VAL_61]]#1) {control = true} : (none) -> none
// CHECK: %[[VAL_31]] = "handshake.branch"(%[[VAL_65]]) {control = false} : (index) -> index
// CHECK: %[[VAL_66:.*]]:2 = "handshake.control_merge"(%[[VAL_46]]) {control = true} : (none) -> (none, index)
// CHECK: "handshake.sink"(%[[VAL_66]]#1) : (index) -> ()
// CHECK: handshake.return %[[VAL_66]]#0 : none
// CHECK: %[[VAL_5:.*]] = constant %[[VAL_3]]#3 {value = 64 : index} : index
// CHECK: %[[VAL_6:.*]] = constant %[[VAL_3]]#2 {value = 0 : index} : index
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_3]]#1 {value = 10 : index} : index
// CHECK: %[[VAL_8:.*]] = constant %[[VAL_3]]#0 {value = 1 : index} : index
// CHECK: %[[VAL_9:.*]] = br %[[VAL_2]] : index
// CHECK: %[[VAL_10:.*]] = br %[[VAL_3]]#4 : none
// CHECK: %[[VAL_11:.*]] = br %[[VAL_4]] : memref<1xi32>
// CHECK: %[[VAL_12:.*]] = br %[[VAL_5]] : index
// CHECK: %[[VAL_13:.*]] = br %[[VAL_6]] : index
// CHECK: %[[VAL_14:.*]] = br %[[VAL_7]] : index
// CHECK: %[[VAL_15:.*]] = br %[[VAL_8]] : index
// CHECK: %[[VAL_16:.*]] = mux %[[VAL_17:.*]]#5 {{\[}}%[[VAL_18:.*]], %[[VAL_14]]] : index, index
// CHECK: %[[VAL_19:.*]]:2 = fork [2] %[[VAL_16]] : index
// CHECK: %[[VAL_20:.*]] = mux %[[VAL_17]]#4 {{\[}}%[[VAL_21:.*]], %[[VAL_9]]] : index, index
// CHECK: %[[VAL_22:.*]] = mux %[[VAL_17]]#3 {{\[}}%[[VAL_23:.*]], %[[VAL_11]]] : index, memref<1xi32>
// CHECK: %[[VAL_24:.*]] = mux %[[VAL_17]]#2 {{\[}}%[[VAL_25:.*]], %[[VAL_12]]] : index, index
// CHECK: %[[VAL_26:.*]] = mux %[[VAL_17]]#1 {{\[}}%[[VAL_27:.*]], %[[VAL_15]]] : index, index
// CHECK: %[[VAL_28:.*]], %[[VAL_29:.*]] = control_merge %[[VAL_30:.*]], %[[VAL_10]] : none
// CHECK: %[[VAL_17]]:6 = fork [6] %[[VAL_29]] : index
// CHECK: %[[VAL_31:.*]] = mux %[[VAL_17]]#0 {{\[}}%[[VAL_32:.*]], %[[VAL_13]]] : index, index
// CHECK: %[[VAL_33:.*]]:2 = fork [2] %[[VAL_31]] : index
// CHECK: %[[VAL_34:.*]] = arith.cmpi slt, %[[VAL_33]]#1, %[[VAL_19]]#1 : index
// CHECK: %[[VAL_35:.*]]:7 = fork [7] %[[VAL_34]] : i1
// CHECK: %[[VAL_36:.*]], %[[VAL_37:.*]] = cond_br %[[VAL_35]]#6, %[[VAL_19]]#0 : index
// CHECK: sink %[[VAL_37]] : index
// CHECK: %[[VAL_38:.*]], %[[VAL_39:.*]] = cond_br %[[VAL_35]]#5, %[[VAL_20]] : index
// CHECK: sink %[[VAL_39]] : index
// CHECK: %[[VAL_40:.*]], %[[VAL_41:.*]] = cond_br %[[VAL_35]]#4, %[[VAL_22]] : memref<1xi32>
// CHECK: sink %[[VAL_41]] : memref<1xi32>
// CHECK: %[[VAL_42:.*]], %[[VAL_43:.*]] = cond_br %[[VAL_35]]#3, %[[VAL_24]] : index
// CHECK: sink %[[VAL_43]] : index
// CHECK: %[[VAL_44:.*]], %[[VAL_45:.*]] = cond_br %[[VAL_35]]#2, %[[VAL_26]] : index
// CHECK: sink %[[VAL_45]] : index
// CHECK: %[[VAL_46:.*]], %[[VAL_47:.*]] = cond_br %[[VAL_35]]#1, %[[VAL_28]] : none
// CHECK: %[[VAL_48:.*]], %[[VAL_49:.*]] = cond_br %[[VAL_35]]#0, %[[VAL_33]]#0 : index
// CHECK: sink %[[VAL_49]] : index
// CHECK: %[[VAL_50:.*]] = merge %[[VAL_48]] : index
// CHECK: %[[VAL_51:.*]]:2 = fork [2] %[[VAL_50]] : index
// CHECK: %[[VAL_52:.*]] = merge %[[VAL_38]] : index
// CHECK: %[[VAL_53:.*]]:2 = fork [2] %[[VAL_52]] : index
// CHECK: %[[VAL_54:.*]] = merge %[[VAL_40]] : memref<1xi32>
// CHECK: %[[VAL_55:.*]]:2 = fork [2] %[[VAL_54]] : memref<1xi32>
// CHECK: %[[VAL_56:.*]] = merge %[[VAL_42]] : index
// CHECK: %[[VAL_57:.*]]:2 = fork [2] %[[VAL_56]] : index
// CHECK: %[[VAL_58:.*]] = merge %[[VAL_44]] : index
// CHECK: %[[VAL_59:.*]]:2 = fork [2] %[[VAL_58]] : index
// CHECK: %[[VAL_60:.*]] = merge %[[VAL_36]] : index
// CHECK: %[[VAL_61:.*]], %[[VAL_62:.*]] = control_merge %[[VAL_46]] : none
// CHECK: %[[VAL_63:.*]]:2 = fork [2] %[[VAL_61]] : none
// CHECK: sink %[[VAL_62]] : index
// CHECK: %[[VAL_64:.*]] = arith.addi %[[VAL_51]]#1, %[[VAL_53]]#1 : index
// CHECK: %[[VAL_65:.*]] = constant %[[VAL_63]]#0 {value = 17 : index} : index
// CHECK: %[[VAL_66:.*]] = arith.addi %[[VAL_64]], %[[VAL_65]] : index
// CHECK: memref.dma_wait %[[VAL_55]]#1{{\[}}%[[VAL_66]]], %[[VAL_57]]#1 : memref<1xi32>
// CHECK: %[[VAL_67:.*]] = arith.addi %[[VAL_51]]#0, %[[VAL_59]]#1 : index
// CHECK: %[[VAL_21]] = br %[[VAL_53]]#0 : index
// CHECK: %[[VAL_23]] = br %[[VAL_55]]#0 : memref<1xi32>
// CHECK: %[[VAL_25]] = br %[[VAL_57]]#0 : index
// CHECK: %[[VAL_27]] = br %[[VAL_59]]#0 : index
// CHECK: %[[VAL_18]] = br %[[VAL_60]] : index
// CHECK: %[[VAL_30]] = br %[[VAL_63]]#1 : none
// CHECK: %[[VAL_32]] = br %[[VAL_67]] : index
// CHECK: %[[VAL_68:.*]], %[[VAL_69:.*]] = control_merge %[[VAL_47]] : none
// CHECK: sink %[[VAL_69]] : index
// CHECK: return %[[VAL_68]] : none
// CHECK: }
// CHECK: }
func @affine_dma_wait(%arg0: index) {
%0 = memref.alloc() : memref<1xi32>
%c64 = arith.constant 64 : index
%c0 = arith.constant 0 : index

View File

@ -1,27 +1,25 @@
// RUN: circt-opt -lower-std-to-handshake -split-input-file %s | FileCheck %s
func @bar(%0 : i32) -> i32 {
// CHECK-LABEL: handshake.func @bar(
// CHECK-SAME: %[[VAL_0:.*]]: i32,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> (i32, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (i32) -> i32
// CHECK: handshake.return %[[VAL_2]], %[[VAL_1]] : i32, none
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : i32
// CHECK: return %[[VAL_2]], %[[VAL_1]] : i32, none
// CHECK: }
func @bar(%0 : i32) -> i32 {
return %0 : i32
}
func @foo(%0 : i32) -> i32 {
// CHECK-LABEL: handshake.func @foo(
// CHECK-SAME: %[[VAL_0:.*]]: i32,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> (i32, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]] = "handshake.merge"(%[[VAL_0]]) : (i32) -> i32
// CHECK: %[[VAL_3:.*]]:2 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_4:.*]]:2 = handshake.instance @bar(%[[VAL_2]], %[[VAL_3]]#0) : (i32, none) -> (i32, none)
// CHECK: "handshake.sink"(%[[VAL_4]]#1) {control = true} : (none) -> ()
// CHECK: handshake.return %[[VAL_4]]#0, %[[VAL_3]]#1 : i32, none
// CHECK: %[[VAL_2:.*]] = merge %[[VAL_0]] : i32
// CHECK: %[[VAL_3:.*]]:2 = fork [2] %[[VAL_1]] : none
// CHECK: %[[VAL_4:.*]]:2 = instance @bar(%[[VAL_2]], %[[VAL_3]]#0) : (i32, none) -> (i32, none)
// CHECK: sink %[[VAL_4]]#1 : none
// CHECK: return %[[VAL_4]]#0, %[[VAL_3]]#1 : i32, none
// CHECK: }
func @foo(%0 : i32) -> i32 {
%a1 = call @bar(%0) : (i32) -> i32
return %a1 : i32
}
@ -43,34 +41,34 @@ func @sub(%arg0 : i32, %arg1: i32) -> i32 {
}
// CHECK: handshake.func @main(%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i1, %[[VAL_3:.*]]: none, ...) -> (i32, none) attributes {argNames = ["in0", "in1", "in2", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_4:.*]] = "handshake.merge"(%[[VAL_0]]) : (i32) -> i32
// CHECK: %[[VAL_5:.*]] = "handshake.merge"(%[[VAL_1]]) : (i32) -> i32
// CHECK: %[[VAL_6:.*]] = "handshake.merge"(%[[VAL_2]]) : (i1) -> i1
// CHECK: %[[VAL_7:.*]]:3 = "handshake.fork"(%[[VAL_6]]) {control = false} : (i1) -> (i1, i1, i1)
// CHECK: %[[VAL_8:.*]], %[[VAL_9:.*]] = "handshake.conditional_branch"(%[[VAL_7]]#2, %[[VAL_4]]) {control = false} : (i1, i32) -> (i32, i32)
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = "handshake.conditional_branch"(%[[VAL_7]]#1, %[[VAL_5]]) {control = false} : (i1, i32) -> (i32, i32)
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = "handshake.conditional_branch"(%[[VAL_7]]#0, %[[VAL_3]]) {control = true} : (i1, none) -> (none, none)
// CHECK: %[[VAL_14:.*]] = "handshake.merge"(%[[VAL_8]]) : (i32) -> i32
// CHECK: %[[VAL_15:.*]] = "handshake.merge"(%[[VAL_10]]) : (i32) -> i32
// CHECK: %[[VAL_16:.*]]:2 = "handshake.control_merge"(%[[VAL_12]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_17:.*]]:2 = "handshake.fork"(%[[VAL_16]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_16]]#1) : (index) -> ()
// CHECK: %[[VAL_18:.*]]:2 = handshake.instance @add(%[[VAL_14]], %[[VAL_15]], %[[VAL_17]]#1) : (i32, i32, none) -> (i32, none)
// CHECK: "handshake.sink"(%[[VAL_18]]#1) {control = true} : (none) -> ()
// CHECK: %[[VAL_19:.*]] = "handshake.branch"(%[[VAL_17]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_20:.*]] = "handshake.branch"(%[[VAL_18]]#0) {control = false} : (i32) -> i32
// CHECK: %[[VAL_21:.*]] = "handshake.merge"(%[[VAL_9]]) : (i32) -> i32
// CHECK: %[[VAL_22:.*]] = "handshake.merge"(%[[VAL_11]]) : (i32) -> i32
// CHECK: %[[VAL_23:.*]]:2 = "handshake.control_merge"(%[[VAL_13]]) {control = true} : (none) -> (none, index)
// CHECK: %[[VAL_24:.*]]:2 = "handshake.fork"(%[[VAL_23]]#0) {control = true} : (none) -> (none, none)
// CHECK: "handshake.sink"(%[[VAL_23]]#1) : (index) -> ()
// CHECK: %[[VAL_25:.*]]:2 = handshake.instance @sub(%[[VAL_21]], %[[VAL_22]], %[[VAL_24]]#1) : (i32, i32, none) -> (i32, none)
// CHECK: "handshake.sink"(%[[VAL_25]]#1) {control = true} : (none) -> ()
// CHECK: %[[VAL_26:.*]] = "handshake.branch"(%[[VAL_24]]#0) {control = true} : (none) -> none
// CHECK: %[[VAL_27:.*]] = "handshake.branch"(%[[VAL_25]]#0) {control = false} : (i32) -> i32
// CHECK: %[[VAL_28:.*]]:2 = "handshake.control_merge"(%[[VAL_26]], %[[VAL_19]]) {control = true} : (none, none) -> (none, index)
// CHECK: %[[VAL_29:.*]] = "handshake.mux"(%[[VAL_28]]#1, %[[VAL_27]], %[[VAL_20]]) : (index, i32, i32) -> i32
// CHECK: handshake.return %[[VAL_29]], %[[VAL_28]]#0 : i32, none
// CHECK: %[[VAL_4:.*]] = merge %[[VAL_0]] : i32
// CHECK: %[[VAL_5:.*]] = merge %[[VAL_1]] : i32
// CHECK: %[[VAL_6:.*]] = merge %[[VAL_2]] : i1
// CHECK: %[[VAL_7:.*]]:3 = fork [3] %[[VAL_6]] : i1
// CHECK: %[[VAL_8:.*]], %[[VAL_9:.*]] = cond_br %[[VAL_7]]#2, %[[VAL_4]] : i32
// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = cond_br %[[VAL_7]]#1, %[[VAL_5]] : i32
// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_7]]#0, %[[VAL_3]] : 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_18:.*]]:2 = fork [2] %[[VAL_16]] : none
// CHECK: sink %[[VAL_17]] : index
// CHECK: %[[VAL_19:.*]]:2 = instance @add(%[[VAL_14]], %[[VAL_15]], %[[VAL_18]]#1) : (i32, i32, none) -> (i32, none)
// CHECK: sink %[[VAL_19]]#1 : none
// CHECK: %[[VAL_20:.*]] = br %[[VAL_18]]#0 : none
// CHECK: %[[VAL_21:.*]] = br %[[VAL_19]]#0 : i32
// CHECK: %[[VAL_22:.*]] = merge %[[VAL_9]] : i32
// CHECK: %[[VAL_23:.*]] = merge %[[VAL_11]] : i32
// CHECK: %[[VAL_24:.*]], %[[VAL_25:.*]] = control_merge %[[VAL_13]] : none
// CHECK: %[[VAL_26:.*]]:2 = fork [2] %[[VAL_24]] : none
// CHECK: sink %[[VAL_25]] : index
// CHECK: %[[VAL_27:.*]]:2 = instance @sub(%[[VAL_22]], %[[VAL_23]], %[[VAL_26]]#1) : (i32, i32, none) -> (i32, none)
// CHECK: sink %[[VAL_27]]#1 : none
// CHECK: %[[VAL_28:.*]] = br %[[VAL_26]]#0 : none
// CHECK: %[[VAL_29:.*]] = br %[[VAL_27]]#0 : i32
// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge %[[VAL_28]], %[[VAL_20]] : none
// CHECK: %[[VAL_32:.*]] = mux %[[VAL_31]] {{\[}}%[[VAL_29]], %[[VAL_21]]] : index, i32
// CHECK: return %[[VAL_32]], %[[VAL_30]] : i32, none
// CHECK: }
func @main(%arg0 : i32, %arg1 : i32, %cond : i1) -> i32 {
cond_br %cond, ^bb1, ^bb2

View File

@ -3,13 +3,13 @@
// CHECK-LABEL: handshake.func @main(
// CHECK-SAME: %[[VAL_0:.*]]: memref<4xi32>,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> (i32, none) attributes {argNames = ["in0", "inCtrl"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:2 = handshake.extmemory[ld = 1, st = 0] (%[[VAL_0]] : memref<4xi32>) (%[[VAL_3:.*]]) {id = 0 : i32} : (index) -> (i32, none)
// CHECK: %[[VAL_4:.*]]:2 = "handshake.fork"(%[[VAL_1]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_5:.*]]:2 = "handshake.fork"(%[[VAL_4]]#1) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_6:.*]] = "handshake.join"(%[[VAL_5]]#1, %[[VAL_2]]#1) {control = true} : (none, none) -> none
// CHECK: %[[VAL_7:.*]] = "handshake.constant"(%[[VAL_5]]#0) {value = 0 : index} : (none) -> index
// CHECK: %[[VAL_8:.*]], %[[VAL_3]] = "handshake.load"(%[[VAL_7]], %[[VAL_2]]#0, %[[VAL_4]]#0) : (index, i32, none) -> (i32, index)
// CHECK: handshake.return %[[VAL_8]], %[[VAL_6]] : i32, none
// CHECK: %[[VAL_2:.*]]:2 = extmemory[ld = 1, st = 0] (%[[VAL_0]] : memref<4xi32>) (%[[VAL_3:.*]]) {id = 0 : i32} : (index) -> (i32, none)
// CHECK: %[[VAL_4:.*]]:2 = fork [2] %[[VAL_1]] : none
// CHECK: %[[VAL_5:.*]]:2 = fork [2] %[[VAL_4]]#1 : none
// CHECK: %[[VAL_6:.*]] = join %[[VAL_5]]#1, %[[VAL_2]]#1 : none
// CHECK: %[[VAL_7:.*]] = constant %[[VAL_5]]#0 {value = 0 : index} : index
// CHECK: %[[VAL_8:.*]], %[[VAL_3]] = load {{\[}}%[[VAL_7]]] %[[VAL_2]]#0, %[[VAL_4]]#0 : index, i32
// CHECK: return %[[VAL_8]], %[[VAL_6]] : i32, none
// CHECK: }
func @main(%mem : memref<4xi32>) -> i32 {
%idx = arith.constant 0 : index

View File

@ -3,86 +3,82 @@
// RUN: circt-opt -handshake-insert-buffer=strategies=all %s | circt-opt -handshake-insert-buffer=strategies=all | FileCheck %s -check-prefix=ALL
module {
handshake.func @simple_loop(%arg0: none, ...) -> none {
// ALL: "handshake.buffer"
// ALL-NOT: "handshake.buffer"
// ALL: "handshake.branch"
%0 = "handshake.branch"(%arg0) {control = true} : (none) -> none
// ALL: "handshake.buffer"
%1:2 = "handshake.control_merge"(%0) {control = true} : (none) -> (none, index)
// ALL: "handshake.buffer"
%2:3 = "handshake.fork"(%1#0) {control = true} : (none) -> (none, none, none)
// ALL: "handshake.buffer"
"handshake.sink"(%1#1) : (index) -> ()
// ALL: "handshake.buffer"
%3 = "handshake.constant"(%2#1) {value = 1 : index} : (none) -> index
// ALL: "handshake.buffer"
%4 = "handshake.constant"(%2#0) {value = 42 : index} : (none) -> index
// ALL: "handshake.buffer"
%5 = "handshake.branch"(%2#2) {control = true} : (none) -> none
// ALL: "handshake.buffer"
%6 = "handshake.branch"(%3) {control = false} : (index) -> index
// ALL: "handshake.buffer"
%7 = "handshake.branch"(%4) {control = false} : (index) -> index
// ALL: "handshake.buffer"
%8 = "handshake.mux"(%11#1, %22, %7) : (index, index, index) -> index
// ALL: "handshake.buffer"
%9:2 = "handshake.fork"(%8) {control = false} : (index) -> (index, index)
// ALL: "handshake.buffer"
// CHECK: %10:2 = "handshake.control_merge"(%28, %5) {control = true} : (none, none) -> (none, index)
// CHECK-NEXT: %11 = "handshake.buffer"(%10#0) {control = true, sequential = true, slots = 2 : i32} : (none) -> none
%10:2 = "handshake.control_merge"(%23, %5) {control = true} : (none, none) -> (none, index)
// ALL: "handshake.buffer"
// CHECK: %12:2 = "handshake.fork"(%10#1) {control = false} : (index) -> (index, index)
// CHECK-NEXT: %13 = "handshake.buffer"(%12#1) {control = false, sequential = true, slots = 2 : i32} : (index) -> index
%11:2 = "handshake.fork"(%10#1) {control = false} : (index) -> (index, index)
// ALL: "handshake.buffer"
%12 = "handshake.mux"(%11#0, %24, %6) : (index, index, index) -> index
// ALL: "handshake.buffer"
// CHECK: %15:2 = "handshake.fork"(%14) {control = false} : (index) -> (index, index)
// CHECK-NEXT: %16 = "handshake.buffer"(%15#1) {control = false, sequential = true, slots = 2 : i32} : (index) -> index
// CHECK-NEXT: %17 = "handshake.buffer"(%15#0) {control = false, sequential = true, slots = 2 : i32} : (index) -> index
%13:2 = "handshake.fork"(%12) {control = false} : (index) -> (index, index)
// ALL: "handshake.buffer"
// ALL: buffer
// ALL-NOT: buffer
// ALL: br
%0 = br %arg0 : none
// ALL: buffer
%1:2 = control_merge %0 : none
// ALL: buffer
%2:3 = fork [3] %1#0 : none
// ALL: buffer
sink %1#1 : index
// ALL: buffer
%3 = constant %2#1 {value = 1 : index} : index
// ALL: buffer
%4 = constant %2#0 {value = 42 : index} : index
// ALL: buffer
%5 = br %2#2 : none
// ALL: buffer
%6 = br %3 : index
// ALL: buffer
%7 = br %4 : index
// ALL: buffer
%8 = mux %11#1 [%22, %7] : index, index
// ALL: buffer
%9:2 = fork [2] %8 : index
// ALL: buffer
// CHECK: %result_0, %index_1 = control_merge %23, %4 : none
// CHECK-NEXT: %9 = buffer [2] %result_0 {sequential = true} : none
%10:2 = control_merge %23, %5 : none
// ALL: buffer
// CHECK: %10:2 = fork [2] %index_1 : index
// CHECK-NEXT: %11 = buffer [2] %10#1 {sequential = true} : index
%11:2 = fork [2] %10#1 : index
// ALL: buffer
%12 = mux %9#0 [%24, %6] : index, index
// ALL: buffer
// CHECK: %13:2 = fork [2] %12 : index
%13:2 = fork [2] %12 : index
// ALL: buffer
%14 = arith.cmpi slt, %13#1, %9#1 : index
// ALL: "handshake.buffer"
%15:3 = "handshake.fork"(%14) {control = false} : (i1) -> (i1, i1, i1)
// ALL: "handshake.buffer"
%trueResult, %falseResult = "handshake.conditional_branch"(%15#2, %9#0) {control = false} : (i1, index) -> (index, index)
// ALL: "handshake.buffer"
"handshake.sink"(%falseResult) : (index) -> ()
// ALL: "handshake.buffer"
%trueResult_0, %falseResult_1 = "handshake.conditional_branch"(%15#1, %10#0) {control = true} : (i1, none) -> (none, none)
// ALL: "handshake.buffer"
%trueResult_2, %falseResult_3 = "handshake.conditional_branch"(%15#0, %13#0) {control = false} : (i1, index) -> (index, index)
// ALL: "handshake.buffer"
"handshake.sink"(%falseResult_3) : (index) -> ()
// ALL: "handshake.buffer"
%16 = "handshake.merge"(%trueResult_2) : (index) -> index
// ALL: "handshake.buffer"
%17 = "handshake.merge"(%trueResult) : (index) -> index
// ALL: "handshake.buffer"
%18:2 = "handshake.control_merge"(%trueResult_0) {control = true} : (none) -> (none, index)
// ALL: "handshake.buffer"
%19:2 = "handshake.fork"(%18#0) {control = true} : (none) -> (none, none)
// ALL: "handshake.buffer"
"handshake.sink"(%18#1) : (index) -> ()
// ALL: "handshake.buffer"
%20 = "handshake.constant"(%19#0) {value = 1 : index} : (none) -> index
// ALL: "handshake.buffer"
// ALL: buffer
%15:3 = fork [3] %14 : i1
// ALL: buffer
%trueResult, %falseResult = cond_br %15#2, %9#0 : index
// ALL: buffer
sink %falseResult : index
// ALL: buffer
%trueResult_0, %falseResult_1 = cond_br %15#1, %10#0 : none
// ALL: buffer
%trueResult_2, %falseResult_3 = cond_br %15#0, %13#0 : index
// ALL: buffer
sink %falseResult_3 : index
// ALL: buffer
%16 = merge %trueResult_2 : index
// ALL: buffer
%17 = merge %trueResult : index
// ALL: buffer
%18:2 = control_merge %trueResult_0 : none
// ALL: buffer
%19:2 = fork [2] %18#0 : none
// ALL: buffer
sink %18#1 : index
// ALL: buffer
%20 = constant %19#0 {value = 1 : index} : index
// ALL: buffer
%21 = arith.addi %16, %20 : index
// ALL: "handshake.buffer"
// CHECK: %26 = "handshake.branch"(%21) {control = false} : (index) -> index
// CHECK-NEXT: %27 = "handshake.buffer"(%26) {control = false, sequential = true, slots = 2 : i32} : (index) -> index
%22 = "handshake.branch"(%17) {control = false} : (index) -> index
// ALL: "handshake.buffer"
%23 = "handshake.branch"(%19#1) {control = true} : (none) -> none
// ALL: "handshake.buffer"
%24 = "handshake.branch"(%21) {control = false} : (index) -> index
// ALL: "handshake.buffer"
%25:2 = "handshake.control_merge"(%falseResult_1) {control = true} : (none) -> (none, index)
// ALL: "handshake.buffer"
"handshake.sink"(%25#1) : (index) -> ()
// ALL: "handshake.buffer"
handshake.return %25#0 : none
// ALL: buffer
%22 = br %17 : index
// ALL: buffer
%23 = br %19#1 : none
// ALL: buffer
%24 = br %21 : index
// ALL: buffer
%25:2 = control_merge %falseResult_1 : none
// ALL: buffer
sink %25#1 : index
// ALL: buffer
return %25#0 : none
}
}

View File

@ -3,6 +3,6 @@
module {
// expected-error @+1 {{Unknown buffer strategy: foo}}
handshake.func @test(%arg0: none, ...) -> none {
handshake.return %arg0 : none
return %arg0 : none
}
}

View File

@ -1,85 +1,82 @@
// RUN: circt-opt -split-input-file -canonicalize='top-down=true region-simplify=true' %s | FileCheck %s
// CHECK-LABEL: handshake.func @simple(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none
// CHECK: %[[VAL_1:.*]] = "handshake.constant"(%[[VAL_0]]) {value = 1 : index} : (none) -> index
// CHECK: %[[VAL_2:.*]]:2 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none)
// CHECK: %[[VAL_3:.*]] = "handshake.constant"(%[[VAL_2]]#0) {value = 42 : index} : (none) -> index
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["arg0"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_1:.*]] = constant %[[VAL_0]] {value = 1 : index} : index
// CHECK: %[[VAL_2:.*]]:2 = fork [2] %[[VAL_0]] : none
// CHECK: %[[VAL_3:.*]] = constant %[[VAL_2]]#0 {value = 42 : index} : index
// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_1]], %[[VAL_3]] : index
// CHECK: "handshake.sink"(%[[VAL_4]]) : (index) -> ()
// CHECK: handshake.return %[[VAL_2]]#1 : none
// CHECK: sink %[[VAL_4]] : index
// CHECK: return %[[VAL_2]]#1 : none
// CHECK: }
handshake.func @simple(%arg0: none, ...) -> none {
%0 = "handshake.constant"(%arg0) {value = 1 : index} : (none) -> index
%1 = "handshake.branch"(%arg0) {control = true} : (none) -> none
%2 = "handshake.branch"(%0) {control = false} : (index) -> index
%3 = "handshake.merge"(%1) : (none) -> none
%4 = "handshake.merge"(%2) : (index) -> index
%5:2 = "handshake.fork"(%3) {control = true} : (none) -> (none, none)
%6 = "handshake.constant"(%5#0) {value = 42 : index} : (none) -> index
%0 = constant %arg0 {value = 1 : index} : index
%1 = br %arg0 : none
%2 = br %0 : index
%3 = merge %1 : none
%4 = merge %2 : index
%5:2 = fork [2] %3 : none
%6 = constant %5#0 {value = 42 : index} : index
%7 = arith.addi %4, %6 : index
"handshake.sink"(%7) : (index) -> ()
sink %7 : index
handshake.return %5#1 : none
}
// -----
// CHECK-LABEL: handshake.func @cmerge_with_control_used(
// CHECK-SAME: %[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, index, none)
// CHECK: %[[VAL_3:.*]]:2 = "handshake.control_merge"(%[[VAL_0]], %[[VAL_1]]) {control = true} : (none, none) -> (none, index)
// CHECK: handshake.return %[[VAL_3]]#0, %[[VAL_3]]#1, %[[VAL_2]] : none, index, none
// CHECK: handshake.func @cmerge_with_control_used(%[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, index, none) attributes {argNames = ["arg0", "arg1", "arg2"], resNames = ["out0", "out1", "outCtrl"]} {
// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge %[[VAL_0]], %[[VAL_1]] : none
// 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 = "handshake.control_merge"(%arg0, %arg1) {control = true} : (none, none) -> (none, index)
%result, %index = control_merge %arg0, %arg1 : none
handshake.return %result, %index, %arg2 : none, index, none
}
// -----
// CHECK-LABEL: handshake.func @cmerge_with_control_sunk(
// CHECK-SAME: %[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, none)
// CHECK: %[[VAL_3:.*]] = "handshake.merge"(%[[VAL_0]], %[[VAL_1]]) : (none, none) -> none
// CHECK: handshake.return %[[VAL_3]], %[[VAL_2]] : none, none
// CHECK: handshake.func @cmerge_with_control_sunk(%[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, none) attributes {argNames = ["arg0", "arg1", "arg2"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_3:.*]] = merge %[[VAL_0]], %[[VAL_1]] : 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 = "handshake.control_merge"(%arg0, %arg1) {control = true} : (none, none) -> (none, index)
"handshake.sink"(%index) : (index) -> ()
%result, %index = control_merge %arg0, %arg1 : none
sink %index : index
handshake.return %result, %arg2 : none, none
}
// -----
// CHECK-LABEL: handshake.func @cmerge_with_control_ignored(
// CHECK-SAME: %[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, none)
// CHECK: %[[VAL_3:.*]] = "handshake.merge"(%[[VAL_0]], %[[VAL_1]]) : (none, none) -> none
// CHECK: handshake.return %[[VAL_3]], %[[VAL_2]] : none, none
// CHECK: handshake.func @cmerge_with_control_ignored(%[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> (none, none) attributes {argNames = ["arg0", "arg1", "arg2"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_3:.*]] = merge %[[VAL_0]], %[[VAL_1]] : 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 = "handshake.control_merge"(%arg0, %arg1) {control = true} : (none, none) -> (none, index)
%result, %index = control_merge %arg0, %arg1 : none
handshake.return %result, %arg2 : none, none
}
// -----
// CHECK-LABEL: handshake.func @sunk_constant(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none
// CHECK: handshake.return %[[VAL_0]] : none
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> none attributes {argNames = ["arg0"], resNames = ["outCtrl"]} {
// CHECK: return %[[VAL_0]] : none
// CHECK: }
handshake.func @sunk_constant(%arg0: none) -> (none) {
%0 = "handshake.constant"(%arg0) { value = 24 : i8 } : (none) -> i8
"handshake.sink"(%0) : (i8) -> ()
%0 = constant %arg0 { value = 24 : i8 } : i8
sink %0 : i8
handshake.return %arg0: none
}
// -----
// CHECK-LABEL: handshake.func @unused_fork_result(
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> (none, none)
// CHECK: %[[VAL_1:.*]]:2 = "handshake.fork"(%[[VAL_0]]) {control = true} : (none) -> (none, none)
// CHECK: handshake.return %[[VAL_1]]#0, %[[VAL_1]]#1 : none, none
// CHECK-SAME: %[[VAL_0:.*]]: none, ...) -> (none, none) attributes {argNames = ["arg0"], resNames = ["out0", "outCtrl"]} {
// CHECK: %[[VAL_1:.*]]:2 = fork [2] %[[VAL_0]] : none
// CHECK: return %[[VAL_1]]#0, %[[VAL_1]]#1 : none, none
// CHECK: }
handshake.func @unused_fork_result(%arg0: none) -> (none, none) {
%0:3 = "handshake.fork"(%arg0) { control = true } : (none) -> (none, none, none)
%0:3 = fork [3] %arg0 : none
handshake.return %0#0, %0#2 : none, none
}

View File

@ -0,0 +1,40 @@
// RUN: circt-opt %s --split-input-file --verify-diagnostics
handshake.func @invalid_operand_count(%data:f32, %staddress: index, %ldaddress: index) -> (f32, none, none) {
// expected-error @+1 {{number of operands 3 does not match number expected of 2 with 1 address inputs per port}}
%0:3 = memory [ld = 0, st = 1](%data, %staddress, %ldaddress) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none, none)
return %0#0, %0#1, %0#2 : f32, none, none
}
// -----
handshake.func @invalid_result_count(%data:f32, %staddress: index, %ldaddress: index) -> (f32, none) {
// expected-error @+1 {{number of results 2 does not match number expected of 3 with 1 address inputs per port}}
%0:2 = memory [ld = 1, st = 1](%data, %staddress, %ldaddress) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (f32, none)
return %0#0, %0#1 : f32, none
}
// -----
handshake.func @invalid_address_type(%data:f32, %staddress: f32, %ldaddress: index) -> (f32, none, none) {
// expected-error @+1 {{address type for load port 0:'index' doesn't match address type 'f32'}}
%0:3 = memory [ld = 1, st = 1](%data, %staddress, %ldaddress) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, f32, index) -> (f32, none, none)
return %0#0, %0#1, %0#2 : f32, none, none
}
// -----
handshake.func @invalid_store_data_type(%data:i32, %staddress: index, %ldaddress: index) -> (f32, none, none) {
// expected-error @+1 {{data type for store port 0:'i32' doesn't match memory type 'f32'}}
%0:3 = memory [ld = 1, st = 1](%data, %staddress, %ldaddress) {id = 0 : i32, lsq = false} : memref<10xf32>, (i32, index, index) -> (f32, none, none)
return %0#0, %0#1, %0#2 : f32, none, none
}
// -----
handshake.func @invalid_load_data_type(%data:f32, %staddress: index, %ldaddress: index) -> (f32, none, none) {
// expected-error @+1 {{data type for load port 0:'i32' doesn't match memory type 'f32'}}
%0:3 = memory[ld = 1, st = 1](%data, %staddress, %ldaddress) {id = 0 : i32, lsq = false} : memref<10xf32>, (f32, index, index) -> (i32, none, none)
return %0#0, %0#1, %0#2 : i32, none, none
}

View File

@ -2,15 +2,15 @@
handshake.func @invalid_merge_like_no_data(%arg0: i1) {
// expected-error @+1 {{'handshake.mux' op must have at least one data operand}}
%0 = "handshake.mux"(%arg0) : (i1) -> (i32)
%0 = mux %arg0 [] : i1, i32
return %0 : i32
}
// -----
handshake.func @invalid_merge_like_wrong_type(%arg0: i1, %arg1: i32, %arg2: i64) {
// expected-error @+1 {{'handshake.mux' op operand has type 'i64', but result has type 'i32'}}
%0 = "handshake.mux"(%arg0, %arg1, %arg2) : (i1, i32, i64) -> (i32)
handshake.func @invalid_merge_like_wrong_type(%arg0: i1, %arg1: i32, %arg2: i64) { // expected-note {{prior use here}}
// expected-error @+1 {{use of value '%arg2' expects different type than prior uses: 'i32' vs 'i64'}}
%0 = mux %arg0 [%arg1, %arg2] : i1, i32
return %0 : i32
}
@ -18,7 +18,7 @@ handshake.func @invalid_merge_like_wrong_type(%arg0: i1, %arg1: i32, %arg2: i64)
handshake.func @invalid_mux_single_operand(%arg0: i1, %arg1: i32) {
// expected-error @+1 {{need at least two inputs to mux}}
%0 = "handshake.mux"(%arg0, %arg1) : (i1, i32) -> (i32)
%0 = mux %arg0 [%arg1] : i1, i32
return %0 : i32
}
@ -26,7 +26,7 @@ handshake.func @invalid_mux_single_operand(%arg0: i1, %arg1: i32) {
handshake.func @invalid_mux_unsupported_select(%arg0: tensor<i1>, %arg1: i32, %arg2: i32) {
// expected-error @+1 {{unsupported type for select operand: 'tensor<i1>'}}
%0 = "handshake.mux"(%arg0, %arg1, %arg2) : (tensor<i1>, i32, i32) -> (i32)
%0 = mux %arg0 [%arg1, %arg2] : tensor<i1>, i32
return %0 : i32
}
@ -34,74 +34,74 @@ 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}}
%0 = "handshake.mux"(%arg0, %arg1, %arg2, %arg3) : (i1, i32, i32, i32) -> (i32)
%0 = mux %arg0 [%arg1, %arg2, %arg3] : i1, i32
return %0 : i32
}
// -----
handshake.func @foo(%ctrl : none) -> none{
handshake.return %ctrl : none
return %ctrl : none
}
handshake.func @invalid_instance_op(%arg0 : i32, %ctrl : none) -> none {
// expected-error @+1 {{'handshake.instance' op last operand must be a control (none-typed) operand.}}
handshake.instance @foo(%ctrl, %arg0) : (none, i32) -> ()
handshake.return %ctrl : none
instance @foo(%ctrl, %arg0) : (none, i32) -> ()
return %ctrl : none
}
// -----
handshake.func @foo(%ctrl : none) -> none{
handshake.return %ctrl : none
return %ctrl : none
}
handshake.func @invalid_instance_op(%ctrl : none) -> none {
// expected-error @+1 {{'handshake.instance' op must provide at least a control operand.}}
handshake.instance @foo() : () -> ()
handshake.return %ctrl : none
instance @foo() : () -> ()
return %ctrl : none
}
// -----
handshake.func @invalid_multidim_memory() {
handshake.func @invalid_multidim_memory(%ctrl : none) -> none {
// expected-error @+1 {{'handshake.memory' op memref must have only a single dimension.}}
"handshake.memory"() {type = memref<10x10xi8>, id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32} : () -> ()
return
memory [ld = 0, st = 0] () {id = 0 : i32, lsq = false} : memref<10x10xi8>, () -> ()
return %ctrl : none
}
// -----
handshake.func @invalid_dynamic_memory() {
handshake.func @invalid_dynamic_memory(%ctrl : none) -> none {
// expected-error @+1 {{'handshake.memory' op memref dimensions for handshake.memory must be static.}}
"handshake.memory"() {type = memref<?xi8>, id = 0 : i32, ld_count = 1 : i32, lsq = false, st_count = 1 : i32} : () -> ()
return
memory [ld = 0, st = 0] () {id = 0 : i32, lsq = false} : memref<?xi8>, () -> ()
return %ctrl : none
}
// -----
// expected-error @+1 {{'handshake.func' op attribute 'argNames' has 2 entries but is expected to have 3.}}
handshake.func @invalid_num_argnames(%a : i32, %b : i32, %c : none) -> none attributes {argNames = ["a", "b"]} {
handshake.return %c : none
return %c : none
}
// -----
// expected-error @+1 {{'handshake.func' op expected all entries in attribute 'argNames' to be strings.}}
handshake.func @invalid_type_argnames(%a : i32, %b : none) -> none attributes {argNames = ["a", 2 : i32]} {
handshake.return %b : none
return %b : none
}
// -----
// expected-error @+1 {{'handshake.func' op attribute 'resNames' has 1 entries but is expected to have 2.}}
handshake.func @invalid_num_resnames(%a : i32, %b : i32, %c : none) -> (i32, none) attributes {resNames = ["a"]} {
handshake.return %a, %c : i32, none
return %a, %c : i32, none
}
// -----
// expected-error @+1 {{'handshake.func' op expected all entries in attribute 'resNames' to be strings.}}
handshake.func @invalid_type_resnames(%a : i32, %b : none) -> none attributes {resNames = [2 : i32]} {
handshake.return %b : none
return %b : none
}

View File

@ -3,12 +3,12 @@
// CHECK-LABEL: handshake.func @missing_fork_and_sink(
// CHECK-SAME: %[[VAL_0:.*]]: i32,
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none attributes {argNames = ["arg0", "ctrl"], resNames = ["outCtrl"]} {
// CHECK: %[[VAL_2:.*]]:2 = "handshake.fork"(%[[VAL_0]]) {control = false} : (i32) -> (i32, i32)
// CHECK: %[[VAL_2:.*]]:2 = fork [2] %[[VAL_0]] : i32
// CHECK: %[[VAL_3:.*]] = arith.addi %[[VAL_2]]#0, %[[VAL_2]]#1 : i32
// CHECK: "handshake.sink"(%[[VAL_3]]) : (i32) -> ()
// CHECK: handshake.return %[[VAL_1]] : none
// CHECK: sink %[[VAL_3]] : i32
// CHECK: return %[[VAL_1]] : none
// CHECK: }
handshake.func @missing_fork_and_sink(%arg0 : i32, %ctrl: none) -> (none) {
%0 = arith.addi %arg0, %arg0 : i32
handshake.return %ctrl: none
return %ctrl: none
}