From 003ae905cd762f16620206d481e5e979c45d9e3a Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 20 Nov 2024 14:18:39 -0500 Subject: [PATCH 01/14] lower arith cmpf to calyx --- .../circt/Dialect/Calyx/CalyxPrimitives.td | 52 +++++++- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 123 +++++++++++++++++- lib/Dialect/Calyx/CalyxOps.cpp | 6 + .../Calyx/Transforms/CalyxLoweringUtils.cpp | 4 +- .../Conversion/SCFToCalyx/convert_simple.mlir | 70 ++++++++++ 5 files changed, 245 insertions(+), 10 deletions(-) diff --git a/include/circt/Dialect/Calyx/CalyxPrimitives.td b/include/circt/Dialect/Calyx/CalyxPrimitives.td index dc77d7bdaca9..57e03a2cf50b 100644 --- a/include/circt/Dialect/Calyx/CalyxPrimitives.td +++ b/include/circt/Dialect/Calyx/CalyxPrimitives.td @@ -332,13 +332,15 @@ def AndLibOp : CombinationalArithBinaryLibraryOp<"and"> {} def OrLibOp : CombinationalArithBinaryLibraryOp<"or"> {} def XorLibOp : CombinationalArithBinaryLibraryOp<"xor"> {} -class ArithBinaryFloatingPointLibraryOp : - ArithBinaryLibraryOp traits = []> : + ArithBinaryLibraryOp, - SameTypeConstraint<"left", "out"> - ]> {} + SameTypeConstraint<"left", "right"> + ])> {} -def AddFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.add"> { +def AddFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.add", [ + SameTypeConstraint<"left", "out"> + ]> { let results = (outs I1:$clk, I1:$reset, I1:$go, I1:$control, I1:$subOp, AnySignlessInteger:$left, AnySignlessInteger:$right, AnySignlessInteger:$roundingMode, AnySignlessInteger:$out, AnySignlessInteger:$exceptionalFlags, I1:$done); @@ -378,7 +380,9 @@ def AddFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.add"> { }]; } -def MulFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.mul"> { +def MulFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.mul", [ + SameTypeConstraint<"left", "out"> + ]> { let results = (outs I1:$clk, I1:$reset, I1:$go, I1:$control, AnySignlessInteger:$left, AnySignlessInteger:$right, AnySignlessInteger:$roundingMode, AnySignlessInteger:$out, AnySignlessInteger:$exceptionalFlags, I1:$done); @@ -413,6 +417,42 @@ def MulFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.mul"> { }]; } +def CompareFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.compare", []> { + let results = (outs I1:$clk, I1:$reset, I1:$go, + AnySignlessInteger:$left, AnySignlessInteger:$right, I1:$signaling, + I1:$lt, I1: $eq, I1: $gt, I1: $unordered, AnySignlessInteger: $exceptionalFlags, I1: $done); + let assemblyFormat = "$sym_name attr-dict `:` qualified(type(results))"; + let extraClassDefinition = [{ + SmallVector $cppClass::portNames() { + return {clkPort, resetPort, goPort, "left", "right", "signaling", + "lt", "eq", "gt", "unordered", "exceptionalFlags", donePort + }; + } + SmallVector $cppClass::portDirections() { + return {Input, Input, Input, Input, Input, Input, Output, Output, Output, Output, Output, Output}; + } + void $cppClass::getAsmResultNames(OpAsmSetValueNameFn setNameFn) { + getCellAsmResultNames(setNameFn, *this, this->portNames()); + } + bool $cppClass::isCombinational() { return false; } + SmallVector $cppClass::portAttributes() { + IntegerAttr isSet = IntegerAttr::get(IntegerType::get(getContext(), 1), 1); + NamedAttrList go, clk, reset, done; + go.append(goPort, isSet); + clk.append(clkPort, isSet); + reset.append(resetPort, isSet); + done.append(donePort, isSet); + return {clk.getDictionary(getContext()), reset.getDictionary(getContext()), + go.getDictionary(getContext()), DictionaryAttr::get(getContext()), + DictionaryAttr::get(getContext()), DictionaryAttr::get(getContext()), + DictionaryAttr::get(getContext()), DictionaryAttr::get(getContext()), + DictionaryAttr::get(getContext()), DictionaryAttr::get(getContext()), + DictionaryAttr::get(getContext()), done.getDictionary(getContext()) + }; + } + }]; +} + def MuxLibOp : CalyxLibraryOp<"mux", "std_", [ Combinational, SameTypeConstraint<"tru", "fal">, SameTypeConstraint<"tru", "out"> ]> { diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index 2b406b2c54dc..ebd280e00faf 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -289,7 +289,7 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern { AndIOp, XOrIOp, OrIOp, ExtUIOp, ExtSIOp, TruncIOp, MulIOp, DivUIOp, DivSIOp, RemUIOp, RemSIOp, /// floating point - AddFOp, MulFOp, + AddFOp, MulFOp, CmpFOp, /// others SelectOp, IndexCastOp, CallOp>( [&](auto op) { return buildOp(rewriter, op).succeeded(); }) @@ -326,6 +326,7 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern { LogicalResult buildOp(PatternRewriter &rewriter, RemSIOp op) const; LogicalResult buildOp(PatternRewriter &rewriter, AddFOp op) const; LogicalResult buildOp(PatternRewriter &rewriter, MulFOp op) const; + LogicalResult buildOp(PatternRewriter &rewriter, CmpFOp op) const; LogicalResult buildOp(PatternRewriter &rewriter, ShRUIOp op) const; LogicalResult buildOp(PatternRewriter &rewriter, ShRSIOp op) const; LogicalResult buildOp(PatternRewriter &rewriter, ShLIOp op) const; @@ -729,6 +730,124 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, mulFOp.getOut()); } +LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, + CmpFOp cmpf) const { + Location loc = cmpf.getLoc(); + IntegerType one = rewriter.getI1Type(), five = rewriter.getIntegerType(5), + width = rewriter.getIntegerType( + cmpf.getLhs().getType().getIntOrFloatBitWidth()); + auto cmpFOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, + {one, one, one, width, width, one, one, one, one, one, + five, one}); + hw::ConstantOp constantOne = + createConstant(loc, rewriter, getComponent(), 1, 1); + Value unordered = cmpFOp.getUnordered(); + rewriter.setInsertionPointToStart(getComponent().getBodyBlock()); + switch (cmpf.getPredicate()) { + case CmpFPredicate::OEQ: { + Value ordered = rewriter.create(loc, unordered, constantOne); + Value out = rewriter.create(loc, ordered, cmpFOp.getEq()); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::OGT: { + Value ordered = rewriter.create(loc, unordered, constantOne); + Value out = rewriter.create(loc, ordered, cmpFOp.getGt()); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::OGE: { + Value ordered = rewriter.create(loc, unordered, constantOne); + Value geValue = + rewriter.create(loc, cmpFOp.getLt(), constantOne); + Value out = rewriter.create(loc, geValue, ordered); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::OLT: { + Value ordered = rewriter.create(loc, unordered, constantOne); + Value out = rewriter.create(loc, cmpFOp.getLt(), ordered); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::OLE: { + Value ordered = rewriter.create(loc, unordered, constantOne); + Value leValue = + rewriter.create(loc, cmpFOp.getGt(), constantOne); + Value out = rewriter.create(loc, leValue, ordered); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::ONE: { + Value ordered = rewriter.create(loc, unordered, constantOne); + Value neValue = + rewriter.create(loc, cmpFOp.getEq(), constantOne); + Value out = rewriter.create(loc, neValue, ordered); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::ORD: { + Value out = rewriter.create(loc, unordered, constantOne); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::UEQ: { + Value out = rewriter.create(loc, unordered, cmpFOp.getEq()); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::UGT: { + Value out = rewriter.create(loc, unordered, cmpFOp.getGt()); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::UGE: { + Value geValue = + rewriter.create(loc, cmpFOp.getLt(), constantOne); + Value out = rewriter.create(loc, unordered, geValue); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::ULT: { + Value out = rewriter.create(loc, unordered, cmpFOp.getLt()); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::ULE: { + Value leValue = + rewriter.create(loc, cmpFOp.getGt(), constantOne); + Value out = rewriter.create(loc, unordered, leValue); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::UNE: { + Value neValue = + rewriter.create(loc, cmpFOp.getEq(), constantOne); + Value out = rewriter.create(loc, unordered, neValue); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::UNO: { + Value out = unordered; + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::AlwaysTrue: { + Value out = constantOne; + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + case CmpFPredicate::AlwaysFalse: { + Value out = createConstant(loc, rewriter, getComponent(), 1, 0); + return buildLibraryBinaryPipeOp(rewriter, cmpf, + cmpFOp, out); + } + } + return failure(); +} + template static LogicalResult buildAllocOp(ComponentLoweringState &componentState, PatternRewriter &rewriter, TAllocOp allocOp) { @@ -2113,7 +2232,7 @@ class SCFToCalyxPass : public circt::impl::SCFToCalyxBase { ShRSIOp, AndIOp, XOrIOp, OrIOp, ExtUIOp, TruncIOp, CondBranchOp, BranchOp, MulIOp, DivUIOp, DivSIOp, RemUIOp, RemSIOp, ReturnOp, arith::ConstantOp, IndexCastOp, FuncOp, - ExtSIOp, CallOp, AddFOp, MulFOp>(); + ExtSIOp, CallOp, AddFOp, MulFOp, CmpFOp>(); RewritePatternSet legalizePatterns(&getContext()); legalizePatterns.add(&getContext()); diff --git a/lib/Dialect/Calyx/CalyxOps.cpp b/lib/Dialect/Calyx/CalyxOps.cpp index a1c7fab279fe..7ae18c59da69 100644 --- a/lib/Dialect/Calyx/CalyxOps.cpp +++ b/lib/Dialect/Calyx/CalyxOps.cpp @@ -1209,10 +1209,16 @@ FloatingPointStandard MulFOpIEEE754::getFloatingPointStandard() { return FloatingPointStandard::IEEE754; } +FloatingPointStandard CompareFOpIEEE754::getFloatingPointStandard() { + return FloatingPointStandard::IEEE754; +} + std::string AddFOpIEEE754::getCalyxLibraryName() { return "std_addFN"; } std::string MulFOpIEEE754::getCalyxLibraryName() { return "std_mulFN"; } +std::string CompareFOpIEEE754::getCalyxLibraryName() { return "std_compareFN"; } + //===----------------------------------------------------------------------===// // GroupInterface //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index 878eb882addf..7e87b91bebb3 100644 --- a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp +++ b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp @@ -673,8 +673,8 @@ void InlineCombGroups::recurseInlineCombGroups( hw::ConstantOp, mlir::arith::ConstantOp, calyx::MultPipeLibOp, calyx::DivUPipeLibOp, calyx::DivSPipeLibOp, calyx::RemSPipeLibOp, calyx::RemUPipeLibOp, mlir::scf::WhileOp, calyx::InstanceOp, - calyx::ConstantOp, calyx::AddFOpIEEE754, calyx::MulFOpIEEE754>( - src.getDefiningOp())) + calyx::ConstantOp, calyx::AddFOpIEEE754, calyx::MulFOpIEEE754, + calyx::CompareFOpIEEE754>(src.getDefiningOp())) continue; auto srcCombGroup = dyn_cast( diff --git a/test/Conversion/SCFToCalyx/convert_simple.mlir b/test/Conversion/SCFToCalyx/convert_simple.mlir index fd0b363263d5..3051916d03fd 100644 --- a/test/Conversion/SCFToCalyx/convert_simple.mlir +++ b/test/Conversion/SCFToCalyx/convert_simple.mlir @@ -322,6 +322,76 @@ module { // ----- +// Test floating point OEQ + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %0 = arith.xori %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: %1 = arith.andi %0, %std_compareFN_0.eq : i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK-DAG: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %1 : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } {toplevel} +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf oeq, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UGE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %0 = arith.xori %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: %1 = arith.ori %std_compareFN_0.unordered, %0 : i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK: calyx.wires { +// CHECK-CHECK: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK-CHECK: calyx.group @bb0_0 { +// CHECK-CHECK: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-CHECK: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-CHECK: calyx.assign %cmpf_0_reg.in = %1 : i1 +// CHECK-CHECK: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-CHECK: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-CHECK: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-CHECK: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-CHECK: } +// CHECK-CHECK: } {toplevel} +// CHECK-CHECK: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf uge, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + // Test parallel op lowering // CHECK: calyx.wires { From 68d2383f3ba5d7969a25e2deed8f63e3cf132155 Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 20 Nov 2024 19:09:29 -0500 Subject: [PATCH 02/14] realize that i should not create arith ops --- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 39 ++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index ebd280e00faf..82dd3d559ca9 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -306,6 +306,7 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern { : WalkResult::interrupt(); }); + getState().getComponentOp().dump(); return success(opBuiltSuccessfully); } @@ -811,9 +812,41 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, cmpFOp, out); } case CmpFPredicate::ULT: { - Value out = rewriter.create(loc, unordered, cmpFOp.getLt()); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + SmallVector types{one, one, one}; + + calyx::ComponentOp componentOp = + getState().getComponentOp(); + SmallVector groupIdentifier = { + "compute", getState().getUniqueName("compare"), + "out"}; + auto groupOp = calyx::createGroup( + rewriter, componentOp, loc, llvm::join(groupIdentifier, "_")); + rewriter.setInsertionPointToEnd(groupOp.getBodyBlock()); + + auto calyxOp = + getState() + .getNewLibraryOpInstance(rewriter, loc, types); + rewriter.create(loc, calyxOp.getLeft(), unordered); + rewriter.create(loc, calyxOp.getRight(), cmpFOp.getLt()); + + auto directions = calyxOp.portDirections(); + SmallVector opInputPorts; + Value opOutputPort; + for (auto dir : enumerate(directions)) { + switch (dir.value()) { + case calyx::Direction::Input: { + opInputPorts.push_back(calyxOp.getResult(dir.index())); + break; + } + case calyx::Direction::Output: { + opOutputPort = calyxOp.getResult(dir.index()); + break; + } + } + } + + return buildLibraryBinaryPipeOp( + rewriter, cmpf, cmpFOp, opOutputPort); } case CmpFPredicate::ULE: { Value leValue = From 5542cb48a13abef2d7c2a3391c7245bea494e0ab Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Thu, 21 Nov 2024 11:46:23 -0500 Subject: [PATCH 03/14] oge and ult --- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 265 +++++++++++++++++------ 1 file changed, 197 insertions(+), 68 deletions(-) diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index 82dd3d559ca9..11baa2b08472 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -306,7 +306,6 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern { : WalkResult::interrupt(); }); - getState().getComponentOp().dump(); return success(opBuiltSuccessfully); } @@ -737,145 +736,275 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, IntegerType one = rewriter.getI1Type(), five = rewriter.getIntegerType(5), width = rewriter.getIntegerType( cmpf.getLhs().getType().getIntOrFloatBitWidth()); - auto cmpFOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, - {one, one, one, width, width, one, one, one, one, one, - five, one}); + auto calyxCmpFOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, + {one, one, one, width, width, one, one, one, one, + one, five, one}); hw::ConstantOp constantOne = createConstant(loc, rewriter, getComponent(), 1, 1); - Value unordered = cmpFOp.getUnordered(); + Value unordered = calyxCmpFOp.getUnordered(); rewriter.setInsertionPointToStart(getComponent().getBodyBlock()); + switch (cmpf.getPredicate()) { case CmpFPredicate::OEQ: { Value ordered = rewriter.create(loc, unordered, constantOne); - Value out = rewriter.create(loc, ordered, cmpFOp.getEq()); + Value out = + rewriter.create(loc, ordered, calyxCmpFOp.getEq()); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::OGT: { Value ordered = rewriter.create(loc, unordered, constantOne); - Value out = rewriter.create(loc, ordered, cmpFOp.getGt()); + Value out = + rewriter.create(loc, ordered, calyxCmpFOp.getGt()); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::OGE: { - Value ordered = rewriter.create(loc, unordered, constantOne); - Value geValue = - rewriter.create(loc, cmpFOp.getLt(), constantOne); - Value out = rewriter.create(loc, geValue, ordered); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", opName, "port"}; + auto geReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, geReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, geReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getLt(), builder)); + + SmallVector unorderedPortIdentifier = {"unordered", opName, + "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + SmallVector outputAndLibOpTypes{one, one, one}; + auto outputAndLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputAndLibOpTypes); + rewriter.create(loc, outputAndLibOp.getLeft(), + geReg.getOut()); + rewriter.create(loc, outputAndLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputAndLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneAndLibOpTypes{one, one, one}; + auto doneAndLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneAndLibOpTypes); + rewriter.create(loc, doneAndLibOp.getLeft(), + geReg.getDone()); + rewriter.create(loc, doneAndLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), + doneAndLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputAndLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); } case CmpFPredicate::OLT: { Value ordered = rewriter.create(loc, unordered, constantOne); - Value out = rewriter.create(loc, cmpFOp.getLt(), ordered); + Value out = + rewriter.create(loc, calyxCmpFOp.getLt(), ordered); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::OLE: { Value ordered = rewriter.create(loc, unordered, constantOne); Value leValue = - rewriter.create(loc, cmpFOp.getGt(), constantOne); + rewriter.create(loc, calyxCmpFOp.getGt(), constantOne); Value out = rewriter.create(loc, leValue, ordered); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::ONE: { Value ordered = rewriter.create(loc, unordered, constantOne); Value neValue = - rewriter.create(loc, cmpFOp.getEq(), constantOne); + rewriter.create(loc, calyxCmpFOp.getEq(), constantOne); Value out = rewriter.create(loc, neValue, ordered); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::ORD: { Value out = rewriter.create(loc, unordered, constantOne); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::UEQ: { - Value out = rewriter.create(loc, unordered, cmpFOp.getEq()); + Value out = + rewriter.create(loc, unordered, calyxCmpFOp.getEq()); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::UGT: { - Value out = rewriter.create(loc, unordered, cmpFOp.getGt()); + Value out = + rewriter.create(loc, unordered, calyxCmpFOp.getGt()); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::UGE: { Value geValue = - rewriter.create(loc, cmpFOp.getLt(), constantOne); + rewriter.create(loc, calyxCmpFOp.getLt(), constantOne); Value out = rewriter.create(loc, unordered, geValue); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::ULT: { - SmallVector types{one, one, one}; + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); - calyx::ComponentOp componentOp = - getState().getComponentOp(); - SmallVector groupIdentifier = { - "compute", getState().getUniqueName("compare"), - "out"}; - auto groupOp = calyx::createGroup( - rewriter, componentOp, loc, llvm::join(groupIdentifier, "_")); - rewriter.setInsertionPointToEnd(groupOp.getBodyBlock()); + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); - auto calyxOp = - getState() - .getNewLibraryOpInstance(rewriter, loc, types); - rewriter.create(loc, calyxOp.getLeft(), unordered); - rewriter.create(loc, calyxOp.getRight(), cmpFOp.getLt()); + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + SmallVector cmpPortIdentifier = {"compare", opName, "port"}; + auto ltReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, ltReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, ltReg.getIn(), calyxCmpFOp.getLt()); + + SmallVector unorderedPortIdentifier = {"unordered", opName, + "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), unordered); + + SmallVector orLibOpTypes{one, one, one}; + auto orLibOp = getState() + .getNewLibraryOpInstance(rewriter, loc, + orLibOpTypes); + rewriter.create(loc, orLibOp.getLeft(), ltReg.getOut()); + rewriter.create(loc, orLibOp.getRight(), + unorderedReg.getOut()); - auto directions = calyxOp.portDirections(); - SmallVector opInputPorts; - Value opOutputPort; - for (auto dir : enumerate(directions)) { - switch (dir.value()) { - case calyx::Direction::Input: { - opInputPorts.push_back(calyxOp.getResult(dir.index())); - break; - } - case calyx::Direction::Output: { - opOutputPort = calyxOp.getResult(dir.index()); - break; - } - } - } + // Write the output to this register. + rewriter.create(loc, reg.getIn(), orLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector andLibOpTypes{one, one, one}; + auto andLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, andLibOpTypes); + rewriter.create(loc, andLibOp.getLeft(), ltReg.getDone()); + rewriter.create(loc, andLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), andLibOp.getOut()); - return buildLibraryBinaryPipeOp( - rewriter, cmpf, cmpFOp, opOutputPort); + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup(orLibOp.getOut(), + group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); } case CmpFPredicate::ULE: { Value leValue = - rewriter.create(loc, cmpFOp.getGt(), constantOne); + rewriter.create(loc, calyxCmpFOp.getGt(), constantOne); Value out = rewriter.create(loc, unordered, leValue); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::UNE: { Value neValue = - rewriter.create(loc, cmpFOp.getEq(), constantOne); + rewriter.create(loc, calyxCmpFOp.getEq(), constantOne); Value out = rewriter.create(loc, unordered, neValue); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::UNO: { Value out = unordered; return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::AlwaysTrue: { Value out = constantOne; return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } case CmpFPredicate::AlwaysFalse: { Value out = createConstant(loc, rewriter, getComponent(), 1, 0); return buildLibraryBinaryPipeOp(rewriter, cmpf, - cmpFOp, out); + calyxCmpFOp, out); } } return failure(); From ed60f77583be413fa857b999132df644c872eded Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Thu, 21 Nov 2024 17:15:12 -0500 Subject: [PATCH 04/14] big chunk of duplication code; test cases --- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 1146 +++++++++++++++-- .../Conversion/SCFToCalyx/convert_simple.mlir | 774 ++++++++++- 2 files changed, 1719 insertions(+), 201 deletions(-) diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index 11baa2b08472..2058042c3908 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -732,6 +732,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, CmpFOp cmpf) const { + Location loc = cmpf.getLoc(); IntegerType one = rewriter.getI1Type(), five = rewriter.getIntegerType(5), width = rewriter.getIntegerType( @@ -748,18 +749,174 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, switch (cmpf.getPredicate()) { case CmpFPredicate::OEQ: { - Value ordered = rewriter.create(loc, unordered, constantOne); - Value out = - rewriter.create(loc, ordered, calyxCmpFOp.getEq()); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, compareReg.getIn(), c1, + calyxCmpFOp.getEq()); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); } case CmpFPredicate::OGT: { - Value ordered = rewriter.create(loc, unordered, constantOne); - Value out = - rewriter.create(loc, ordered, calyxCmpFOp.getGt()); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, compareReg.getIn(), c1, + calyxCmpFOp.getGt()); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); } case CmpFPredicate::OGE: { StringRef opName = cmpf.getOperationName().split(".").second; @@ -779,19 +936,18 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, cmpf.getRhs()); hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", opName, "port"}; - auto geReg = + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = createRegister(loc, rewriter, getComponent(), 1, getState().getUniqueName( llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, geReg.getWriteEn(), + rewriter.create(loc, compareReg.getWriteEn(), calyxCmpFOp.getDone()); rewriter.create( - loc, geReg.getIn(), c1, + loc, compareReg.getIn(), c1, comb::createOrFoldNot(loc, calyxCmpFOp.getLt(), builder)); - SmallVector unorderedPortIdentifier = {"unordered", opName, - "port"}; + SmallVector unorderedPortIdentifier = {"unordered", "port"}; auto unorderedReg = createRegister(loc, rewriter, getComponent(), 1, getState().getUniqueName( @@ -802,17 +958,17 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, loc, unorderedReg.getIn(), c1, comb::createOrFoldNot(loc, unordered, builder)); - SmallVector outputAndLibOpTypes{one, one, one}; - auto outputAndLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputAndLibOpTypes); - rewriter.create(loc, outputAndLibOp.getLeft(), - geReg.getOut()); - rewriter.create(loc, outputAndLibOp.getRight(), + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), unorderedReg.getOut()); // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputAndLibOp.getOut()); + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); // The write enable port is high when the pipeline is done. rewriter.create(loc, reg.getWriteEn(), calyxCmpFOp.getDone()); @@ -823,17 +979,16 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, loc, calyxCmpFOp.getGo(), c1, comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); // The group is done when the register write is complete. - SmallVector doneAndLibOpTypes{one, one, one}; - auto doneAndLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneAndLibOpTypes); - rewriter.create(loc, doneAndLibOp.getLeft(), - geReg.getDone()); - rewriter.create(loc, doneAndLibOp.getRight(), + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), unorderedReg.getDone()); - rewriter.create(loc, reg.getDone(), - doneAndLibOp.getOut()); + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); // Pass the result from the source operation to register holding the resullt // from the Calyx primitive. @@ -841,7 +996,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, // Register the values for the pipeline. getState().registerEvaluatingGroup( - outputAndLibOp.getOut(), group); + outputLibOp.getOut(), group); getState().registerEvaluatingGroup( calyxCmpFOp.getLeft(), group); getState().registerEvaluatingGroup( @@ -850,53 +1005,91 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, return success(); } case CmpFPredicate::OLT: { - Value ordered = rewriter.create(loc, unordered, constantOne); - Value out = - rewriter.create(loc, calyxCmpFOp.getLt(), ordered); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, compareReg.getIn(), c1, + calyxCmpFOp.getLt()); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); } case CmpFPredicate::OLE: { - Value ordered = rewriter.create(loc, unordered, constantOne); - Value leValue = - rewriter.create(loc, calyxCmpFOp.getGt(), constantOne); - Value out = rewriter.create(loc, leValue, ordered); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::ONE: { - Value ordered = rewriter.create(loc, unordered, constantOne); - Value neValue = - rewriter.create(loc, calyxCmpFOp.getEq(), constantOne); - Value out = rewriter.create(loc, neValue, ordered); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::ORD: { - Value out = rewriter.create(loc, unordered, constantOne); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::UEQ: { - Value out = - rewriter.create(loc, unordered, calyxCmpFOp.getEq()); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::UGT: { - Value out = - rewriter.create(loc, unordered, calyxCmpFOp.getGt()); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::UGE: { - Value geValue = - rewriter.create(loc, calyxCmpFOp.getLt(), constantOne); - Value out = rewriter.create(loc, unordered, geValue); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::ULT: { StringRef opName = cmpf.getOperationName().split(".").second; auto reg = createRegister( loc, rewriter, getComponent(), 1, @@ -913,63 +1106,68 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, rewriter.create(loc, calyxCmpFOp.getRight(), cmpf.getRhs()); - SmallVector cmpPortIdentifier = {"compare", opName, "port"}; - auto ltReg = + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = createRegister(loc, rewriter, getComponent(), 1, getState().getUniqueName( llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, ltReg.getWriteEn(), + rewriter.create(loc, compareReg.getWriteEn(), calyxCmpFOp.getDone()); - rewriter.create(loc, ltReg.getIn(), calyxCmpFOp.getLt()); + rewriter.create( + loc, compareReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getGt(), builder)); - SmallVector unorderedPortIdentifier = {"unordered", opName, - "port"}; + SmallVector unorderedPortIdentifier = {"unordered", "port"}; auto unorderedReg = createRegister(loc, rewriter, getComponent(), 1, getState().getUniqueName( llvm::join(unorderedPortIdentifier, "_"))); rewriter.create(loc, unorderedReg.getWriteEn(), calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), unordered); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); - SmallVector orLibOpTypes{one, one, one}; - auto orLibOp = getState() - .getNewLibraryOpInstance(rewriter, loc, - orLibOpTypes); - rewriter.create(loc, orLibOp.getLeft(), ltReg.getOut()); - rewriter.create(loc, orLibOp.getRight(), + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), unorderedReg.getOut()); // Write the output to this register. - rewriter.create(loc, reg.getIn(), orLibOp.getOut()); + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); // The write enable port is high when the pipeline is done. rewriter.create(loc, reg.getWriteEn(), calyxCmpFOp.getDone()); // Set pipelineOp to high as long as its done signal is not high. // This prevents the pipelineOP from executing for the cycle that we write // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); rewriter.create( loc, calyxCmpFOp.getGo(), c1, comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); // The group is done when the register write is complete. - SmallVector andLibOpTypes{one, one, one}; - auto andLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, andLibOpTypes); - rewriter.create(loc, andLibOp.getLeft(), ltReg.getDone()); - rewriter.create(loc, andLibOp.getRight(), + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), unorderedReg.getDone()); - rewriter.create(loc, reg.getDone(), andLibOp.getOut()); + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); // Pass the result from the source operation to register holding the resullt // from the Calyx primitive. cmpf.getResult().replaceAllUsesWith(reg.getOut()); // Register the values for the pipeline. - getState().registerEvaluatingGroup(orLibOp.getOut(), - group); + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); getState().registerEvaluatingGroup( calyxCmpFOp.getLeft(), group); getState().registerEvaluatingGroup( @@ -977,34 +1175,720 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, return success(); } - case CmpFPredicate::ULE: { - Value leValue = - rewriter.create(loc, calyxCmpFOp.getGt(), constantOne); - Value out = rewriter.create(loc, unordered, leValue); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::UNE: { - Value neValue = - rewriter.create(loc, calyxCmpFOp.getEq(), constantOne); - Value out = rewriter.create(loc, unordered, neValue); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::UNO: { - Value out = unordered; - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::AlwaysTrue: { - Value out = constantOne; - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); - } - case CmpFPredicate::AlwaysFalse: { - Value out = createConstant(loc, rewriter, getComponent(), 1, 0); - return buildLibraryBinaryPipeOp(rewriter, cmpf, - calyxCmpFOp, out); + case CmpFPredicate::ONE: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, compareReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getEq(), builder)); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::ORD: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), unorderedReg.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + rewriter.create(loc, reg.getDone(), + unorderedReg.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + unorderedReg.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::UEQ: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, compareReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getEq(), builder)); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, unorderedReg.getIn(), c1, + comb::createOrFoldNot(loc, unordered, builder)); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::UGT: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, compareReg.getIn(), + calyxCmpFOp.getGt()); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), unordered); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::UGE: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, compareReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getLt(), builder)); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), unordered); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::ULT: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, compareReg.getIn(), + calyxCmpFOp.getLt()); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), unordered); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::ULE: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, compareReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getGt(), builder)); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), unordered); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::UNE: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + SmallVector cmpPortIdentifier = {"compare", "port"}; + auto compareReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(cmpPortIdentifier, "_"))); + rewriter.create(loc, compareReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create( + loc, compareReg.getIn(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getEq(), builder)); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), unordered); + + SmallVector outputLibOpTypes{one, one, one}; + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, outputLibOpTypes); + rewriter.create(loc, outputLibOp.getLeft(), + compareReg.getOut()); + rewriter.create(loc, outputLibOp.getRight(), + unorderedReg.getOut()); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + SmallVector doneLibOpTypes{one, one, one}; + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, doneLibOpTypes); + rewriter.create(loc, doneLibOp.getLeft(), + compareReg.getDone()); + rewriter.create(loc, doneLibOp.getRight(), + unorderedReg.getDone()); + + rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + outputLibOp.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::UNO: { + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = createRegister( + loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); + + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); + + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), + cmpf.getRhs()); + + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + + SmallVector unorderedPortIdentifier = {"unordered", "port"}; + auto unorderedReg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName( + llvm::join(unorderedPortIdentifier, "_"))); + rewriter.create(loc, unorderedReg.getWriteEn(), + calyxCmpFOp.getDone()); + rewriter.create(loc, unorderedReg.getIn(), c1, unordered); + + // Write the output to this register. + rewriter.create(loc, reg.getIn(), unorderedReg.getOut()); + // The write enable port is high when the pipeline is done. + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + // Set pipelineOp to high as long as its done signal is not high. + // This prevents the pipelineOP from executing for the cycle that we write + // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); + // The group is done when the register write is complete. + rewriter.create(loc, reg.getDone(), + unorderedReg.getOut()); + + // Pass the result from the source operation to register holding the resullt + // from the Calyx primitive. + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register the values for the pipeline. + getState().registerEvaluatingGroup( + unorderedReg.getOut(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); + } + case CmpFPredicate::AlwaysTrue: { + cmpf.getResult().replaceAllUsesWith(constantOne); + return success(); + } + case CmpFPredicate::AlwaysFalse: { + Value constantZero = createConstant(loc, rewriter, getComponent(), 1, 0); + cmpf.getResult().replaceAllUsesWith(constantZero); + return success(); } } return failure(); diff --git a/test/Conversion/SCFToCalyx/convert_simple.mlir b/test/Conversion/SCFToCalyx/convert_simple.mlir index 3051916d03fd..1f0887baa740 100644 --- a/test/Conversion/SCFToCalyx/convert_simple.mlir +++ b/test/Conversion/SCFToCalyx/convert_simple.mlir @@ -322,76 +322,6 @@ module { // ----- -// Test floating point OEQ - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %0 = arith.xori %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: %1 = arith.andi %0, %std_compareFN_0.eq : i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK-DAG: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %1 : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } {toplevel} -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf oeq, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point UGE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %0 = arith.xori %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: %1 = arith.ori %std_compareFN_0.unordered, %0 : i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK: calyx.wires { -// CHECK-CHECK: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK-CHECK: calyx.group @bb0_0 { -// CHECK-CHECK: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-CHECK: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-CHECK: calyx.assign %cmpf_0_reg.in = %1 : i1 -// CHECK-CHECK: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-CHECK: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-CHECK: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-CHECK: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-CHECK: } -// CHECK-CHECK: } {toplevel} -// CHECK-CHECK: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf uge, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - // Test parallel op lowering // CHECK: calyx.wires { @@ -508,3 +438,707 @@ module { } } +// ----- + +// Test floating point OEQ + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf oeq, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OGT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ogt, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OGE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf oge, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OLT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf olt, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OLE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ole, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ONE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf one, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ORD + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %unordered_port_0_reg.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ord, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UEQ + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ueq, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UGT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ugt, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UGE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf uge, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ULT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ult, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ULE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ule, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UNE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf une, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UNO + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered ? %true : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %unordered_port_0_reg.out ? %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf uno, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point AlwaysTrue + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %true : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf true, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point AlwaysFalse + + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %false : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf false, %arg0, %0 : f32 + + return %1 : i1 + } +} From 5f891a766749a5963c749e665b828a2a67373d3d Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Fri, 22 Nov 2024 13:11:29 -0500 Subject: [PATCH 05/14] using predicate info to refactor --- .../circt/Dialect/Calyx/CalyxLoweringUtils.h | 20 + lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 1253 ++--------------- .../Calyx/Transforms/CalyxLoweringUtils.cpp | 108 ++ .../Conversion/SCFToCalyx/convert_simple.mlir | 482 ++++--- 4 files changed, 492 insertions(+), 1371 deletions(-) diff --git a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h index f94227efbd35..cea5bd279c20 100644 --- a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h +++ b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h @@ -779,6 +779,26 @@ class BuildCallInstance : public calyx::FuncOpPartialLoweringPattern { ComponentOp getCallComponent(mlir::func::CallOp callOp) const; }; +/// Predicate information for the floating point comparisons +struct PredicateInfo { + struct InputPorts { + // Relevant ports to extract from the `std_compareFN`. For example, we + // extract the `lt` and the `unordered` ports when the predicate is `oge`. + enum Port { EQ, GT, LT, UNORDERED } port; + // Whether we should invert the port before passing as inputs to the `op` + // field. For example, we should invert both the `lt` and the `unordered` + // port just extracted for predicate `oge`. + bool invert; + }; + + // The combinational logic to apply to the input ports. For example, we should + // apply `AND` logic to the two input ports for predicate `oge`. + enum CombLogic { AND, OR, SPECIAL } logic; + SmallVector inputPorts; +}; + +PredicateInfo getPredicateInfo(mlir::arith::CmpFPredicate pred); + } // namespace calyx } // namespace circt diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index 2058042c3908..f2759e046ae4 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -30,6 +30,7 @@ #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/LogicalResult.h" +#include "llvm/Support/raw_ostream.h" #include @@ -732,7 +733,6 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, CmpFOp cmpf) const { - Location loc = cmpf.getLoc(); IntegerType one = rewriter.getI1Type(), five = rewriter.getIntegerType(5), width = rewriter.getIntegerType( @@ -742,1156 +742,151 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, rewriter, loc, {one, one, one, width, width, one, one, one, one, one, five, one}); - hw::ConstantOp constantOne = - createConstant(loc, rewriter, getComponent(), 1, 1); - Value unordered = calyxCmpFOp.getUnordered(); + hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); rewriter.setInsertionPointToStart(getComponent().getBodyBlock()); - switch (cmpf.getPredicate()) { - case CmpFPredicate::OEQ: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, compareReg.getIn(), c1, - calyxCmpFOp.getEq()); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::OGT: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, compareReg.getIn(), c1, - calyxCmpFOp.getGt()); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::OGE: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getLt(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::OLT: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, compareReg.getIn(), c1, - calyxCmpFOp.getLt()); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::OLE: { - StringRef opName = cmpf.getOperationName().split(".").second; + auto createSignalRegister = + [&](Value signal, bool invert, StringRef nameSuffix, Location loc, + PatternRewriter &rewriter, calyx::ComponentOp component, + calyx::CompareFOpIEEE754 calyxCmpFOp, calyx::GroupOp group, + OpBuilder &builder) -> calyx::RegisterOp { auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getGt(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. + loc, rewriter, component, 1, + getState().getUniqueName(nameSuffix)); rewriter.create(loc, reg.getWriteEn(), calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); + if (invert) + rewriter.create( + loc, reg.getIn(), c1, comb::createOrFoldNot(loc, signal, builder)); + else + rewriter.create(loc, reg.getIn(), signal); + return reg; + }; - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); + using calyx::PredicateInfo; + PredicateInfo info = calyx::getPredicateInfo(cmpf.getPredicate()); + if (info.logic == PredicateInfo::SPECIAL) { + if (cmpf.getPredicate() == CmpFPredicate::AlwaysTrue) { + cmpf.getResult().replaceAllUsesWith(c1); + return success(); + } - return success(); + if (cmpf.getPredicate() == CmpFPredicate::AlwaysFalse) { + Value constantZero = createConstant(loc, rewriter, getComponent(), 1, 0); + cmpf.getResult().replaceAllUsesWith(constantZero); + return success(); + } } - case CmpFPredicate::ONE: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); + // General case + StringRef opName = cmpf.getOperationName().split(".").second; + auto reg = + createRegister(loc, rewriter, getComponent(), 1, + getState().getUniqueName(opName)); - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); + // Operation pipelines are not combinational, so a GroupOp is required. + auto group = createGroupForOp(rewriter, cmpf); + OpBuilder builder(group->getRegion(0)); + getState().addBlockScheduleable(cmpf->getBlock(), + group); - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getEq(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); + rewriter.setInsertionPointToEnd(group.getBodyBlock()); + rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); + rewriter.create(loc, calyxCmpFOp.getRight(), cmpf.getRhs()); + + // Prepare signals and create registers + SmallVector inputRegs; + for (const auto &input : info.inputPorts) { + Value signal; + switch (input.port) { + case PredicateInfo::InputPorts::Port::EQ: { + signal = calyxCmpFOp.getEq(); + break; + } + case PredicateInfo::InputPorts::Port::GT: { + signal = calyxCmpFOp.getGt(); + break; + } + case PredicateInfo::InputPorts::Port::LT: { + signal = calyxCmpFOp.getLt(); + break; + } + case PredicateInfo::InputPorts::Port::UNORDERED: { + signal = calyxCmpFOp.getUnordered(); + break; + } + } + std::string nameSuffix = + (input.port == PredicateInfo::InputPorts::Port::UNORDERED) + ? "unordered_port" + : "compare_port"; + auto signalReg = + createSignalRegister(signal, input.invert, nameSuffix, loc, rewriter, + getComponent(), calyxCmpFOp, group, builder); + inputRegs.push_back(signalReg); + } + + // Create the output logical operation + Value outputValue, doneValue; + if (info.logic == PredicateInfo::SPECIAL) { + // it's guaranteed to be either ORD or UNO + outputValue = inputRegs[0].getOut(); + doneValue = inputRegs[0].getOut(); + } else { + if (info.logic == PredicateInfo::AND) { + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one, one}); + rewriter.create(loc, outputLibOp.getLeft(), + inputRegs[0].getOut()); + rewriter.create(loc, outputLibOp.getRight(), + inputRegs[1].getOut()); + + outputValue = outputLibOp.getOut(); + } else /*info.op == PredicateInfo::OR*/ { + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one, one}); + rewriter.create(loc, outputLibOp.getLeft(), + inputRegs[0].getOut()); + rewriter.create(loc, outputLibOp.getRight(), + inputRegs[1].getOut()); + + outputValue = outputLibOp.getOut(); + } - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; auto doneLibOp = getState() .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); + rewriter, loc, {one, one, one}); rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); + inputRegs[0].getDone()); rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); + inputRegs[1].getDone()); + doneValue = doneLibOp.getOut(); } - case CmpFPredicate::ORD: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); + // Write to the output register + rewriter.create(loc, reg.getIn(), outputValue); + rewriter.create(loc, reg.getWriteEn(), doneValue); - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); + // Set the go and done signal + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getDone(), builder)); + rewriter.create(loc, reg.getDone()); - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); + cmpf.getResult().replaceAllUsesWith(reg.getOut()); - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); + // Register evaluating groups + getState().registerEvaluatingGroup(outputValue, + group); + getState().registerEvaluatingGroup(doneValue, group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); - // Write the output to this register. - rewriter.create(loc, reg.getIn(), unorderedReg.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - rewriter.create(loc, reg.getDone(), - unorderedReg.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - unorderedReg.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::UEQ: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getEq(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, unorderedReg.getIn(), c1, - comb::createOrFoldNot(loc, unordered, builder)); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::UGT: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, compareReg.getIn(), - calyxCmpFOp.getGt()); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), unordered); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::UGE: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getLt(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), unordered); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::ULT: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, compareReg.getIn(), - calyxCmpFOp.getLt()); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), unordered); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::ULE: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getGt(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), unordered); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::UNE: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - SmallVector cmpPortIdentifier = {"compare", "port"}; - auto compareReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(cmpPortIdentifier, "_"))); - rewriter.create(loc, compareReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create( - loc, compareReg.getIn(), c1, - comb::createOrFoldNot(loc, calyxCmpFOp.getEq(), builder)); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), unordered); - - SmallVector outputLibOpTypes{one, one, one}; - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, outputLibOpTypes); - rewriter.create(loc, outputLibOp.getLeft(), - compareReg.getOut()); - rewriter.create(loc, outputLibOp.getRight(), - unorderedReg.getOut()); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), outputLibOp.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - SmallVector doneLibOpTypes{one, one, one}; - auto doneLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, doneLibOpTypes); - rewriter.create(loc, doneLibOp.getLeft(), - compareReg.getDone()); - rewriter.create(loc, doneLibOp.getRight(), - unorderedReg.getDone()); - - rewriter.create(loc, reg.getDone(), doneLibOp.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - outputLibOp.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::UNO: { - StringRef opName = cmpf.getOperationName().split(".").second; - auto reg = createRegister( - loc, rewriter, getComponent(), 1, - getState().getUniqueName(opName)); - - // Operation pipelines are not combinational, so a GroupOp is required. - auto group = createGroupForOp(rewriter, cmpf); - OpBuilder builder(group->getRegion(0)); - getState().addBlockScheduleable(cmpf->getBlock(), - group); - - rewriter.setInsertionPointToEnd(group.getBodyBlock()); - rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); - rewriter.create(loc, calyxCmpFOp.getRight(), - cmpf.getRhs()); - - hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); - - SmallVector unorderedPortIdentifier = {"unordered", "port"}; - auto unorderedReg = - createRegister(loc, rewriter, getComponent(), 1, - getState().getUniqueName( - llvm::join(unorderedPortIdentifier, "_"))); - rewriter.create(loc, unorderedReg.getWriteEn(), - calyxCmpFOp.getDone()); - rewriter.create(loc, unorderedReg.getIn(), c1, unordered); - - // Write the output to this register. - rewriter.create(loc, reg.getIn(), unorderedReg.getOut()); - // The write enable port is high when the pipeline is done. - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - // Set pipelineOp to high as long as its done signal is not high. - // This prevents the pipelineOP from executing for the cycle that we write - // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done - rewriter.create( - loc, calyxCmpFOp.getGo(), c1, - comb::createOrFoldNot(group.getLoc(), calyxCmpFOp.getDone(), builder)); - // The group is done when the register write is complete. - rewriter.create(loc, reg.getDone(), - unorderedReg.getOut()); - - // Pass the result from the source operation to register holding the resullt - // from the Calyx primitive. - cmpf.getResult().replaceAllUsesWith(reg.getOut()); - - // Register the values for the pipeline. - getState().registerEvaluatingGroup( - unorderedReg.getOut(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getLeft(), group); - getState().registerEvaluatingGroup( - calyxCmpFOp.getRight(), group); - - return success(); - } - case CmpFPredicate::AlwaysTrue: { - cmpf.getResult().replaceAllUsesWith(constantOne); - return success(); - } - case CmpFPredicate::AlwaysFalse: { - Value constantZero = createConstant(loc, rewriter, getComponent(), 1, 0); - cmpf.getResult().replaceAllUsesWith(constantZero); - return success(); - } - } - return failure(); + return success(); } template diff --git a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index 7e87b91bebb3..1e1e5db2327d 100644 --- a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp +++ b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp @@ -843,5 +843,113 @@ BuildCallInstance::getCallComponent(mlir::func::CallOp callOp) const { return nullptr; } +PredicateInfo getPredicateInfo(CmpFPredicate pred) { + PredicateInfo info; + switch (pred) { + case CmpFPredicate::OEQ: { + info.logic = PredicateInfo::AND; + info.inputPorts = {{PredicateInfo::InputPorts::EQ, false}, + {PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::OGT: { + info.logic = PredicateInfo::AND; + info.inputPorts = {{PredicateInfo::InputPorts::GT, false}, + {PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::OGE: { + info.logic = PredicateInfo::AND; + info.inputPorts = {{PredicateInfo::InputPorts::LT, true}, + {PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::OLT: { + info.logic = PredicateInfo::AND; + info.inputPorts = {{PredicateInfo::InputPorts::LT, false}, + {PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::OLE: { + info.logic = PredicateInfo::AND; + info.inputPorts = {{PredicateInfo::InputPorts::GT, true}, + {PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::ONE: { + info.logic = PredicateInfo::AND; + info.inputPorts = {{PredicateInfo::InputPorts::EQ, true}, + {PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::ORD: { + info.logic = PredicateInfo::SPECIAL; + info.inputPorts = {{PredicateInfo::InputPorts::UNORDERED, true}}; + break; + } + + case CmpFPredicate::UEQ: { + info.logic = PredicateInfo::OR; + info.inputPorts = {{PredicateInfo::InputPorts::EQ, false}, + {PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::UGT: { + info.logic = PredicateInfo::OR; + info.inputPorts = {{PredicateInfo::InputPorts::GT, false}, + {PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::UGE: { + info.logic = PredicateInfo::OR; + info.inputPorts = {{PredicateInfo::InputPorts::LT, true}, + {PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::ULT: { + info.logic = PredicateInfo::OR; + info.inputPorts = {{PredicateInfo::InputPorts::LT, false}, + {PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::ULE: { + info.logic = PredicateInfo::OR; + info.inputPorts = {{PredicateInfo::InputPorts::GT, true}, + {PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::UNE: { + info.logic = PredicateInfo::OR; + info.inputPorts = {{PredicateInfo::InputPorts::EQ, true}, + {PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::UNO: { + info.logic = PredicateInfo::SPECIAL; + info.inputPorts = {{PredicateInfo::InputPorts::UNORDERED, false}}; + break; + } + + case CmpFPredicate::AlwaysTrue: + case CmpFPredicate::AlwaysFalse: + info.logic = PredicateInfo::SPECIAL; + break; + } + + return info; +} + } // namespace calyx } // namespace circt diff --git a/test/Conversion/SCFToCalyx/convert_simple.mlir b/test/Conversion/SCFToCalyx/convert_simple.mlir index 1f0887baa740..93282ef068d4 100644 --- a/test/Conversion/SCFToCalyx/convert_simple.mlir +++ b/test/Conversion/SCFToCalyx/convert_simple.mlir @@ -455,24 +455,24 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { // CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 // CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 @@ -505,24 +505,24 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { // CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 // CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 @@ -556,25 +556,25 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { // CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 // CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 @@ -608,24 +608,24 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { // CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 // CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 @@ -659,25 +659,25 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { // CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 // CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 @@ -711,25 +711,25 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { // CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 // CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 @@ -760,18 +760,18 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %unordered_port_0_reg.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -790,8 +790,8 @@ module { // CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { // CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 // CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 // CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 // CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 // CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 // CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 @@ -799,25 +799,23 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_1.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -845,23 +843,23 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -889,24 +887,24 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -934,23 +932,23 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -978,24 +976,24 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -1023,24 +1021,24 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.group_done %std_and_0.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { @@ -1065,17 +1063,17 @@ module { // CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 // CHECK: calyx.wires { // CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered ? %true : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.group_done %unordered_port_0_reg.out ? %cmpf_0_reg.done : i1 -// CHECK-DAG: } +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } module { func.func @main(%arg0 : f32) -> i1 { From a94f799907826e9a2ef555bdb194261a4861ff01 Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Fri, 22 Nov 2024 14:53:41 -0500 Subject: [PATCH 06/14] emit std_compareFN --- lib/Dialect/Calyx/Export/CalyxEmitter.cpp | 11 +++- test/Dialect/Calyx/emit.mlir | 68 +++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/Calyx/Export/CalyxEmitter.cpp b/lib/Dialect/Calyx/Export/CalyxEmitter.cpp index c9cfb1ade747..7e9167981ea2 100644 --- a/lib/Dialect/Calyx/Export/CalyxEmitter.cpp +++ b/lib/Dialect/Calyx/Export/CalyxEmitter.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" #include #include @@ -157,6 +158,10 @@ struct ImportTracker { static constexpr std::string_view sFloatingPoint = "float/mulFN"; return {sFloatingPoint}; }) + .Case([&](auto op) -> FailureOr { + static constexpr std::string_view sFloatingPoint = "float/compareFN"; + return {sFloatingPoint}; + }) .Default([&](auto op) { auto diag = op->emitOpError() << "not supported for emission"; return diag; @@ -679,7 +684,7 @@ void Emitter::emitComponent(ComponentInterface op) { emitLibraryPrimTypedByFirstOutputPort( op, /*calyxLibName=*/{"std_sdiv_pipe"}); }) - .Case( + .Case( [&](auto op) { emitLibraryFloatingPoint(op); }) .Default([&](auto op) { emitOpError(op, "not supported for emission inside component"); @@ -996,8 +1001,10 @@ void Emitter::emitLibraryPrimTypedByFirstOutputPort( void Emitter::emitLibraryFloatingPoint(Operation *op) { auto cell = cast(op); + // magic number for the index of `left/right` input port + size_t inputPortIndex = cell.getInputPorts().size() - 3; unsigned bitWidth = - cell.getOutputPorts()[0].getType().getIntOrFloatBitWidth(); + cell.getInputPorts()[inputPortIndex].getType().getIntOrFloatBitWidth(); // Since Calyx interacts with HardFloat, we'll also only be using expWidth and // sigWidth. See // http://www.jhauser.us/arithmetic/HardFloat-1/doc/HardFloat-Verilog.html diff --git a/test/Dialect/Calyx/emit.mlir b/test/Dialect/Calyx/emit.mlir index 2f814b5ae84f..5cfb573ab0b0 100644 --- a/test/Dialect/Calyx/emit.mlir +++ b/test/Dialect/Calyx/emit.mlir @@ -384,3 +384,71 @@ module attributes {calyx.entrypoint = "main"} { } {toplevel} } +// ----- + +module attributes {calyx.entrypoint = "main"} { + // CHECK: import "primitives/float/compareFN.futil"; + calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { + %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 + %true = hw.constant true + %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 + %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 + %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 + %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 + %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 + // CHECK-DAG: std_compareFN_0 = std_compareFN(8, 24, 32); + %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 + %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 + calyx.wires { + calyx.assign %out0 = %ret_arg0_reg.out : i1 + // CHECK-LABEL: group bb0_0 { + // CHECK-NEXT: std_compareFN_0.left = in0; + // CHECK-NEXT: std_compareFN_0.right = cst_0.out; + // CHECK-NEXT: compare_port_0_reg.write_en = std_compareFN_0.done; + // CHECK-NEXT: compare_port_0_reg.in = std_compareFN_0.eq; + // CHECK-NEXT: unordered_port_0_reg.write_en = std_compareFN_0.done; + // CHECK-NEXT: unordered_port_0_reg.in = !std_compareFN_0.unordered ? 1'd1; + // CHECK-NEXT: std_and_0.left = compare_port_0_reg.out; + // CHECK-NEXT: std_and_0.right = unordered_port_0_reg.out; + // CHECK-NEXT: std_and_1.left = compare_port_0_reg.done; + // CHECK-NEXT: std_and_1.right = unordered_port_0_reg.done; + // CHECK-NEXT: cmpf_0_reg.in = std_and_0.out; + // CHECK-NEXT: cmpf_0_reg.write_en = std_and_1.out; + // CHECK-NEXT: std_compareFN_0.go = !std_compareFN_0.done ? 1'd1; + // CHECK-NEXT: bb0_0[done] = cmpf_0_reg.done; + // CHECK-NEXT: } + calyx.group @bb0_0 { + calyx.assign %std_compareFN_0.left = %in0 : i32 + calyx.assign %std_compareFN_0.right = %cst : i32 + calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 + calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 + calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 + %0 = comb.xor %std_compareFN_0.unordered, %true : i1 + calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 + calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 + calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 + calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 + calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 + calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 + calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 + %1 = comb.xor %std_compareFN_0.done, %true : i1 + calyx.assign %std_compareFN_0.go = %1 ? %true : i1 + calyx.group_done %cmpf_0_reg.done : i1 + } + calyx.group @ret_assign_0 { + calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 + calyx.assign %ret_arg0_reg.write_en = %true : i1 + calyx.group_done %ret_arg0_reg.done : i1 + } + } + calyx.control { + calyx.seq { + calyx.seq { + calyx.enable @bb0_0 + calyx.enable @ret_assign_0 + } + } + } + } {toplevel} +} + From 05506271e1c1474c9065901c19296782fd92000c Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Tue, 26 Nov 2024 01:00:41 -0500 Subject: [PATCH 07/14] code style refinement --- .../circt/Dialect/Calyx/CalyxLoweringUtils.h | 8 +- .../circt/Dialect/Calyx/CalyxPrimitives.td | 1 + lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 67 +++++++------ lib/Dialect/Calyx/Export/CalyxEmitter.cpp | 1 - .../Calyx/Transforms/CalyxLoweringUtils.cpp | 97 ++++++++----------- 5 files changed, 86 insertions(+), 88 deletions(-) diff --git a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h index cea5bd279c20..5cf510cb2165 100644 --- a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h +++ b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h @@ -784,7 +784,8 @@ struct PredicateInfo { struct InputPorts { // Relevant ports to extract from the `std_compareFN`. For example, we // extract the `lt` and the `unordered` ports when the predicate is `oge`. - enum Port { EQ, GT, LT, UNORDERED } port; + enum class Port { eq, gt, lt, unordered }; + Port port; // Whether we should invert the port before passing as inputs to the `op` // field. For example, we should invert both the `lt` and the `unordered` // port just extracted for predicate `oge`. @@ -792,8 +793,9 @@ struct PredicateInfo { }; // The combinational logic to apply to the input ports. For example, we should - // apply `AND` logic to the two input ports for predicate `oge`. - enum CombLogic { AND, OR, SPECIAL } logic; + // apply `logicAnd` to the two input ports for predicate `oge`. + enum class CombLogic { logicAnd, logicOr, noComb }; + CombLogic logic; SmallVector inputPorts; }; diff --git a/include/circt/Dialect/Calyx/CalyxPrimitives.td b/include/circt/Dialect/Calyx/CalyxPrimitives.td index 57e03a2cf50b..a1a103faa428 100644 --- a/include/circt/Dialect/Calyx/CalyxPrimitives.td +++ b/include/circt/Dialect/Calyx/CalyxPrimitives.td @@ -417,6 +417,7 @@ def MulFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.mul", [ }]; } +// This models the compare operation interface in Berkeley HardFloat implementation. def CompareFOpIEEE754 : ArithBinaryFloatingPointLibraryOp<"ieee754.compare", []> { let results = (outs I1:$clk, I1:$reset, I1:$go, AnySignlessInteger:$left, AnySignlessInteger:$right, I1:$signaling, diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index f2759e046ae4..01256ab1061d 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -30,7 +30,6 @@ #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/LogicalResult.h" -#include "llvm/Support/raw_ostream.h" #include @@ -764,8 +763,10 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, }; using calyx::PredicateInfo; + using CombLogic = PredicateInfo::CombLogic; + using Port = PredicateInfo::InputPorts::Port; PredicateInfo info = calyx::getPredicateInfo(cmpf.getPredicate()); - if (info.logic == PredicateInfo::SPECIAL) { + if (info.logic == CombLogic::noComb) { if (cmpf.getPredicate() == CmpFPredicate::AlwaysTrue) { cmpf.getResult().replaceAllUsesWith(c1); return success(); @@ -799,25 +800,25 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, for (const auto &input : info.inputPorts) { Value signal; switch (input.port) { - case PredicateInfo::InputPorts::Port::EQ: { + case Port::eq: { signal = calyxCmpFOp.getEq(); break; } - case PredicateInfo::InputPorts::Port::GT: { + case Port::gt: { signal = calyxCmpFOp.getGt(); break; } - case PredicateInfo::InputPorts::Port::LT: { + case Port::lt: { signal = calyxCmpFOp.getLt(); break; } - case PredicateInfo::InputPorts::Port::UNORDERED: { + case Port::unordered: { signal = calyxCmpFOp.getUnordered(); break; } } std::string nameSuffix = - (input.port == PredicateInfo::InputPorts::Port::UNORDERED) + (input.port == PredicateInfo::InputPorts::Port::unordered) ? "unordered_port" : "compare_port"; auto signalReg = @@ -828,33 +829,39 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, // Create the output logical operation Value outputValue, doneValue; - if (info.logic == PredicateInfo::SPECIAL) { + switch (info.logic) { + case CombLogic::noComb: { // it's guaranteed to be either ORD or UNO outputValue = inputRegs[0].getOut(); doneValue = inputRegs[0].getOut(); - } else { - if (info.logic == PredicateInfo::AND) { - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, {one, one, one}); - rewriter.create(loc, outputLibOp.getLeft(), - inputRegs[0].getOut()); - rewriter.create(loc, outputLibOp.getRight(), - inputRegs[1].getOut()); - - outputValue = outputLibOp.getOut(); - } else /*info.op == PredicateInfo::OR*/ { - auto outputLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, {one, one, one}); - rewriter.create(loc, outputLibOp.getLeft(), - inputRegs[0].getOut()); - rewriter.create(loc, outputLibOp.getRight(), - inputRegs[1].getOut()); - - outputValue = outputLibOp.getOut(); - } + break; + } + case CombLogic::logicAnd: { + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one, one}); + rewriter.create(loc, outputLibOp.getLeft(), + inputRegs[0].getOut()); + rewriter.create(loc, outputLibOp.getRight(), + inputRegs[1].getOut()); + + outputValue = outputLibOp.getOut(); + break; + } + case CombLogic::logicOr: { + auto outputLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one, one}); + rewriter.create(loc, outputLibOp.getLeft(), + inputRegs[0].getOut()); + rewriter.create(loc, outputLibOp.getRight(), + inputRegs[1].getOut()); + + outputValue = outputLibOp.getOut(); + } + } + if (info.logic != CombLogic::noComb) { auto doneLibOp = getState() .getNewLibraryOpInstance( rewriter, loc, {one, one, one}); diff --git a/lib/Dialect/Calyx/Export/CalyxEmitter.cpp b/lib/Dialect/Calyx/Export/CalyxEmitter.cpp index 7e9167981ea2..489546fa7b93 100644 --- a/lib/Dialect/Calyx/Export/CalyxEmitter.cpp +++ b/lib/Dialect/Calyx/Export/CalyxEmitter.cpp @@ -24,7 +24,6 @@ #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/raw_ostream.h" #include #include diff --git a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index 1e1e5db2327d..e0fab37ebffc 100644 --- a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp +++ b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp @@ -844,107 +844,96 @@ BuildCallInstance::getCallComponent(mlir::func::CallOp callOp) const { } PredicateInfo getPredicateInfo(CmpFPredicate pred) { + using CombLogic = PredicateInfo::CombLogic; + using Port = PredicateInfo::InputPorts::Port; PredicateInfo info; switch (pred) { case CmpFPredicate::OEQ: { - info.logic = PredicateInfo::AND; - info.inputPorts = {{PredicateInfo::InputPorts::EQ, false}, - {PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = CombLogic::logicAnd, + .inputPorts = {{Port::eq, /*inverted=*/false}, + {Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::OGT: { - info.logic = PredicateInfo::AND; - info.inputPorts = {{PredicateInfo::InputPorts::GT, false}, - {PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, + .inputPorts = {{Port::gt, /*inverted=*/false}, + {Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::OGE: { - info.logic = PredicateInfo::AND; - info.inputPorts = {{PredicateInfo::InputPorts::LT, true}, - {PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, + .inputPorts = {{Port::lt, /*inverted=*/true}, + {Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::OLT: { - info.logic = PredicateInfo::AND; - info.inputPorts = {{PredicateInfo::InputPorts::LT, false}, - {PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, + .inputPorts = {{Port::lt, /*inverted=*/false}, + {Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::OLE: { - info.logic = PredicateInfo::AND; - info.inputPorts = {{PredicateInfo::InputPorts::GT, true}, - {PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, + .inputPorts = {{Port::gt, /*inverted=*/true}, + {Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::ONE: { - info.logic = PredicateInfo::AND; - info.inputPorts = {{PredicateInfo::InputPorts::EQ, true}, - {PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, + .inputPorts = {{Port::eq, /*inverted=*/true}, + {Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::ORD: { - info.logic = PredicateInfo::SPECIAL; - info.inputPorts = {{PredicateInfo::InputPorts::UNORDERED, true}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::noComb, + .inputPorts = {{Port::unordered, /*inverted=*/true}}}; } case CmpFPredicate::UEQ: { - info.logic = PredicateInfo::OR; - info.inputPorts = {{PredicateInfo::InputPorts::EQ, false}, - {PredicateInfo::InputPorts::UNORDERED, false}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, + .inputPorts = {{Port::eq, /*inverted=*/false}, + {Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::UGT: { - info.logic = PredicateInfo::OR; - info.inputPorts = {{PredicateInfo::InputPorts::GT, false}, - {PredicateInfo::InputPorts::UNORDERED, false}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, + .inputPorts = {{Port::gt, /*inverted=*/false}, + {Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::UGE: { - info.logic = PredicateInfo::OR; - info.inputPorts = {{PredicateInfo::InputPorts::LT, true}, - {PredicateInfo::InputPorts::UNORDERED, false}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, + .inputPorts = {{Port::lt, /*inverted=*/true}, + {Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::ULT: { - info.logic = PredicateInfo::OR; - info.inputPorts = {{PredicateInfo::InputPorts::LT, false}, - {PredicateInfo::InputPorts::UNORDERED, false}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, + .inputPorts = {{Port::lt, /*inverted=*/false}, + {Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::ULE: { - info.logic = PredicateInfo::OR; - info.inputPorts = {{PredicateInfo::InputPorts::GT, true}, - {PredicateInfo::InputPorts::UNORDERED, false}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, + .inputPorts = {{Port::gt, /*inverted=*/true}, + {Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::UNE: { - info.logic = PredicateInfo::OR; - info.inputPorts = {{PredicateInfo::InputPorts::EQ, true}, - {PredicateInfo::InputPorts::UNORDERED, false}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, + .inputPorts = {{Port::eq, /*inverted=*/true}, + {Port::unordered, /*inverted=*/false}}}; break; } case CmpFPredicate::UNO: { - info.logic = PredicateInfo::SPECIAL; - info.inputPorts = {{PredicateInfo::InputPorts::UNORDERED, false}}; - break; + return PredicateInfo{.logic = PredicateInfo::CombLogic::noComb, + .inputPorts = {{Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::AlwaysTrue: case CmpFPredicate::AlwaysFalse: - info.logic = PredicateInfo::SPECIAL; + return PredicateInfo{.logic = PredicateInfo::CombLogic::noComb}; break; } From 982227baabe7e3cde23a5c348dfb33e4f4654727 Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 27 Nov 2024 12:43:27 -0500 Subject: [PATCH 08/14] change noComb to none --- include/circt/Dialect/Calyx/CalyxLoweringUtils.h | 2 +- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 7 ++++--- lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h index 5cf510cb2165..fd41b420423d 100644 --- a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h +++ b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h @@ -794,7 +794,7 @@ struct PredicateInfo { // The combinational logic to apply to the input ports. For example, we should // apply `logicAnd` to the two input ports for predicate `oge`. - enum class CombLogic { logicAnd, logicOr, noComb }; + enum class CombLogic { none, logicAnd, logicOr }; CombLogic logic; SmallVector inputPorts; }; diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index 01256ab1061d..bda2d02b1ca0 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -766,7 +766,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, using CombLogic = PredicateInfo::CombLogic; using Port = PredicateInfo::InputPorts::Port; PredicateInfo info = calyx::getPredicateInfo(cmpf.getPredicate()); - if (info.logic == CombLogic::noComb) { + if (info.logic == CombLogic::none) { if (cmpf.getPredicate() == CmpFPredicate::AlwaysTrue) { cmpf.getResult().replaceAllUsesWith(c1); return success(); @@ -830,7 +830,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, // Create the output logical operation Value outputValue, doneValue; switch (info.logic) { - case CombLogic::noComb: { + case CombLogic::none: { // it's guaranteed to be either ORD or UNO outputValue = inputRegs[0].getOut(); doneValue = inputRegs[0].getOut(); @@ -858,10 +858,11 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, inputRegs[1].getOut()); outputValue = outputLibOp.getOut(); + break; } } - if (info.logic != CombLogic::noComb) { + if (info.logic != CombLogic::none) { auto doneLibOp = getState() .getNewLibraryOpInstance( rewriter, loc, {one, one, one}); diff --git a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index e0fab37ebffc..50dbe8e37457 100644 --- a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp +++ b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp @@ -885,7 +885,7 @@ PredicateInfo getPredicateInfo(CmpFPredicate pred) { } case CmpFPredicate::ORD: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::noComb, + return PredicateInfo{.logic = PredicateInfo::CombLogic::none, .inputPorts = {{Port::unordered, /*inverted=*/true}}}; } @@ -927,13 +927,13 @@ PredicateInfo getPredicateInfo(CmpFPredicate pred) { } case CmpFPredicate::UNO: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::noComb, + return PredicateInfo{.logic = PredicateInfo::CombLogic::none, .inputPorts = {{Port::unordered, /*inverted=*/false}}}; } case CmpFPredicate::AlwaysTrue: case CmpFPredicate::AlwaysFalse: - return PredicateInfo{.logic = PredicateInfo::CombLogic::noComb}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::none}; break; } From 20e2b7a6c8cf8e7dd697df54729f058f71839e39 Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 27 Nov 2024 12:47:53 -0500 Subject: [PATCH 09/14] move float compare test cases to a separate file --- .../Conversion/SCFToCalyx/convert_simple.mlir | 702 ------------------ test/Conversion/SCFToCalyx/float_compare.mlir | 702 ++++++++++++++++++ 2 files changed, 702 insertions(+), 702 deletions(-) create mode 100644 test/Conversion/SCFToCalyx/float_compare.mlir diff --git a/test/Conversion/SCFToCalyx/convert_simple.mlir b/test/Conversion/SCFToCalyx/convert_simple.mlir index 93282ef068d4..fd0b363263d5 100644 --- a/test/Conversion/SCFToCalyx/convert_simple.mlir +++ b/test/Conversion/SCFToCalyx/convert_simple.mlir @@ -438,705 +438,3 @@ module { } } -// ----- - -// Test floating point OEQ - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf oeq, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point OGT - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ogt, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point OGE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf oge, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point OLT - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf olt, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point OLE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ole, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point ONE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf one, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point ORD - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ord, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point UEQ - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ueq, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point UGT - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ugt, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point UGE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf uge, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point ULT - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ult, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point ULE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf ule, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point UNE - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 -// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf une, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point UNO - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @bb0_0 { -// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 -// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 -// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 -// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf uno, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point AlwaysTrue - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %true : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf true, %arg0, %0 : f32 - - return %1 : i1 - } -} - -// ----- - -// Test floating point AlwaysFalse - - -// CHECK: module attributes {calyx.entrypoint = "main"} { -// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { -// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 -// CHECK-DAG: %true = hw.constant true -// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 -// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 -// CHECK: calyx.wires { -// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 -// CHECK: calyx.group @ret_assign_0 { -// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %false : i1 -// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 -// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 -// CHECK-DAG: } -// CHECK-DAG: } - -module { - func.func @main(%arg0 : f32) -> i1 { - %0 = arith.constant 4.2 : f32 - %1 = arith.cmpf false, %arg0, %0 : f32 - - return %1 : i1 - } -} diff --git a/test/Conversion/SCFToCalyx/float_compare.mlir b/test/Conversion/SCFToCalyx/float_compare.mlir new file mode 100644 index 000000000000..5740b88eac13 --- /dev/null +++ b/test/Conversion/SCFToCalyx/float_compare.mlir @@ -0,0 +1,702 @@ +// RUN: circt-opt %s --lower-scf-to-calyx -canonicalize -split-input-file | FileCheck %s + +// Test floating point OEQ + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf oeq, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OGT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ogt, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OGE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf oge, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OLT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf olt, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point OLE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ole, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ONE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_1.left, %std_and_1.right, %std_and_1.out = calyx.std_and @std_and_1 : i1, i1, i1 +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 +// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %cmpf_0_reg.out : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf one, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ORD + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ord, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UEQ + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ueq, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UGT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ugt, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UGE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf uge, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ULT + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ult, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point ULE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf ule, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UNE + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_and_0.left, %std_and_0.right, %std_and_0.out = calyx.std_and @std_and_0 : i1, i1, i1 +// CHECK-DAG: %std_or_0.left, %std_or_0.right, %std_or_0.out = calyx.std_or @std_or_0 : i1, i1, i1 +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %compare_port_0_reg.in, %compare_port_0_reg.write_en, %compare_port_0_reg.clk, %compare_port_0_reg.reset, %compare_port_0_reg.out, %compare_port_0_reg.done = calyx.register @compare_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_or_0.right = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 +// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf une, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point UNO + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %unordered_port_0_reg.in, %unordered_port_0_reg.write_en, %unordered_port_0_reg.clk, %unordered_port_0_reg.reset, %unordered_port_0_reg.out, %unordered_port_0_reg.done = calyx.register @unordered_port_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %cmpf_0_reg.in, %cmpf_0_reg.write_en, %cmpf_0_reg.clk, %cmpf_0_reg.reset, %cmpf_0_reg.out, %cmpf_0_reg.done = calyx.register @cmpf_0_reg : i1, i1, i1, i1, i1, i1 +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @bb0_0 { +// CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 +// CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 +// CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf uno, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point AlwaysTrue + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %true : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf true, %arg0, %0 : f32 + + return %1 : i1 + } +} + +// ----- + +// Test floating point AlwaysFalse + + +// CHECK: module attributes {calyx.entrypoint = "main"} { +// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i1, %done: i1 {done}) { +// CHECK-DAG: %cst = calyx.constant @cst_0 <4.200000e+00 : f32> : i32 +// CHECK-DAG: %true = hw.constant true +// CHECK-DAG: %std_compareFN_0.clk, %std_compareFN_0.reset, %std_compareFN_0.go, %std_compareFN_0.left, %std_compareFN_0.right, %std_compareFN_0.signaling, %std_compareFN_0.lt, %std_compareFN_0.eq, %std_compareFN_0.gt, %std_compareFN_0.unordered, %std_compareFN_0.exceptionalFlags, %std_compareFN_0.done = calyx.ieee754.compare @std_compareFN_0 : i1, i1, i1, i32, i32, i1, i1, i1, i1, i1, i5, i1 +// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i1, i1, i1, i1, i1, i1 +// CHECK: calyx.wires { +// CHECK-DAG: calyx.assign %out0 = %ret_arg0_reg.out : i1 +// CHECK: calyx.group @ret_assign_0 { +// CHECK-DAG: calyx.assign %ret_arg0_reg.in = %false : i1 +// CHECK-DAG: calyx.assign %ret_arg0_reg.write_en = %true : i1 +// CHECK-DAG: calyx.group_done %ret_arg0_reg.done : i1 +// CHECK-DAG: } +// CHECK-DAG: } + +module { + func.func @main(%arg0 : f32) -> i1 { + %0 = arith.constant 4.2 : f32 + %1 = arith.cmpf false, %arg0, %0 : f32 + + return %1 : i1 + } +} From 2900f7572d8f472179da4d80757a18145b7e44ef Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 27 Nov 2024 22:54:39 -0500 Subject: [PATCH 10/14] enum naming --- .../circt/Dialect/Calyx/CalyxLoweringUtils.h | 6 +- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 20 ++--- .../Calyx/Transforms/CalyxLoweringUtils.cpp | 82 +++++++++---------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h index fd41b420423d..de1aaf086c6f 100644 --- a/include/circt/Dialect/Calyx/CalyxLoweringUtils.h +++ b/include/circt/Dialect/Calyx/CalyxLoweringUtils.h @@ -784,7 +784,7 @@ struct PredicateInfo { struct InputPorts { // Relevant ports to extract from the `std_compareFN`. For example, we // extract the `lt` and the `unordered` ports when the predicate is `oge`. - enum class Port { eq, gt, lt, unordered }; + enum class Port { Eq, Gt, Lt, Unordered }; Port port; // Whether we should invert the port before passing as inputs to the `op` // field. For example, we should invert both the `lt` and the `unordered` @@ -793,8 +793,8 @@ struct PredicateInfo { }; // The combinational logic to apply to the input ports. For example, we should - // apply `logicAnd` to the two input ports for predicate `oge`. - enum class CombLogic { none, logicAnd, logicOr }; + // apply `And` to the two input ports for predicate `oge`. + enum class CombLogic { None, And, Or }; CombLogic logic; SmallVector inputPorts; }; diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index bda2d02b1ca0..f98e7d90d37f 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -766,7 +766,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, using CombLogic = PredicateInfo::CombLogic; using Port = PredicateInfo::InputPorts::Port; PredicateInfo info = calyx::getPredicateInfo(cmpf.getPredicate()); - if (info.logic == CombLogic::none) { + if (info.logic == CombLogic::None) { if (cmpf.getPredicate() == CmpFPredicate::AlwaysTrue) { cmpf.getResult().replaceAllUsesWith(c1); return success(); @@ -800,25 +800,25 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, for (const auto &input : info.inputPorts) { Value signal; switch (input.port) { - case Port::eq: { + case Port::Eq: { signal = calyxCmpFOp.getEq(); break; } - case Port::gt: { + case Port::Gt: { signal = calyxCmpFOp.getGt(); break; } - case Port::lt: { + case Port::Lt: { signal = calyxCmpFOp.getLt(); break; } - case Port::unordered: { + case Port::Unordered: { signal = calyxCmpFOp.getUnordered(); break; } } std::string nameSuffix = - (input.port == PredicateInfo::InputPorts::Port::unordered) + (input.port == PredicateInfo::InputPorts::Port::Unordered) ? "unordered_port" : "compare_port"; auto signalReg = @@ -830,13 +830,13 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, // Create the output logical operation Value outputValue, doneValue; switch (info.logic) { - case CombLogic::none: { + case CombLogic::None: { // it's guaranteed to be either ORD or UNO outputValue = inputRegs[0].getOut(); doneValue = inputRegs[0].getOut(); break; } - case CombLogic::logicAnd: { + case CombLogic::And: { auto outputLibOp = getState() .getNewLibraryOpInstance( rewriter, loc, {one, one, one}); @@ -848,7 +848,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, outputValue = outputLibOp.getOut(); break; } - case CombLogic::logicOr: { + case CombLogic::Or: { auto outputLibOp = getState() .getNewLibraryOpInstance( rewriter, loc, {one, one, one}); @@ -862,7 +862,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, } } - if (info.logic != CombLogic::none) { + if (info.logic != CombLogic::None) { auto doneLibOp = getState() .getNewLibraryOpInstance( rewriter, loc, {one, one, one}); diff --git a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index 50dbe8e37457..a3da15f1a5ef 100644 --- a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp +++ b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp @@ -849,91 +849,91 @@ PredicateInfo getPredicateInfo(CmpFPredicate pred) { PredicateInfo info; switch (pred) { case CmpFPredicate::OEQ: { - return PredicateInfo{.logic = CombLogic::logicAnd, - .inputPorts = {{Port::eq, /*inverted=*/false}, - {Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = CombLogic::And, + .inputPorts = {{Port::Eq, /*inverted=*/false}, + {Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::OGT: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, - .inputPorts = {{Port::gt, /*inverted=*/false}, - {Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::And, + .inputPorts = {{Port::Gt, /*inverted=*/false}, + {Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::OGE: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, - .inputPorts = {{Port::lt, /*inverted=*/true}, - {Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::And, + .inputPorts = {{Port::Lt, /*inverted=*/true}, + {Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::OLT: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, - .inputPorts = {{Port::lt, /*inverted=*/false}, - {Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::And, + .inputPorts = {{Port::Lt, /*inverted=*/false}, + {Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::OLE: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, - .inputPorts = {{Port::gt, /*inverted=*/true}, - {Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::And, + .inputPorts = {{Port::Gt, /*inverted=*/true}, + {Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::ONE: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicAnd, - .inputPorts = {{Port::eq, /*inverted=*/true}, - {Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::And, + .inputPorts = {{Port::Eq, /*inverted=*/true}, + {Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::ORD: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::none, - .inputPorts = {{Port::unordered, /*inverted=*/true}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::None, + .inputPorts = {{Port::Unordered, /*inverted=*/true}}}; } case CmpFPredicate::UEQ: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, - .inputPorts = {{Port::eq, /*inverted=*/false}, - {Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, + .inputPorts = {{Port::Eq, /*inverted=*/false}, + {Port::Unordered, /*inverted=*/false}}}; } case CmpFPredicate::UGT: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, - .inputPorts = {{Port::gt, /*inverted=*/false}, - {Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, + .inputPorts = {{Port::Gt, /*inverted=*/false}, + {Port::Unordered, /*inverted=*/false}}}; } case CmpFPredicate::UGE: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, - .inputPorts = {{Port::lt, /*inverted=*/true}, - {Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, + .inputPorts = {{Port::Lt, /*inverted=*/true}, + {Port::Unordered, /*inverted=*/false}}}; } case CmpFPredicate::ULT: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, - .inputPorts = {{Port::lt, /*inverted=*/false}, - {Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, + .inputPorts = {{Port::Lt, /*inverted=*/false}, + {Port::Unordered, /*inverted=*/false}}}; } case CmpFPredicate::ULE: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, - .inputPorts = {{Port::gt, /*inverted=*/true}, - {Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, + .inputPorts = {{Port::Gt, /*inverted=*/true}, + {Port::Unordered, /*inverted=*/false}}}; } case CmpFPredicate::UNE: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::logicOr, - .inputPorts = {{Port::eq, /*inverted=*/true}, - {Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, + .inputPorts = {{Port::Eq, /*inverted=*/true}, + {Port::Unordered, /*inverted=*/false}}}; break; } case CmpFPredicate::UNO: { - return PredicateInfo{.logic = PredicateInfo::CombLogic::none, - .inputPorts = {{Port::unordered, /*inverted=*/false}}}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::None, + .inputPorts = {{Port::Unordered, /*inverted=*/false}}}; } case CmpFPredicate::AlwaysTrue: case CmpFPredicate::AlwaysFalse: - return PredicateInfo{.logic = PredicateInfo::CombLogic::none}; + return PredicateInfo{.logic = PredicateInfo::CombLogic::None}; break; } From 4d697e6fe0a545bceba7942275c46f26b7324eb1 Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 27 Nov 2024 23:21:13 -0500 Subject: [PATCH 11/14] use std_not instead of guarded assignment because register in port has data attr, which will rewrite the guarded assgn --- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index f98e7d90d37f..ad0a32834fbe 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -754,10 +754,15 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, getState().getUniqueName(nameSuffix)); rewriter.create(loc, reg.getWriteEn(), calyxCmpFOp.getDone()); - if (invert) - rewriter.create( - loc, reg.getIn(), c1, comb::createOrFoldNot(loc, signal, builder)); - else + if (invert) { + auto notLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one}); + rewriter.create(loc, notLibOp.getIn(), signal); + rewriter.create(loc, reg.getIn(), notLibOp.getOut()); + getState().registerEvaluatingGroup( + notLibOp.getOut(), group); + } else rewriter.create(loc, reg.getIn(), signal); return reg; }; From 0bce9c91875618400cd422aa379cf6e082380f3a Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Wed, 27 Nov 2024 23:44:37 -0500 Subject: [PATCH 12/14] add signaling --- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 27 ++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index ad0a32834fbe..0549bfd172ff 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -741,6 +741,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, rewriter, loc, {one, one, one, width, width, one, one, one, one, one, five, one}); + hw::ConstantOp c0 = createConstant(loc, rewriter, getComponent(), 1, 0); hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); rewriter.setInsertionPointToStart(getComponent().getBodyBlock()); @@ -778,8 +779,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, } if (cmpf.getPredicate() == CmpFPredicate::AlwaysFalse) { - Value constantZero = createConstant(loc, rewriter, getComponent(), 1, 0); - cmpf.getResult().replaceAllUsesWith(constantZero); + cmpf.getResult().replaceAllUsesWith(c0); return success(); } } @@ -800,6 +800,29 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, rewriter.create(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); rewriter.create(loc, calyxCmpFOp.getRight(), cmpf.getRhs()); + bool signalingFlag = false; + switch (cmpf.getPredicate()) { + case CmpFPredicate::UGT: + case CmpFPredicate::UGE: + case CmpFPredicate::ULT: + case CmpFPredicate::ULE: + case CmpFPredicate::OGT: + case CmpFPredicate::OGE: + case CmpFPredicate::OLT: + case CmpFPredicate::OLE: + signalingFlag = true; + break; + default: + break; + } + + // The IEEE Standard mandates that equality comparisons ordinarily are quiet, + // while inequality comparisons ordinarily are signaling. + if (signalingFlag) + rewriter.create(loc, calyxCmpFOp.getSignaling(), c1); + else + rewriter.create(loc, calyxCmpFOp.getSignaling(), c0); + // Prepare signals and create registers SmallVector inputRegs; for (const auto &input : info.inputPorts) { From 99a0a4ef238bbddaf97d81285e872cac8f88740e Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Thu, 28 Nov 2024 11:02:52 -0500 Subject: [PATCH 13/14] change tests by adding signaling and changing from comb xor to calyx std_not --- test/Conversion/SCFToCalyx/float_compare.mlir | 106 ++++++++++-------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/test/Conversion/SCFToCalyx/float_compare.mlir b/test/Conversion/SCFToCalyx/float_compare.mlir index 5740b88eac13..eb982cf325e5 100644 --- a/test/Conversion/SCFToCalyx/float_compare.mlir +++ b/test/Conversion/SCFToCalyx/float_compare.mlir @@ -18,19 +18,20 @@ // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %false : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { @@ -68,19 +69,20 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { @@ -119,20 +121,21 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_1.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_1.out : i1 // CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { @@ -171,19 +174,20 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { @@ -222,20 +226,21 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_1.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_1.out : i1 // CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { @@ -274,20 +279,21 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %false : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.eq : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %1 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_1.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_1.out : i1 // CHECK-DAG: calyx.assign %std_and_0.left = %compare_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %std_and_1.left = %compare_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %std_and_1.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_and_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_1.out : i1 -// CHECK-DAG: %2 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %2 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } // CHECK: calyx.group @ret_assign_0 { @@ -323,13 +329,14 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %false : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.unordered, %true : i1 -// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.unordered : i1 +// CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %unordered_port_0_reg.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } @@ -362,6 +369,7 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %false : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.eq : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 @@ -406,6 +414,7 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.gt : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 @@ -450,9 +459,10 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.lt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.lt : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 // CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 @@ -461,8 +471,8 @@ module { // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } @@ -495,6 +505,7 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_compareFN_0.lt : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 @@ -539,9 +550,10 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %true : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.gt, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.gt : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 // CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 @@ -550,8 +562,8 @@ module { // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } @@ -584,9 +596,10 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %false : i1 // CHECK-DAG: calyx.assign %compare_port_0_reg.write_en = %std_compareFN_0.done : i1 -// CHECK-DAG: %0 = comb.xor %std_compareFN_0.eq, %true : i1 -// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %0 ? %true : i1 +// CHECK-DAG: calyx.assign %std_not_0.in = %std_compareFN_0.eq : i1 +// CHECK-DAG: calyx.assign %compare_port_0_reg.in = %std_not_0.out : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 // CHECK-DAG: calyx.assign %std_or_0.left = %compare_port_0_reg.out : i1 @@ -595,8 +608,8 @@ module { // CHECK-DAG: calyx.assign %std_and_0.right = %unordered_port_0_reg.done : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %std_or_0.out : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.write_en = %std_and_0.out : i1 -// CHECK-DAG: %1 = comb.xor %std_compareFN_0.done, %true : i1 -// CHECK-DAG: calyx.assign %std_compareFN_0.go = %1 ? %true : i1 +// CHECK-DAG: %0 = comb.xor %std_compareFN_0.done, %true : i1 +// CHECK-DAG: calyx.assign %std_compareFN_0.go = %0 ? %true : i1 // CHECK-DAG: calyx.group_done %cmpf_0_reg.done : i1 // CHECK-DAG: } @@ -626,6 +639,7 @@ module { // CHECK: calyx.group @bb0_0 { // CHECK-DAG: calyx.assign %std_compareFN_0.left = %in0 : i32 // CHECK-DAG: calyx.assign %std_compareFN_0.right = %cst : i32 +// CHECK-DAG: calyx.assign %std_compareFN_0.signaling = %false : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.write_en = %std_compareFN_0.done : i1 // CHECK-DAG: calyx.assign %unordered_port_0_reg.in = %std_compareFN_0.unordered : i1 // CHECK-DAG: calyx.assign %cmpf_0_reg.in = %unordered_port_0_reg.out : i1 From 733876def510707be88052fa6e0543b56003074a Mon Sep 17 00:00:00 2001 From: Jiahan Xie Date: Thu, 28 Nov 2024 16:25:28 -0500 Subject: [PATCH 14/14] move createSignalRegister to a class method; and more refactor --- lib/Conversion/SCFToCalyx/SCFToCalyx.cpp | 71 +++++++++++-------- .../Calyx/Transforms/CalyxLoweringUtils.cpp | 14 ---- 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp index 0549bfd172ff..eba68cfc092b 100644 --- a/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp +++ b/lib/Conversion/SCFToCalyx/SCFToCalyx.cpp @@ -503,6 +503,33 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern { address.value()); } } + + calyx::RegisterOp createSignalRegister(PatternRewriter &rewriter, + Value signal, bool invert, + StringRef nameSuffix, + calyx::CompareFOpIEEE754 calyxCmpFOp, + calyx::GroupOp group) const { + Location loc = calyxCmpFOp.getLoc(); + IntegerType one = rewriter.getI1Type(); + auto component = getComponent(); + OpBuilder builder(group->getRegion(0)); + auto reg = createRegister( + loc, rewriter, component, 1, + getState().getUniqueName(nameSuffix)); + rewriter.create(loc, reg.getWriteEn(), + calyxCmpFOp.getDone()); + if (invert) { + auto notLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one}); + rewriter.create(loc, notLibOp.getIn(), signal); + rewriter.create(loc, reg.getIn(), notLibOp.getOut()); + getState().registerEvaluatingGroup( + notLibOp.getOut(), group); + } else + rewriter.create(loc, reg.getIn(), signal); + return reg; + }; }; LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, @@ -745,29 +772,6 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); rewriter.setInsertionPointToStart(getComponent().getBodyBlock()); - auto createSignalRegister = - [&](Value signal, bool invert, StringRef nameSuffix, Location loc, - PatternRewriter &rewriter, calyx::ComponentOp component, - calyx::CompareFOpIEEE754 calyxCmpFOp, calyx::GroupOp group, - OpBuilder &builder) -> calyx::RegisterOp { - auto reg = createRegister( - loc, rewriter, component, 1, - getState().getUniqueName(nameSuffix)); - rewriter.create(loc, reg.getWriteEn(), - calyxCmpFOp.getDone()); - if (invert) { - auto notLibOp = getState() - .getNewLibraryOpInstance( - rewriter, loc, {one, one}); - rewriter.create(loc, notLibOp.getIn(), signal); - rewriter.create(loc, reg.getIn(), notLibOp.getOut()); - getState().registerEvaluatingGroup( - notLibOp.getOut(), group); - } else - rewriter.create(loc, reg.getIn(), signal); - return reg; - }; - using calyx::PredicateInfo; using CombLogic = PredicateInfo::CombLogic; using Port = PredicateInfo::InputPorts::Port; @@ -812,16 +816,22 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, case CmpFPredicate::OLE: signalingFlag = true; break; - default: + case CmpFPredicate::UEQ: + case CmpFPredicate::UNE: + case CmpFPredicate::OEQ: + case CmpFPredicate::ONE: + case CmpFPredicate::UNO: + case CmpFPredicate::ORD: + case CmpFPredicate::AlwaysTrue: + case CmpFPredicate::AlwaysFalse: + signalingFlag = false; break; } // The IEEE Standard mandates that equality comparisons ordinarily are quiet, // while inequality comparisons ordinarily are signaling. - if (signalingFlag) - rewriter.create(loc, calyxCmpFOp.getSignaling(), c1); - else - rewriter.create(loc, calyxCmpFOp.getSignaling(), c0); + rewriter.create(loc, calyxCmpFOp.getSignaling(), + signalingFlag ? c1 : c0); // Prepare signals and create registers SmallVector inputRegs; @@ -849,9 +859,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter, (input.port == PredicateInfo::InputPorts::Port::Unordered) ? "unordered_port" : "compare_port"; - auto signalReg = - createSignalRegister(signal, input.invert, nameSuffix, loc, rewriter, - getComponent(), calyxCmpFOp, group, builder); + auto signalReg = createSignalRegister(rewriter, signal, input.invert, + nameSuffix, calyxCmpFOp, group); inputRegs.push_back(signalReg); } diff --git a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index a3da15f1a5ef..eaa2c9737773 100644 --- a/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp +++ b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp @@ -853,84 +853,70 @@ PredicateInfo getPredicateInfo(CmpFPredicate pred) { .inputPorts = {{Port::Eq, /*inverted=*/false}, {Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::OGT: { return PredicateInfo{.logic = PredicateInfo::CombLogic::And, .inputPorts = {{Port::Gt, /*inverted=*/false}, {Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::OGE: { return PredicateInfo{.logic = PredicateInfo::CombLogic::And, .inputPorts = {{Port::Lt, /*inverted=*/true}, {Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::OLT: { return PredicateInfo{.logic = PredicateInfo::CombLogic::And, .inputPorts = {{Port::Lt, /*inverted=*/false}, {Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::OLE: { return PredicateInfo{.logic = PredicateInfo::CombLogic::And, .inputPorts = {{Port::Gt, /*inverted=*/true}, {Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::ONE: { return PredicateInfo{.logic = PredicateInfo::CombLogic::And, .inputPorts = {{Port::Eq, /*inverted=*/true}, {Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::ORD: { return PredicateInfo{.logic = PredicateInfo::CombLogic::None, .inputPorts = {{Port::Unordered, /*inverted=*/true}}}; } - case CmpFPredicate::UEQ: { return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, .inputPorts = {{Port::Eq, /*inverted=*/false}, {Port::Unordered, /*inverted=*/false}}}; } - case CmpFPredicate::UGT: { return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, .inputPorts = {{Port::Gt, /*inverted=*/false}, {Port::Unordered, /*inverted=*/false}}}; } - case CmpFPredicate::UGE: { return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, .inputPorts = {{Port::Lt, /*inverted=*/true}, {Port::Unordered, /*inverted=*/false}}}; } - case CmpFPredicate::ULT: { return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, .inputPorts = {{Port::Lt, /*inverted=*/false}, {Port::Unordered, /*inverted=*/false}}}; } - case CmpFPredicate::ULE: { return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, .inputPorts = {{Port::Gt, /*inverted=*/true}, {Port::Unordered, /*inverted=*/false}}}; } - case CmpFPredicate::UNE: { return PredicateInfo{.logic = PredicateInfo::CombLogic::Or, .inputPorts = {{Port::Eq, /*inverted=*/true}, {Port::Unordered, /*inverted=*/false}}}; break; } - case CmpFPredicate::UNO: { return PredicateInfo{.logic = PredicateInfo::CombLogic::None, .inputPorts = {{Port::Unordered, /*inverted=*/false}}}; } - case CmpFPredicate::AlwaysTrue: case CmpFPredicate::AlwaysFalse: return PredicateInfo{.logic = PredicateInfo::CombLogic::None};