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/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..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 @@ -289,7 +290,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 +327,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 +731,164 @@ 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 calyxCmpFOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, + {one, one, one, width, width, one, one, one, one, + one, five, one}); + 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) + rewriter.create( + loc, reg.getIn(), c1, comb::createOrFoldNot(loc, signal, builder)); + else + rewriter.create(loc, reg.getIn(), signal); + return reg; + }; + + 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(); + } + + if (cmpf.getPredicate() == CmpFPredicate::AlwaysFalse) { + Value constantZero = createConstant(loc, rewriter, getComponent(), 1, 0); + cmpf.getResult().replaceAllUsesWith(constantZero); + return success(); + } + } + + // General case + 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()); + + // 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(); + } + + auto doneLibOp = getState() + .getNewLibraryOpInstance( + rewriter, loc, {one, one, one}); + rewriter.create(loc, doneLibOp.getLeft(), + inputRegs[0].getDone()); + rewriter.create(loc, doneLibOp.getRight(), + inputRegs[1].getDone()); + doneValue = doneLibOp.getOut(); + } + + // Write to the output register + rewriter.create(loc, reg.getIn(), outputValue); + rewriter.create(loc, reg.getWriteEn(), doneValue); + + // Set the go and done signal + rewriter.create( + loc, calyxCmpFOp.getGo(), c1, + comb::createOrFoldNot(loc, calyxCmpFOp.getDone(), builder)); + rewriter.create(loc, reg.getDone()); + + cmpf.getResult().replaceAllUsesWith(reg.getOut()); + + // Register evaluating groups + getState().registerEvaluatingGroup(outputValue, + group); + getState().registerEvaluatingGroup(doneValue, group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getLeft(), group); + getState().registerEvaluatingGroup( + calyxCmpFOp.getRight(), group); + + return success(); +} + template static LogicalResult buildAllocOp(ComponentLoweringState &componentState, PatternRewriter &rewriter, TAllocOp allocOp) { @@ -2113,7 +2273,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/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/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp b/lib/Dialect/Calyx/Transforms/CalyxLoweringUtils.cpp index 878eb882addf..1e1e5db2327d 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( @@ -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 fd0b363263d5..93282ef068d4 100644 --- a/test/Conversion/SCFToCalyx/convert_simple.mlir +++ b/test/Conversion/SCFToCalyx/convert_simple.mlir @@ -438,3 +438,705 @@ 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/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} +} +