Skip to content

Commit

Permalink
[HWArith] Make hwarith.icmp result an i1 (#7413)
Browse files Browse the repository at this point in the history
As discussed in #7406. Resolves #7406.
  • Loading branch information
teqdruid authored Aug 9, 2024
1 parent 36a3a42 commit 562036c
Showing 4 changed files with 16 additions and 29 deletions.
15 changes: 7 additions & 8 deletions docs/Dialects/HWArith/RationaleHWArith.md
Original file line number Diff line number Diff line change
@@ -483,19 +483,18 @@ can be simplified to:
%4 = hwarith.icmp lt %0, %1 : si3, ui5
```

Note that the result of the comparison is *always* of type `ui1`, regardless of
the operands. So if the `i1` type is needed, the result must be cast
accordingly.
Note that the result of the comparison is *always* of type `i1` since the
logical result is a boolean, which doesn't have signedness semantics.

#### Overview

| | LHS type | RHS type | Comparison type | Result type |
| - | :------- | :------- | :--------------------------------------- | :---------- |
|(U)| `ui<a>` | `ui<b>` | `ui<r>`, *r* = max(*a*, *b*) | `ui1` |
|(S)| `si<a>` | `si<b>` | `si<r>`, *r* = max(*a*, *b*) | `ui1` |
|(M)| `ui<a>` | `si<b>` | `si<r>`, *r* = *a* + 1 **if** *a**b* | `ui1` |
| | | | `si<r>`, *r* = *b* **if** *a* < *b* | `ui1` |
|(M)| `si<a>` | `ui<b>` | Same as `ui<b> si<a>` | `ui1` |
|(U)| `ui<a>` | `ui<b>` | `ui<r>`, *r* = max(*a*, *b*) | `i1` |
|(S)| `si<a>` | `si<b>` | `si<r>`, *r* = max(*a*, *b*) | `i1` |
|(M)| `ui<a>` | `si<b>` | `si<r>`, *r* = *a* + 1 **if** *a**b* | `i1` |
| | | | `si<r>`, *r* = *b* **if** *a* < *b* | `i1` |
|(M)| `si<a>` | `ui<b>` | Same as `ui<b> si<a>` | `i1` |

#### Examples
```mlir
14 changes: 7 additions & 7 deletions include/circt/Dialect/HWArith/HWArithOps.td
Original file line number Diff line number Diff line change
@@ -227,16 +227,16 @@ def ICmpOp : HWArithOp<"icmp", [Pure]> {
let description = [{
The `icmp` operation compares two integers using a predicate. If the
predicate is true, returns 1, otherwise returns 0. This operation always
returns a one bit wide result of type `ui1`. Both operand types may be
returns a one bit wide result of type `i1`. Both operand types may be
signed or unsigned scalar integer types of arbitrary bitwidth.

| LHS type | RHS type | Comparison type | Result type |
| :------- | :------- | :--------------------------------------- | :---------- |
| `ui<a>` | `ui<b>` | `ui<r>`, *r* = max(*a*, *b*) | `ui1` |
| `si<a>` | `si<b>` | `si<r>`, *r* = max(*a*, *b*) | `ui1` |
| `ui<a>` | `si<b>` | `si<r>`, *r* = *a* + 1 **if** *a* ≥ *b* | `ui1` |
| | | `si<r>`, *r* = *b* **if** *a* < *b* | `ui1` |
| `si<a>` | `ui<b>` | Same as `ui<b> si<a>` | `ui1` |
| `ui<a>` | `ui<b>` | `ui<r>`, *r* = max(*a*, *b*) | `i1` |
| `si<a>` | `si<b>` | `si<r>`, *r* = max(*a*, *b*) | `i1` |
| `ui<a>` | `si<b>` | `si<r>`, *r* = *a* + 1 **if** *a* ≥ *b* | `i1` |
| | | `si<r>`, *r* = *b* **if** *a* < *b* | `i1` |
| `si<a>` | `ui<b>` | Same as `ui<b> si<a>` | `i1` |

Examples:
```mlir
@@ -248,7 +248,7 @@ def ICmpOp : HWArithOp<"icmp", [Pure]> {

let arguments = (ins ICmpPredicate:$predicate,
HWArithIntegerType:$lhs, HWArithIntegerType:$rhs);
let results = (outs UI1:$result);
let results = (outs I1:$result);

let assemblyFormat = "$predicate $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)";
}
14 changes: 2 additions & 12 deletions test/Conversion/HWArithToHW/test_basic.mlir
Original file line number Diff line number Diff line change
@@ -243,13 +243,8 @@ hw.module @icmp(in %op0: i32, in %op1: i32, out sisi: i1, out siui: i1, out uisi
// CHECK: %[[UIUI_OUT:.*]] = comb.icmp ult %op0, %op1 : i32
%uiui = hwarith.icmp lt %op0Unsigned, %op1Unsigned : ui32, ui32

%sisiOut = hwarith.cast %sisi : (ui1) -> i1
%siuiOut = hwarith.cast %siui : (ui1) -> i1
%uisiOut = hwarith.cast %uisi : (ui1) -> i1
%uiuiOut = hwarith.cast %uiui : (ui1) -> i1

// CHECK: hw.output %[[SISI_OUT]], %[[SIUI_OUT]], %[[UISI_OUT]], %[[UIUI_OUT]] : i1, i1, i1, i1
hw.output %sisiOut, %siuiOut, %uisiOut, %uiuiOut : i1, i1, i1, i1
hw.output %sisi, %siui, %uisi, %uiui: i1, i1, i1, i1
}

// -----
@@ -285,13 +280,8 @@ hw.module @icmp_mixed_width(in %op0: i5, in %op1: i7, out sisi: i1, out siui: i1
// CHECK: %[[UIUI_OUT:.*]] = comb.icmp ult %[[OP0_PADDED]], %op1 : i7
%uiui = hwarith.icmp lt %op0Unsigned, %op1Unsigned : ui5, ui7

%sisiOut = hwarith.cast %sisi : (ui1) -> i1
%siuiOut = hwarith.cast %siui : (ui1) -> i1
%uisiOut = hwarith.cast %uisi : (ui1) -> i1
%uiuiOut = hwarith.cast %uiui : (ui1) -> i1

// CHECK: hw.output %[[SISI_OUT]], %[[SIUI_OUT]], %[[UISI_OUT]], %[[UIUI_OUT]] : i1, i1, i1, i1
hw.output %sisiOut, %siuiOut, %uisiOut, %uiuiOut : i1, i1, i1, i1
hw.output %sisi, %siui, %uisi, %uiui: i1, i1, i1, i1
}

// -----
2 changes: 0 additions & 2 deletions test/Dialect/HWArith/basic.mlir
Original file line number Diff line number Diff line change
@@ -33,6 +33,4 @@ hw.module @test1() {
%12 = hwarith.cast %11 : (si10) -> i9
// CHECK: %13 = hwarith.icmp eq %5, %10 : ui2, si9
%13 = hwarith.icmp eq %5, %10 : ui2, si9
// CHECK: %14 = hwarith.cast %13 : (ui1) -> i1
%14 = hwarith.cast %13 : (ui1) -> i1
}

0 comments on commit 562036c

Please sign in to comment.