diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index c4e958ec73..9b855154f3 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -315,6 +315,7 @@ def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi"> { def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui"> { let summary = "Integer signed width extension."; + let hasCanonicalizer = 1; } def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [ diff --git a/integration-test/if_convert/buffer.json b/integration-test/if_convert/buffer.json index 01493e7de7..32eba852a8 100644 --- a/integration-test/if_convert/buffer.json +++ b/integration-test/if_convert/buffer.json @@ -28,7 +28,7 @@ "comment": "To achieve better II" }, { - "pred": "extsi2", + "pred": "constant11", "outid": 0, "slots": 4, "type": "fifo_break_none", diff --git a/integration-test/loop_path/buffer.json b/integration-test/loop_path/buffer.json index dd6973e22e..2db523d1bc 100644 --- a/integration-test/loop_path/buffer.json +++ b/integration-test/loop_path/buffer.json @@ -7,21 +7,21 @@ "comment": "To avoid deadlock" }, { - "pred": "cmpi2", + "pred": "fork1", "outid": 0, "slots": 2, "type": "fifo_break_none", "comment": "To achieve better II" }, { - "pred": "fork3", - "outid": 0, + "pred": "fork5", + "outid": 1, "slots": 2, "type": "fifo_break_none", "comment": "To achieve better II" }, { - "pred": "trunci0", + "pred": "fork11", "outid": 0, "slots": 2, "type": "fifo_break_none", @@ -33,12 +33,5 @@ "slots": 2, "type": "fifo_break_none", "comment": "Buffer non-spec token to prevent II=2 locking (placed before spec_commit to avoid the effect of non-deterministic naming)" - }, - { - "pred": "fork11", - "outid": 0, - "slots": 2, - "type": "fifo_break_none", - "comment": "To absorb latency for spec_commit4 (ctrl)" } ] diff --git a/integration-test/nested_loop/buffer.json b/integration-test/nested_loop/buffer.json index c96f590b31..ee608b8038 100644 --- a/integration-test/nested_loop/buffer.json +++ b/integration-test/nested_loop/buffer.json @@ -35,7 +35,7 @@ "comment": "Buffer non-spec token to prevent II=2 locking" }, { - "pred": "extsi3", + "pred": "constant18", "outid": 0, "slots": 4, "type": "fifo_break_none", diff --git a/integration-test/single_loop/buffer.json b/integration-test/single_loop/buffer.json index e61dfa731e..1e183b8cd1 100644 --- a/integration-test/single_loop/buffer.json +++ b/integration-test/single_loop/buffer.json @@ -14,7 +14,7 @@ "comment": "To absorb latency for spec_commit4 (data)" }, { - "pred": "extsi1", + "pred": "constant9", "outid": 0, "slots": 5, "type": "fifo_break_none", diff --git a/lib/Dialect/Handshake/HandshakeCanonicalization.td b/lib/Dialect/Handshake/HandshakeCanonicalization.td index 1b8fca40a6..0fc4846274 100644 --- a/lib/Dialect/Handshake/HandshakeCanonicalization.td +++ b/lib/Dialect/Handshake/HandshakeCanonicalization.td @@ -25,6 +25,16 @@ def ExtSIOfExtUI : Pat< (Handshake_ExtSIOp (Handshake_ExtUIOp $x)), (Handshake_ExtUIOp $x) >; +def ExtUIOfConst : Pat< + (Handshake_ExtUIOp:$ext (Handshake_ConstantOp $attr, $ctrl)), + (Handshake_ConstantOp (NativeCodeCall<"constantFoldExt($0.getOwner(), $1)"> $ext, $attr), $ctrl) +>; + +def ExtSIOfConst : Pat< + (Handshake_ExtSIOp:$ext (Handshake_ConstantOp $attr, $ctrl)), + (Handshake_ConstantOp (NativeCodeCall<"constantFoldExt($0.getOwner(), $1)"> $ext, $attr), $ctrl) +>; + //===----------------------------------------------------------------------===// // TruncIOp //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 63c1870e69..3bfcaae04a 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -187,6 +187,21 @@ static unsigned getDataBitWidth(Value val) { return cast(val.getType()).getDataBitWidth(); } +static IntegerAttr constantFoldExt(Operation *op, Attribute attr) { + auto integerAttr = cast(attr); + if (auto extUI = dyn_cast(op)) + return IntegerAttr::get( + extUI.getType().getDataType(), + integerAttr.getValue().zext(extUI.getType().getDataBitWidth())); + + if (auto extSI = dyn_cast(op)) + return IntegerAttr::get( + extSI.getType().getDataType(), + integerAttr.getValue().sext(extSI.getType().getDataBitWidth())); + + llvm_unreachable("only expected extui and extsi"); +} + namespace { #include "lib/Dialect/Handshake/HandshakeCanonicalization.inc" } // namespace @@ -1883,7 +1898,7 @@ static OpFoldResult foldExtOp(Op op) { void ExtSIOp::getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context) { - results.add(context); + results.add(context); } OpFoldResult ExtSIOp::fold(FoldAdaptor adaptor) { return foldExtOp(*this); } @@ -1912,6 +1927,11 @@ LogicalResult ExtSIOp::verify() { return verifyExtOp(*this); } OpFoldResult ExtUIOp::fold(FoldAdaptor adaptor) { return foldExtOp(*this); } +void ExtUIOp::getCanonicalizationPatterns(RewritePatternSet &results, + MLIRContext *context) { + results.add(context); +} + LogicalResult ExtUIOp::verify() { return verifyExtOp(*this); } //===----------------------------------------------------------------------===// diff --git a/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir b/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir index 6e1b1c8d52..7b8226a3ed 100644 --- a/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir +++ b/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir @@ -134,11 +134,10 @@ handshake.func @xoriFW(%arg0: !handshake.channel, %arg1: !handshake.channel< // CHECK-LABEL: handshake.func @shliFW( // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "start"], resNames = ["out0"]} { -// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i4} : <>, -// CHECK: %[[VAL_3:.*]] = extsi %[[VAL_0]] : to -// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_2]] : to -// CHECK: %[[VAL_5:.*]] = shli %[[VAL_3]], %[[VAL_4]] : -// CHECK: end %[[VAL_5]] : +// CHECK: %[[VAL_2:.*]] = extsi %[[VAL_0]] : to +// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 4 : i32} : <>, +// CHECK: %[[VAL_4:.*]] = shli %[[VAL_2]], %[[VAL_3]] : +// CHECK: end %[[VAL_4]] : // CHECK: } handshake.func @shliFW(%arg0: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %cst = handshake.constant %start {value = 4 : i4} : <>, @@ -153,12 +152,11 @@ handshake.func @shliFW(%arg0: !handshake.channel, %start: !handshake.contro // CHECK-LABEL: handshake.func @shrsiFW( // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "start"], resNames = ["out0"]} { -// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i4} : <>, -// CHECK: %[[VAL_3:.*]] = extui %[[VAL_2]] : to -// CHECK: %[[VAL_4:.*]] = shrsi %[[VAL_0]], %[[VAL_3]] : -// CHECK: %[[VAL_5:.*]] = trunci %[[VAL_4]] : to -// CHECK: %[[VAL_6:.*]] = extsi %[[VAL_5]] : to -// CHECK: end %[[VAL_6]] : +// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i16} : <>, +// CHECK: %[[VAL_3:.*]] = shrsi %[[VAL_0]], %[[VAL_2]] : +// CHECK: %[[VAL_4:.*]] = trunci %[[VAL_3]] : to +// CHECK: %[[VAL_5:.*]] = extsi %[[VAL_4]] : to +// CHECK: end %[[VAL_5]] : // CHECK: } handshake.func @shrsiFW(%arg0: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %cst = handshake.constant %start {value = 4 : i4} : <>, @@ -173,12 +171,11 @@ handshake.func @shrsiFW(%arg0: !handshake.channel, %start: !handshake.contr // CHECK-LABEL: handshake.func @shruiFW( // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "start"], resNames = ["out0"]} { -// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i4} : <>, -// CHECK: %[[VAL_3:.*]] = extui %[[VAL_2]] : to -// CHECK: %[[VAL_4:.*]] = shrui %[[VAL_0]], %[[VAL_3]] : -// CHECK: %[[VAL_5:.*]] = trunci %[[VAL_4]] : to -// CHECK: %[[VAL_6:.*]] = extsi %[[VAL_5]] : to -// CHECK: end %[[VAL_6]] : +// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i16} : <>, +// CHECK: %[[VAL_3:.*]] = shrui %[[VAL_0]], %[[VAL_2]] : +// CHECK: %[[VAL_4:.*]] = trunci %[[VAL_3]] : to +// CHECK: %[[VAL_5:.*]] = extsi %[[VAL_4]] : to +// CHECK: end %[[VAL_5]] : // CHECK: } handshake.func @shruiFW(%arg0: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %cst = handshake.constant %start {value = 4 : i4} : <>, diff --git a/test/Transforms/HandshakeOptimizeBitwidths/bound-opti.mlir b/test/Transforms/HandshakeOptimizeBitwidths/bound-opti.mlir index febaa4d9ba..6f51e8bb0d 100644 --- a/test/Transforms/HandshakeOptimizeBitwidths/bound-opti.mlir +++ b/test/Transforms/HandshakeOptimizeBitwidths/bound-opti.mlir @@ -5,12 +5,11 @@ // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "start"], resNames = ["out0"]} { // CHECK: %[[VAL_2:.*]] = trunci %[[VAL_0]] {handshake.bb = 0 : ui32} : to -// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i6} : <>, -// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_3]] : to -// CHECK: %[[VAL_5:.*]] = cmpi eq, %[[VAL_0]], %[[VAL_4]] : -// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_5]], %[[VAL_2]] : , -// CHECK: %[[VAL_8:.*]] = extsi %[[VAL_6]] : to -// CHECK: end %[[VAL_8]] : +// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i32} : <>, +// CHECK: %[[VAL_4:.*]] = cmpi eq, %[[VAL_0]], %[[VAL_3]] : +// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = cond_br %[[VAL_4]], %[[VAL_2]] : , +// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_5]] : to +// CHECK: end %[[VAL_7]] : // CHECK: } handshake.func @boundEqCst(%arg0: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %bound = constant %start {value = 16 : i6} : <>, @@ -26,12 +25,11 @@ handshake.func @boundEqCst(%arg0: !handshake.channel, %start: !handshake.co // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "start"], resNames = ["out0"]} { // CHECK: %[[VAL_2:.*]] = trunci %[[VAL_0]] {handshake.bb = 0 : ui32} : to -// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i6} : <>, -// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_3]] : to -// CHECK: %[[VAL_5:.*]] = cmpi ule, %[[VAL_0]], %[[VAL_4]] : -// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_5]], %[[VAL_2]] : , -// CHECK: %[[VAL_8:.*]] = extsi %[[VAL_6]] : to -// CHECK: end %[[VAL_8]] : +// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i32} : <>, +// CHECK: %[[VAL_4:.*]] = cmpi ule, %[[VAL_0]], %[[VAL_3]] : +// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = cond_br %[[VAL_4]], %[[VAL_2]] : , +// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_5]] : to +// CHECK: end %[[VAL_7]] : // CHECK: } handshake.func @boundUleCst(%arg0: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %bound = constant %start {value = 16 : i6} : <>, @@ -47,12 +45,11 @@ handshake.func @boundUleCst(%arg0: !handshake.channel, %start: !handshake.c // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "start"], resNames = ["out0"]} { // CHECK: %[[VAL_2:.*]] = trunci %[[VAL_0]] {handshake.bb = 0 : ui32} : to -// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i6} : <>, -// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_3]] : to -// CHECK: %[[VAL_5:.*]] = cmpi ule, %[[VAL_4]], %[[VAL_0]] : -// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = cond_br %[[VAL_5]], %[[VAL_2]] : , -// CHECK: %[[VAL_8:.*]] = extsi %[[VAL_7]] : to -// CHECK: end %[[VAL_8]] : +// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i32} : <>, +// CHECK: %[[VAL_4:.*]] = cmpi ule, %[[VAL_3]], %[[VAL_0]] : +// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = cond_br %[[VAL_4]], %[[VAL_2]] : , +// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_6]] : to +// CHECK: end %[[VAL_7]] : // CHECK: } handshake.func @boundUleCstFlip(%arg0: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %bound = constant %start {value = 16 : i6} : <>, @@ -65,7 +62,8 @@ handshake.func @boundUleCstFlip(%arg0: !handshake.channel, %start: !handsha // ----- // CHECK-LABEL: handshake.func @argUleArg( -// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, %[[VAL_1:.*]]: !handshake.channel, +// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, +// CHECK-SAME: %[[VAL_1:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_2:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "bound", "start"], resNames = ["out0"]} { // CHECK: %[[VAL_3:.*]] = trunci %[[VAL_0]] {handshake.bb = 0 : ui32} : to // CHECK: %[[VAL_4:.*]] = extsi %[[VAL_1]] : to @@ -84,26 +82,24 @@ handshake.func @argUleArg(%arg0: !handshake.channel, %bound: !handshake.cha // ----- // CHECK-LABEL: handshake.func @mulCmps( -// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, %[[VAL_1:.*]]: !handshake.channel, +// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, +// CHECK-SAME: %[[VAL_1:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_2:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "bound", "start"], resNames = ["out0"]} { // CHECK: %[[VAL_3:.*]] = trunci %[[VAL_0]] {handshake.bb = 0 : ui32} : to -// CHECK: %[[VAL_4:.*]] = constant %[[VAL_2]] {value = false} : <>, -// CHECK: %[[VAL_5:.*]] = constant %[[VAL_2]] {value = 50 : i7} : <>, -// CHECK: %[[VAL_6:.*]] = constant %[[VAL_2]] {value = 100 : i8} : <>, -// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_4]] : to -// CHECK: %[[VAL_8:.*]] = extsi %[[VAL_5]] : to -// CHECK: %[[VAL_9:.*]] = extsi %[[VAL_6]] : to -// CHECK: %[[VAL_10:.*]] = extsi %[[VAL_1]] : to -// CHECK: %[[VAL_11:.*]] = cmpi uge, %[[VAL_0]], %[[VAL_7]] : -// CHECK: %[[VAL_12:.*]] = cmpi ult, %[[VAL_0]], %[[VAL_9]] : -// CHECK: %[[VAL_13:.*]] = cmpi ne, %[[VAL_0]], %[[VAL_8]] : -// CHECK: %[[VAL_14:.*]] = cmpi ult, %[[VAL_0]], %[[VAL_10]] : -// CHECK: %[[VAL_15:.*]] = andi %[[VAL_11]], %[[VAL_12]] : -// CHECK: %[[VAL_16:.*]] = andi %[[VAL_13]], %[[VAL_14]] : -// CHECK: %[[VAL_17:.*]] = andi %[[VAL_15]], %[[VAL_16]] : -// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = cond_br %[[VAL_17]], %[[VAL_3]] : , -// CHECK: %[[VAL_20:.*]] = extsi %[[VAL_18]] : to -// CHECK: end %[[VAL_20]] : +// CHECK: %[[VAL_4:.*]] = constant %[[VAL_2]] {value = 0 : i32} : <>, +// CHECK: %[[VAL_5:.*]] = constant %[[VAL_2]] {value = 50 : i32} : <>, +// CHECK: %[[VAL_6:.*]] = constant %[[VAL_2]] {value = 100 : i32} : <>, +// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_1]] : to +// CHECK: %[[VAL_8:.*]] = cmpi uge, %[[VAL_0]], %[[VAL_4]] : +// CHECK: %[[VAL_9:.*]] = cmpi ult, %[[VAL_0]], %[[VAL_6]] : +// CHECK: %[[VAL_10:.*]] = cmpi ne, %[[VAL_0]], %[[VAL_5]] : +// CHECK: %[[VAL_11:.*]] = cmpi ult, %[[VAL_0]], %[[VAL_7]] : +// CHECK: %[[VAL_12:.*]] = andi %[[VAL_8]], %[[VAL_9]] : +// CHECK: %[[VAL_13:.*]] = andi %[[VAL_10]], %[[VAL_11]] : +// CHECK: %[[VAL_14:.*]] = andi %[[VAL_12]], %[[VAL_13]] : +// CHECK: %[[VAL_15:.*]], %[[VAL_16:.*]] = cond_br %[[VAL_14]], %[[VAL_3]] : , +// CHECK: %[[VAL_17:.*]] = extsi %[[VAL_15]] : to +// CHECK: end %[[VAL_17]] : // CHECK: } handshake.func @mulCmps(%arg0: !handshake.channel, %bound: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel { %0 = constant %start {value = 0 : i1} : <>, @@ -129,19 +125,17 @@ handshake.func @mulCmps(%arg0: !handshake.channel, %bound: !handshake.chann // CHECK-LABEL: handshake.func @simpleLoop( // CHECK-SAME: %[[VAL_0:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["start"], resNames = ["out0"]} { // CHECK: %[[VAL_1:.*]] = source : <> -// CHECK: %[[VAL_2:.*]] = constant %[[VAL_0]] {value = false} : <>, -// CHECK: %[[VAL_3:.*]] = extsi %[[VAL_2]] : to -// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]] {value = 16 : i6} : <>, -// CHECK: %[[VAL_5:.*]] = constant %[[VAL_1]] {value = 1 : i2} : <>, -// CHECK: %[[VAL_6:.*]] = extsi %[[VAL_5]] : to -// CHECK: %[[VAL_7:.*]] = merge %[[VAL_3]], %[[VAL_8:.*]] : -// CHECK: %[[VAL_9:.*]] = extsi %[[VAL_7]] : to -// CHECK: %[[VAL_10:.*]] = addi %[[VAL_9]], %[[VAL_6]] : -// CHECK: %[[VAL_11:.*]] = cmpi ult, %[[VAL_10]], %[[VAL_4]] : -// CHECK: %[[VAL_12:.*]], %[[VAL_13:.*]] = cond_br %[[VAL_11]], %[[VAL_10]] : , -// CHECK: %[[VAL_14:.*]] = extsi %[[VAL_13]] : to -// CHECK: %[[VAL_8]] = trunci %[[VAL_12]] : to -// CHECK: end %[[VAL_14]] : +// CHECK: %[[VAL_2:.*]] = constant %[[VAL_0]] {value = 0 : i5} : <>, +// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 16 : i6} : <>, +// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]] {value = 1 : i6} : <>, +// CHECK: %[[VAL_5:.*]] = merge %[[VAL_2]], %[[VAL_6:.*]] : +// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_5]] : to +// CHECK: %[[VAL_8:.*]] = addi %[[VAL_7]], %[[VAL_4]] : +// CHECK: %[[VAL_9:.*]] = cmpi ult, %[[VAL_8]], %[[VAL_3]] : +// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = cond_br %[[VAL_9]], %[[VAL_8]] : , +// CHECK: %[[VAL_12:.*]] = extsi %[[VAL_11]] : to +// CHECK: %[[VAL_6]] = trunci %[[VAL_10]] : to +// CHECK: end %[[VAL_12]] : // CHECK: } handshake.func @simpleLoop(%start: !handshake.control<>) -> !handshake.channel { %source = source : <> @@ -160,53 +154,48 @@ handshake.func @simpleLoop(%start: !handshake.control<>) -> !handshake.channel, ...) -> !handshake.channel attributes {argNames = ["start"], resNames = ["out0"]} { // CHECK: %[[VAL_1:.*]] = source {handshake.bb = 0 : ui32} : <> // CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 16 : i6} : <>, -// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = false} : <>, -// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_3]] : to -// CHECK: %[[VAL_5:.*]] = extsi %[[VAL_3]] : to -// CHECK: %[[VAL_6:.*]] = constant %[[VAL_1]] {value = 1 : i2} : <>, -// CHECK: %[[VAL_7:.*]] = extsi %[[VAL_6]] : to -// CHECK: %[[VAL_8:.*]], %[[VAL_9:.*]] = control_merge [%[[VAL_0]], %[[VAL_10:.*]]] : [<>, <>] to <>, -// CHECK: %[[VAL_11:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_5]], %[[VAL_12:.*]]] : , [, ] to -// CHECK: %[[VAL_13:.*]] = mux %[[VAL_9]] {{\[}}%[[VAL_4]], %[[VAL_14:.*]]] : , [, ] to -// CHECK: %[[VAL_15:.*]] = extsi %[[VAL_13]] : to -// CHECK: %[[VAL_16:.*]] = addi %[[VAL_15]], %[[VAL_7]] : -// CHECK: %[[VAL_17:.*]] = trunci %[[VAL_16]] : to -// CHECK: %[[VAL_18:.*]] = cmpi ult, %[[VAL_16]], %[[VAL_2]] : -// CHECK: %[[VAL_14]], %[[VAL_19:.*]] = cond_br %[[VAL_18]], %[[VAL_17]] : , -// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = cond_br %[[VAL_18]], %[[VAL_11]] : , -// CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = cond_br %[[VAL_18]], %[[VAL_8]] : , <> -// CHECK: %[[VAL_24:.*]] = source : <> -// CHECK: %[[VAL_25:.*]] = constant %[[VAL_24]] {value = 32 : i7} : <>, -// CHECK: %[[VAL_26:.*]] = constant %[[VAL_24]] {value = false} : <>, -// CHECK: %[[VAL_27:.*]] = extsi %[[VAL_26]] : to -// CHECK: %[[VAL_28:.*]] = constant %[[VAL_24]] {value = 1 : i2} : <>, -// CHECK: %[[VAL_29:.*]] = extsi %[[VAL_28]] : to -// CHECK: %[[VAL_30:.*]], %[[VAL_31:.*]] = control_merge [%[[VAL_22]], %[[VAL_32:.*]]] : [<>, <>] to <>, -// CHECK: %[[VAL_33:.*]] = mux %[[VAL_31]] {{\[}}%[[VAL_20]], %[[VAL_34:.*]]] : , [, ] to -// CHECK: %[[VAL_35:.*]] = mux %[[VAL_31]] {{\[}}%[[VAL_27]], %[[VAL_36:.*]]] : , [, ] to -// CHECK: %[[VAL_37:.*]] = extsi %[[VAL_35]] : to -// CHECK: %[[VAL_38:.*]] = addi %[[VAL_37]], %[[VAL_29]] : -// CHECK: %[[VAL_39:.*]] = trunci %[[VAL_38]] : to -// CHECK: %[[VAL_40:.*]] = cmpi ult, %[[VAL_38]], %[[VAL_25]] : -// CHECK: %[[VAL_36]], %[[VAL_41:.*]] = cond_br %[[VAL_40]], %[[VAL_39]] : , -// CHECK: %[[VAL_42:.*]], %[[VAL_12]] = cond_br %[[VAL_40]], %[[VAL_33]] : , -// CHECK: %[[VAL_43:.*]], %[[VAL_10]] = cond_br %[[VAL_40]], %[[VAL_30]] : , <> -// CHECK: %[[VAL_44:.*]] = source : <> -// CHECK: %[[VAL_45:.*]] = constant %[[VAL_44]] {value = 10 : i5} : <>, -// CHECK: %[[VAL_46:.*]] = extsi %[[VAL_45]] : to -// CHECK: %[[VAL_47:.*]], %[[VAL_48:.*]] = control_merge [%[[VAL_43]]] : [<>] to <>, -// CHECK: %[[VAL_49:.*]] = merge %[[VAL_42]] : -// CHECK: %[[VAL_50:.*]] = addi %[[VAL_49]], %[[VAL_46]] : -// CHECK: %[[VAL_34]] = br %[[VAL_50]] : -// CHECK: %[[VAL_32]] = br %[[VAL_47]] : <> -// CHECK: %[[VAL_51:.*]] = merge %[[VAL_21]] : -// CHECK: end %[[VAL_51]] : +// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 0 : i5} : <>, +// CHECK: %[[VAL_4:.*]] = constant %[[VAL_1]] {value = 0 : i32} : <>, +// CHECK: %[[VAL_5:.*]] = constant %[[VAL_1]] {value = 1 : i6} : <>, +// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = control_merge {{\[}}%[[VAL_0]], %[[VAL_8:.*]]] : [<>, <>] to <>, +// CHECK: %[[VAL_9:.*]] = mux %[[VAL_7]] {{\[}}%[[VAL_4]], %[[VAL_10:.*]]] : , [, ] to +// CHECK: %[[VAL_11:.*]] = mux %[[VAL_7]] {{\[}}%[[VAL_3]], %[[VAL_12:.*]]] : , [, ] to +// CHECK: %[[VAL_13:.*]] = extsi %[[VAL_11]] : to +// CHECK: %[[VAL_14:.*]] = addi %[[VAL_13]], %[[VAL_5]] : +// CHECK: %[[VAL_15:.*]] = trunci %[[VAL_14]] : to +// CHECK: %[[VAL_16:.*]] = cmpi ult, %[[VAL_14]], %[[VAL_2]] : +// CHECK: %[[VAL_12]], %[[VAL_17:.*]] = cond_br %[[VAL_16]], %[[VAL_15]] : , +// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]] = cond_br %[[VAL_16]], %[[VAL_9]] : , +// CHECK: %[[VAL_20:.*]], %[[VAL_21:.*]] = cond_br %[[VAL_16]], %[[VAL_6]] : , <> +// CHECK: %[[VAL_22:.*]] = source : <> +// CHECK: %[[VAL_23:.*]] = constant %[[VAL_22]] {value = 32 : i7} : <>, +// CHECK: %[[VAL_24:.*]] = constant %[[VAL_22]] {value = 0 : i6} : <>, +// CHECK: %[[VAL_25:.*]] = constant %[[VAL_22]] {value = 1 : i7} : <>, +// CHECK: %[[VAL_26:.*]], %[[VAL_27:.*]] = control_merge {{\[}}%[[VAL_20]], %[[VAL_28:.*]]] : [<>, <>] to <>, +// CHECK: %[[VAL_29:.*]] = mux %[[VAL_27]] {{\[}}%[[VAL_18]], %[[VAL_30:.*]]] : , [, ] to +// CHECK: %[[VAL_31:.*]] = mux %[[VAL_27]] {{\[}}%[[VAL_24]], %[[VAL_32:.*]]] : , [, ] to +// CHECK: %[[VAL_33:.*]] = extsi %[[VAL_31]] : to +// CHECK: %[[VAL_34:.*]] = addi %[[VAL_33]], %[[VAL_25]] : +// CHECK: %[[VAL_35:.*]] = trunci %[[VAL_34]] : to +// CHECK: %[[VAL_36:.*]] = cmpi ult, %[[VAL_34]], %[[VAL_23]] : +// CHECK: %[[VAL_32]], %[[VAL_37:.*]] = cond_br %[[VAL_36]], %[[VAL_35]] : , +// CHECK: %[[VAL_38:.*]], %[[VAL_10]] = cond_br %[[VAL_36]], %[[VAL_29]] : , +// CHECK: %[[VAL_39:.*]], %[[VAL_8]] = cond_br %[[VAL_36]], %[[VAL_26]] : , <> +// CHECK: %[[VAL_40:.*]] = source : <> +// CHECK: %[[VAL_41:.*]] = constant %[[VAL_40]] {value = 10 : i32} : <>, +// CHECK: %[[VAL_42:.*]], %[[VAL_43:.*]] = control_merge {{\[}}%[[VAL_39]]] : [<>] to <>, +// CHECK: %[[VAL_44:.*]] = merge %[[VAL_38]] : +// CHECK: %[[VAL_45:.*]] = addi %[[VAL_44]], %[[VAL_41]] : +// CHECK: %[[VAL_30]] = br %[[VAL_45]] : +// CHECK: %[[VAL_28]] = br %[[VAL_42]] : <> +// CHECK: %[[VAL_46:.*]] = merge %[[VAL_19]] : +// CHECK: end %[[VAL_46]] : // CHECK: } - handshake.func @nestedLoop(%start: !handshake.control<>) -> !handshake.channel { // ^^entry outer loop: %sourceOut = source {handshake.bb = 0 : ui32} : <> diff --git a/test/Transforms/HandshakeOptimizeBitwidths/handshake-special.mlir b/test/Transforms/HandshakeOptimizeBitwidths/handshake-special.mlir index 875dfaca57..e5a392fd41 100644 --- a/test/Transforms/HandshakeOptimizeBitwidths/handshake-special.mlir +++ b/test/Transforms/HandshakeOptimizeBitwidths/handshake-special.mlir @@ -4,7 +4,7 @@ // CHECK-LABEL: handshake.func @cmergeToMuxIndexOpt( // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, %[[VAL_1:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_2:.*]]: !handshake.control<>, ...) -> (!handshake.channel, !handshake.channel) attributes {argNames = ["arg0", "arg1", "start"], resNames = ["out0", "out1"]} { -// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge [%[[VAL_0]], %[[VAL_1]]] : [, ] to , +// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge {{\[}}%[[VAL_0]], %[[VAL_1]]] : [, ] to , // CHECK: %[[VAL_5:.*]] = mux %[[VAL_4]] {{\[}}%[[VAL_0]], %[[VAL_1]]] : , [, ] to // CHECK: end %[[VAL_3]], %[[VAL_5]] : , // CHECK: } @@ -19,8 +19,8 @@ handshake.func @cmergeToMuxIndexOpt(%arg0: !handshake.channel, %arg1: !hand // CHECK-LABEL: handshake.func @cmergeToMuxIndexOpt( // CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel, %[[VAL_1:.*]]: !handshake.channel, // CHECK-SAME: %[[VAL_2:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "arg1", "start"], resNames = ["out0"]} { -// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge [%[[VAL_0]]] : [] to , -// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = control_merge [%[[VAL_1]]] : [] to , +// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = control_merge {{\[}}%[[VAL_0]]] : [] to , +// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = control_merge {{\[}}%[[VAL_1]]] : [] to , // CHECK: %[[VAL_7:.*]] = extui %[[VAL_6]] : to // CHECK: %[[VAL_8:.*]] = addi %[[VAL_5]], %[[VAL_7]] : // CHECK: %[[VAL_9:.*]] = addi %[[VAL_8]], %[[VAL_3]] : @@ -40,19 +40,18 @@ handshake.func @cmergeToMuxIndexOpt(%arg0: !handshake.channel, %arg1: !hand // CHECK-LABEL: handshake.func @memAddrOpt( // CHECK-SAME: %[[VAL_0:.*]]: memref<1000xi32>, %[[VAL_1:.*]]: !handshake.control<>, %[[VAL_2:.*]]: !handshake.control<>, ...) -> (!handshake.channel, !handshake.control<>) attributes {argNames = ["mem", "mem_start", "start"], resNames = ["out0", "out1"]} { -// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = mem_controller{{\[}}%[[VAL_0]] : memref<1000xi32>] %[[VAL_1]] (%[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]], %[[VAL_9:.*]], %[[VAL_10:.*]]) %[[VAL_2]] {connectedBlocks = [0 : i32]} : (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> !handshake.channel -// CHECK: %[[VAL_11:.*]] = constant %[[VAL_2]] {value = 0 : i8} : <>, -// CHECK: %[[VAL_12:.*]] = extui %[[VAL_11]] : to -// CHECK: %[[VAL_13:.*]] = constant %[[VAL_2]] {value = 500 : i16} : <>, -// CHECK: %[[VAL_14:.*]] = trunci %[[VAL_13]] : to -// CHECK: %[[VAL_15:.*]] = constant %[[VAL_2]] {value = 999 : i32} : <>, -// CHECK: %[[VAL_16:.*]] = trunci %[[VAL_15]] : to -// CHECK: %[[VAL_17:.*]] = constant %[[VAL_2]] {value = 42 : i32} : <>, +// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = mem_controller{{\[}}%[[VAL_0]] : memref<1000xi32>] %[[VAL_1]] (%[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]], %[[VAL_9:.*]], %[[VAL_10:.*]]) %[[VAL_2]] {connectedBlocks = [0 : i32]} : (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> !handshake.channel +// CHECK: %[[VAL_11:.*]] = constant %[[VAL_2]] {value = 0 : i10} : <>, +// CHECK: %[[VAL_12:.*]] = constant %[[VAL_2]] {value = 500 : i16} : <>, +// CHECK: %[[VAL_13:.*]] = trunci %[[VAL_12]] : to +// CHECK: %[[VAL_14:.*]] = constant %[[VAL_2]] {value = 999 : i32} : <>, +// CHECK: %[[VAL_15:.*]] = trunci %[[VAL_14]] : to +// CHECK: %[[VAL_16:.*]] = constant %[[VAL_2]] {value = 42 : i32} : <>, // CHECK: %[[VAL_5]] = constant %[[VAL_2]] {handshake.bb = 0 : ui32, value = 2 : i32} : <>, -// CHECK: %[[VAL_6]], %[[VAL_18:.*]] = load{{\[}}%[[VAL_12]]] %[[VAL_3]] {handshake.bb = 0 : ui32} : , , , -// CHECK: %[[VAL_7]], %[[VAL_8]] = store{{\[}}%[[VAL_14]]] %[[VAL_17]] {handshake.bb = 0 : ui32} : , , , -// CHECK: %[[VAL_9]], %[[VAL_10]] = store{{\[}}%[[VAL_16]]] %[[VAL_17]] {handshake.bb = 0 : ui32} : , , , -// CHECK: end %[[VAL_18]], %[[VAL_4]] : , <> +// CHECK: %[[VAL_6]], %[[VAL_17:.*]] = load{{\[}}%[[VAL_11]]] %[[VAL_3]] {handshake.bb = 0 : ui32} : , , , +// CHECK: %[[VAL_7]], %[[VAL_8]] = store{{\[}}%[[VAL_13]]] %[[VAL_16]] {handshake.bb = 0 : ui32} : , , , +// CHECK: %[[VAL_9]], %[[VAL_10]] = store{{\[}}%[[VAL_15]]] %[[VAL_16]] {handshake.bb = 0 : ui32} : , , , +// CHECK: end %[[VAL_17]], %[[VAL_4]] : , <> // CHECK: } handshake.func @memAddrOpt(%mem: memref<1000xi32>, %mem_start: !handshake.control<>, %start: !handshake.control<>) -> (!handshake.channel, !handshake.control<>) { %ldData1, %done = mem_controller[%mem : memref<1000xi32>] %mem_start (%ctrl1, %ldAddr1, %stAddr1, %stData1, %stAddr2, %stData2) %start {connectedBlocks = [0 : i32]} : (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> !handshake.channel @@ -72,24 +71,23 @@ handshake.func @memAddrOpt(%mem: memref<1000xi32>, %mem_start: !handshake.contro // ----- + // CHECK-LABEL: handshake.func @memAddrOptMasterSlave( // CHECK-SAME: %[[VAL_0:.*]]: memref<1000xi32>, %[[VAL_1:.*]]: !handshake.control<>, %[[VAL_2:.*]]: !handshake.control<>, ...) -> (!handshake.channel, !handshake.control<>) attributes {argNames = ["mem", "mem_start", "start"], resNames = ["out0", "out1"]} { -// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = mem_controller{{\[}}%[[VAL_0]] : memref<1000xi32>] %[[VAL_1]] (%[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]]#1, %[[VAL_8]]#2, %[[VAL_8]]#3) %[[VAL_2]] {connectedBlocks = [0 : i32]} : (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> !handshake.channel +// CHECK: %[[VAL_3:.*]], %[[VAL_4:.*]] = mem_controller{{\[}}%[[VAL_0]] : memref<1000xi32>] %[[VAL_1]] (%[[VAL_5:.*]], %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]]#1, %[[VAL_8]]#2, %[[VAL_8]]#3) %[[VAL_2]] {connectedBlocks = [0 : i32]} : (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> !handshake.channel // CHECK: %[[VAL_8]]:4 = lsq[MC] (%[[VAL_2]], %[[VAL_9:.*]], %[[VAL_10:.*]], %[[VAL_11:.*]], %[[VAL_3]]) {groupSizes = [2 : i32]} : (!handshake.control<>, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -// CHECK: %[[VAL_12:.*]] = constant %[[VAL_2]] {value = 0 : i8} : <>, -// CHECK: %[[VAL_13:.*]] = extui %[[VAL_12]] : to -// CHECK: %[[VAL_14:.*]] = constant %[[VAL_2]] {value = 500 : i16} : <>, -// CHECK: %[[VAL_15:.*]] = trunci %[[VAL_14]] : to -// CHECK: %[[VAL_16:.*]] = constant %[[VAL_2]] {value = 999 : i32} : <>, -// CHECK: %[[VAL_17:.*]] = trunci %[[VAL_16]] : to -// CHECK: %[[VAL_18:.*]] = constant %[[VAL_2]] {value = 42 : i32} : <>, +// CHECK: %[[VAL_12:.*]] = constant %[[VAL_2]] {value = 0 : i10} : <>, +// CHECK: %[[VAL_13:.*]] = constant %[[VAL_2]] {value = 500 : i16} : <>, +// CHECK: %[[VAL_14:.*]] = trunci %[[VAL_13]] : to +// CHECK: %[[VAL_15:.*]] = constant %[[VAL_2]] {value = 999 : i32} : <>, +// CHECK: %[[VAL_16:.*]] = trunci %[[VAL_15]] : to +// CHECK: %[[VAL_17:.*]] = constant %[[VAL_2]] {value = 42 : i32} : <>, // CHECK: %[[VAL_5]] = constant %[[VAL_2]] {handshake.bb = 0 : ui32, value = 2 : i32} : <>, -// CHECK: %[[VAL_9]], %[[VAL_19:.*]] = load{{\[}}%[[VAL_13]]] %[[VAL_8]]#0 {handshake.bb = 0 : ui32} : , , , -// CHECK: %[[VAL_10]], %[[VAL_11]] = store{{\[}}%[[VAL_15]]] %[[VAL_18]] {handshake.bb = 0 : ui32} : , , , -// CHECK: %[[VAL_6]], %[[VAL_7]] = store{{\[}}%[[VAL_17]]] %[[VAL_18]] {handshake.bb = 0 : ui32} : , , , -// CHECK: end %[[VAL_19]], %[[VAL_4]] : , <> +// CHECK: %[[VAL_9]], %[[VAL_18:.*]] = load{{\[}}%[[VAL_12]]] %[[VAL_8]]#0 {handshake.bb = 0 : ui32} : , , , +// CHECK: %[[VAL_10]], %[[VAL_11]] = store{{\[}}%[[VAL_14]]] %[[VAL_17]] {handshake.bb = 0 : ui32} : , , , +// CHECK: %[[VAL_6]], %[[VAL_7]] = store{{\[}}%[[VAL_16]]] %[[VAL_17]] {handshake.bb = 0 : ui32} : , , , +// CHECK: end %[[VAL_18]], %[[VAL_4]] : , <> // CHECK: } - handshake.func @memAddrOptMasterSlave(%mem: memref<1000xi32>, %mem_start: !handshake.control<>, %start: !handshake.control<>) -> (!handshake.channel, !handshake.control<>) { %ldDataToLSQ, %done = mem_controller[%mem : memref<1000xi32>] %mem_start (%ctrl1, %stAddr2, %stData2, %ldAddrToMC, %stAddrToMC, %stdDataToMC) %start {connectedBlocks = [0 : i32]} : (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> !handshake.channel %ldData1, %ldAddrToMC, %stAddrToMC, %stdDataToMC = lsq[MC] (%start, %ldAddr1, %stAddr1, %stData1, %ldDataToLSQ) {groupSizes = [2 : i32]} : (!handshake.control<>, !handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) -> (!handshake.channel, !handshake.channel, !handshake.channel, !handshake.channel) diff --git a/test/Transforms/canonicalize.mlir b/test/Transforms/canonicalize.mlir new file mode 100644 index 0000000000..bf14ecf914 --- /dev/null +++ b/test/Transforms/canonicalize.mlir @@ -0,0 +1,26 @@ +// NOTE: Assertions have been autogenerated by utils/generate-test-checks.py +// RUN: dynamatic-opt --canonicalize %s --split-input-file | FileCheck %s + +// CHECK-LABEL: handshake.func @constantFoldExtUI( +// CHECK-SAME: %[[VAL_0:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["start"], resNames = ["out0"]} { +// CHECK: %[[VAL_1:.*]] = constant %[[VAL_0]] {value = 64170 : i32} : <>, +// CHECK: end %[[VAL_1]] : +// CHECK: } +handshake.func @constantFoldExtUI(%start: !handshake.control<>) -> !handshake.channel { + %c = constant %start {value = 0xFAAA : i16} : <>, + %d = extui %c : to + end %d : +} + +// ----- + +// CHECK-LABEL: handshake.func @constantFoldExtSI( +// CHECK-SAME: %[[VAL_0:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["start"], resNames = ["out0"]} { +// CHECK: %[[VAL_1:.*]] = constant %[[VAL_0]] {value = -1366 : i32} : <>, +// CHECK: end %[[VAL_1]] : +// CHECK: } +handshake.func @constantFoldExtSI(%start: !handshake.control<>) -> !handshake.channel { + %c = constant %start {value = 0xFAAA : i16} : <>, + %d = extsi %c : to + end %d : +}