<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/64774>64774</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Flag `--canonicalize` is broken in `mlir-opt` with LLVM 16
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          azteca1998
      </td>
    </tr>
</table>

<pre>
    ## LLVM version

LLVM 16.0.6 in both Linux and Mac OS.

## MLIR input

```mlir
module {
 func.func public @felt2bool(%arg0: i252) -> !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)> attributes {llvm.emit_c_interface} {
 %c1_i64 = arith.constant 1 : i64
    %0 = llvm.alloca %c1_i64 x !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)> {alignment = 1 : i64} : (i64) -> !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>>
    %c1_i64_0 = arith.constant 1 : i64
    %1 = llvm.alloca %c1_i64_0 x !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)> {alignment = 1 : i64} : (i64) -> !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>>
    cf.br ^bb1(%arg0 : i252)
  ^bb1(%2: i252):  // pred: ^bb0
    cf.br ^bb2(%2 : i252)
  ^bb2(%3: i252):  // pred: ^bb1
    cf.br ^bb3(%3 : i252)
  ^bb3(%4: i252):  // pred: ^bb2
    cf.br ^bb4
  ^bb4:  // pred: ^bb3
    %c1_i252 = arith.constant 1 : i252
    cf.br ^bb5(%c1_i252 : i252)
  ^bb5(%5: i252):  // pred: ^bb4
    cf.br ^bb6(%5 : i252)
  ^bb6(%6: i252):  // pred: ^bb5
    cf.br ^bb7(%3 : i252)
  ^bb7(%7: i252):  // pred: ^bb6
    cf.br ^bb8(%5 : i252)
  ^bb8(%8: i252):  // pred: ^bb7
 cf.br ^bb9(%7, %8 : i252, i252)
  ^bb9(%9: i252, %10: i252):  // pred: ^bb8
    %11 = arith.extui %9 : i252 to i256
    %12 = arith.extui %10 : i252 to i256
    %13 = arith.subi %11, %12 : i256
 %c3618502788666131213697322783095070105623107215331596699973092056135872020481_i256 = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020481 : i256
    %14 = arith.addi %13, %c3618502788666131213697322783095070105623107215331596699973092056135872020481_i256 : i256
    %15 = arith.cmpi ult, %11, %12 : i256
    %16 = arith.select %15, %14, %13 : i256
    %17 = arith.trunci %16 : i256 to i252
 cf.br ^bb10(%17 : i252)
  ^bb10(%18: i252):  // pred: ^bb9
    cf.br ^bb11(%18 : i252)
  ^bb11(%19: i252):  // pred: ^bb10
    %c0_i252 = arith.constant 0 : i252
    %20 = arith.cmpi eq, %19, %c0_i252 : i252
 cf.cond_br %20, ^bb12, ^bb17
  ^bb12:  // pred: ^bb11
    cf.br ^bb13
  ^bb13:  // pred: ^bb12
    %21 = llvm.mlir.undef : !llvm.struct<()>
    cf.br ^bb14(%21 : !llvm.struct<()>)
  ^bb14(%22: !llvm.struct<()>):  // pred: ^bb13
    %true = arith.constant true
 %23 = llvm.mlir.undef : !llvm.struct<(i1, array<0 x i8>, struct<()>)>
 %24 = llvm.insertvalue %true, %23[0] : !llvm.struct<(i1, array<0 x i8>, struct<()>)> 
    %25 = llvm.insertvalue %22, %24[2] : !llvm.struct<(i1, array<0 x i8>, struct<()>)> 
    %26 = llvm.bitcast %1 : !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>> to !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>)>>
    llvm.store %25, %26 {alignment = 1 : i64} : !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>)>>
    %27 = llvm.load %1 {alignment = 1 : i64} : !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>>
 cf.br ^bb15(%27 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>)
  ^bb15(%28: !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>):  // pred: ^bb14
    cf.br ^bb16
  ^bb16:  // pred: ^bb15
 cf.br ^bb22(%28 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>)
  ^bb17:  // pred: ^bb11
    cf.br ^bb18(%19 : i252)
 ^bb18(%29: i252):  // pred: ^bb17
    cf.br ^bb19
  ^bb19:  // pred: ^bb18
    %30 = llvm.mlir.undef : !llvm.struct<()>
    cf.br ^bb20(%30 : !llvm.struct<()>)
  ^bb20(%31: !llvm.struct<()>):  // pred: ^bb19
 %false = arith.constant false
    %32 = llvm.mlir.undef : !llvm.struct<(i1, array<0 x i8>, struct<()>)>
    %33 = llvm.insertvalue %false, %32[0] : !llvm.struct<(i1, array<0 x i8>, struct<()>)> 
    %34 = llvm.insertvalue %31, %33[2] : !llvm.struct<(i1, array<0 x i8>, struct<()>)> 
    %35 = llvm.bitcast %0 : !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>> to !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>)>>
    llvm.store %34, %35 {alignment = 1 : i64} : !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>)>>
    %36 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>>
    cf.br ^bb21(%36 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>)
  ^bb21(%37: !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>):  // pred: ^bb20
    cf.br ^bb22(%37 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>)
  ^bb22(%38: !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>):  // 2 preds: ^bb16, ^bb21
    cf.br ^bb23(%38 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>)
  ^bb23(%39: !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>):  // pred: ^bb22
    cf.br ^bb24(%39 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>)
  ^bb24(%40: !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>):  // pred: ^bb23
    return %39 : !llvm.struct<(i1, array<0 x i8>, struct<()>, array<0 x i8>)>
  }
}
```

## Expected behaviour

When calling `felt2bool::felt2bool::felt_to_bool` with `0`, `1`, and `2` it should return `false`, `true`, `false` (the first value of the returned struct, aka the `i1`). Invoking it after conversion without canonicalization works as expected, however when adding the `--canonicalize` flag it returns the wrong value when the argument is `0`.

In other words, for an input of `0`, `1` and `2`, the outputs are:
  - Expected: `false`, `true`, `false` (works correctly without `--canonicalize`).
  - Actual: `false`, `true`, `false` (actual behaviour with `--canonicalize`).

## Steps to reproduce

Write the following piece of code in `felt2bool.c`:
```c
#include <stdint.h>
#include <stdio.h>


void _mlir_ciface_felt2bool(uint8_t *dst, uint64_t, uint64_t, uint64_t, uint64_t);


int main()
{
    size_t i;
    uint8_t dst;

    for (i = 0; i < 3; i++)
    {
 _mlir_ciface_felt2bool(&dst, i, 0, 0, 0);
        printf("felt2bool(%lu) = %s\n", i, dst ? "true" : "false");
    }

    return 0;
}
```

Store the MLIR code as `felt2bool.mlir`. Then, compile the source code into LLVM IR both with and without `--canonicalize`:

```bash
cat felt2bool.mlir | mlir-opt-16 --convert-scf-to-cf --convert-func-to-llvm | mlir-translate-16 --mlir-to-llvmir > felt2bool-ok.ll
cat felt2bool.mlir | mlir-opt-16 --canonicalize --convert-scf-to-cf --convert-func-to-llvm | mlir-translate-16 --mlir-to-llvmir > felt2bool-err.ll
```

Build binaries for both versions:
```bash
clang-16 felt2bool.c felt2bool-ok.ll -o felt2bool-ok
clang-16 felt2bool.c felt2bool-err.ll -o felt2bool-err
```

Execute them:
```bash
./felt2bool-ok
./felt2bool-err
```

The output will be as follows:
```
$ ./felt2bool-ok 
felt2bool(0) = false
felt2bool(1) = true
felt2bool(2) = false
$ ./felt2bool-err 
felt2bool(0) = true
felt2bool(1) = true
felt2bool(2) = false
```
The `felt2bool-err`'s `felt2bool(0)` should print `false` to be correct.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkWl-P2y7W_jTMDUqEwcb2RS7mr1Sp1Sv9Wr17GWFMErYOZDGemfbTr8DYsRN7mtntpKvdUZRxgHOe5xzgnINtVtdyq4RYgeQOJA83rLE7bVbspxWcRXme3RS6_LECmABM4OfP__8FPgtTS60AegDotv327RFdoiWFUsFC2x38LFXzCpkq4RfG4f99XQ4Fgr4vnz_9BaU6NHbUSVH72VfStE17XTaVgCC9a3_DTaP40n3BQ1NUkkMQo42oLC60rgDOAE6Y2SJAbqHECQY4hwtAHiHAUVU975e1NQ23gNwDnMkI4HvIjGE_ALlH8BXKDJBH1zgcBnAeWieGui7IrDWyaKyoHVOPI_bSrvlaKivMhnEB0oeBFQAnPFpLGkNAHiAz0u6WXKvaMmVhBD17GofBELrxyA_1ullVac4GSl4_1jyQ3rFKbtVeKOtZHBk6q4izJ3O_Tp19sAaQ-4_g5D5D77SOWKPL_RnN-3ON_tc9yjfLwkCQPBZFdNxUcLCrurHDMXjYT1wnfgL4CR6MKL1NbiyaRMFBwyxEGEAugYgmIUjQMAsRBsSXQOBJiHikL56VJmdrtzV9buk6MlN4Scv4qGDasDAsucSweBKIBg2zEGEAvQQimYRIfzU9YUB6CQSdhMh-ZUUYkF0CkQbJgf68Y4jv3bxmA5z7SbwgkA_HudCELiGQjcNZNFg_4tU20rXmPQVotftPx0J4SihCv5AiA6m6KVqhqCPfr0M6SHaERlmCcJpllNKIRDgiNE8JxmlGUJ6gFEUooZhEKMVRQkiU5JTmeZ4SlGOU0IgkWYoRRnHmFzud2i2_E-TUiGD6MGGzsmxNJ8H0D7FyikUytH5_kLCpbOf--XkIwkPX1aIS3LY6O7m4uyAzCtKBAmsaxWWvtx0eVg0-3yERale81zGTS7ohF-3CfDpnRZ2OeZhuSH5RRkHjiI1mIzaaiNgusaHTKRP_6Pycd8sHnYTx3n1cq3LtjHOK_GhPCh8v07FxeN6S6eQYkbECMq_gxLBBHeXK9mWjSrEJJcx5BRVqjUkKcagBol9Jn05lJ4h_LTdr1TglW9OIqdl17ceohsm7bH9npTZwlMOKj1hS1cLYZ1Y5ki3ZsIQwAckdAsnD7yQBxxOezBLBXQLDMUju8MfSoEcahbSc1bar6m-vUy27KPfbgM4q8OAxbVrPdtHZmX3B2eGjWDkG6dHxlWZl8Pr1SF1wghlGlVD84vR3rcV5_NO41EFn10CejWzTFX1Ex1zpvILk3Ku4O69l1_dq-u7clnWpfqIaGI3AlxUD6TTMCc83FIxLd4J-VwrFoXYi6J0ptBeM_o0Umh-z1YZV9WQC9R1j6_GVkmiAI7Ppq-XWxlmCPzyRkvmMTroinpAPT6QkmUyk6L8zkZLudOPM_rOJlNDzRIr-wxLpSXgJZyZCrx71e-j0T-ZSPHPzsrs5ef0ao4e-do2BvWfqY_Sn_WEUT6dh3N2AvX7N0EPnf3T1TN_ExXFH7vp-CdAx-qN-GZy9jbCNUfBK7uh8kT6EB5D9RfckcuLZ5ePrQXArSliIHXuWujHDQX_bCQU5qyqpthDQwbNJcgvI7cTPtdVr30IRfJF256Q8tNtPFEXhkqnS_cRumLSw3ummKnt_UdRWL72YvynQ_-o6IcCZ3Qm4kaa2sK039Aa6plaTKDsXOsjvzHcBimRLI1_CT-pZf3fGSQvZxgoDuVbh0bDnrxsLOVNaSc4q-ZNZ36HN9xqyGorgPad_p1_EszDwxfmMlaXTGvAWi4EKz3xTMY_Z8qz9wBej1TaY4ZW4Rma2jc-esu5cOXoE_UlBbXcOVpuydjw22kCm2ufRzh3nEzD0vmt2OLqxh8bWkBnhJjOspUW_Pvzqfce8tC7i2hjBbfWj9-WUN9xMHBFvuW1Y9V485qWOq7hffG-gjTbCVysOtSvejDgYXTZcjDaCkVZ4R210VekXN7kHKbhfcFyXAko12iBL7qDI6bsAvMeUildN6Y4V97UtpbLLXb-Jz7v1sHfw_axlCdfupLHmcsO4WA9fH2ikstnaVcC3Ze03gWuh8frC6xyQu3NMqSzcM6lCUAqx5u4Y9mr5U6wtlL20a-y4OCJjra7XLVoXC32RiAC5g-7yHhJ_CfCd_wzujx8BZ60HmAarpftCw698xM39HYxUduPF8MkrGFUDcO6ZAZzUILlXoL056PWW7ohBniDAuL13iUOox-EIhk_hjoH5NFOgo2veDN5f_QnALUf_7olfgKweL0D_2glFS_htJ5QjyvX-IKtWrNaN4aJbuVa378R8-qt96cXvHRck3ty15HbydZeC1bu2iTMLx3wgSO-hu1jog11EFC4Wbby1i5pvFlYv-GbQtmkUd40uZx5FrWGqrpgVrYK2rR3kEMjjEXShvy-r6j1sBjZ-ODlhTM9ucprvGlmVsJCKGSlqv0n8_IQEVZ_Hl4HzK6a2jsQgJJ06Bi70qOkiyZb1WFQY84YZj6-CN2343L9FeQnw0zmdcevbSN_6TAZfZOXSgdsWbcie8FYXbWN4Ch3uKgwDAeqCwOCuz7A_6vqPj1WG3XhC_BxZGPMW9LTqfwV57IJvbZ0ydrNLlek4qAQuLueGks2HzVEyttq5PWT-5U25ImVOcnYjVhHNMc7SmCQ3u1VeFLwQaVKyYpOlKENZROKcpBtEKUcJupErjDBBWZRGSYJIstyUuSApRaJI8iKhBYiR2DNZLX1Jrc32RtZ1I1Y0TtP4pmKFqGr_QiDGSrxA3-micfJwY1ZOZlE02xrEqJK1rY9arLSVWD25Cm2ydpM1LIz-LlTI-V0E6Uve8B7hTWOq1c7ag195_qiwlXbXFEuu9wA_OcDwb3Ew-u_C1alPnmYN8JM3458BAAD__5tp4Xo">