Lowering CF to LLVM

Hi folks!
I have troubles lowering the CF dialect to the LLVM dialect. Below is a simplified version of the issue.

module  {
  func.func @name(){
    %c0 = arith.constant 0 : index
    cf.br ^bb1(%c0 : index)

  ^bb1(%0: index):  // 2 preds: ^bb0, ^bb2
    %c1 = arith.constant 1 : i1
    cf.cond_br %c1, ^bb2, ^bb3

  ^bb2:  // pred: ^bb1
    %c2 = arith.constant 2 : index
    cf.br ^bb1(%c2 : index)

  ^bb3:  // pred: ^bb1

Running mlir-opt --convert-cf-to-llvm results in the following error:

cant_lower.mlir:5:5: error: type mismatch for bb argument #0 of successor #0
    cf.br ^bb1(%c0 : index)
cant_lower.mlir:5:5: note: see current operation: "llvm.br"(%1)[^bb1] : (i64) -> ()

The same error arises with mlir-opt --pass-pipeline='convert-cf-to-llvm{index-bitwidth=64}'

Are there any issues with the source code or the commands being used?
Or are some intermediate steps necessary to lower the source to the LLVM dialect?

I would assume LLVMTypeConverter should handle this as part of dialect conversion within this pass. Is this built at head? (I also see only one test for this pass and it’s not run in isolation, so it may be that is always run with another that does some of its lifting but that’s a bug).

1 Like

The used built is @00a1258
I will build at head and see if the issue persists

Seems the same issue as here: [MLIR] Conversion from cf to llvm dialect fails for basic blocks with index arguments · Issue #55301 · llvm/llvm-project · GitHub

1 Like

Thank you for the hint!
I’ll see if I can help fixing it

For anyone who faces the same challenge, I’ve written a simple pass that can resolve the issue:

This is because the block parameters are currently being updated by convert-func-to-llvm, so a command like the following will succeed mlir-opt --convert-func-to-llvm --convert-arith-to-llvm --convert-cf-to-llvm. I am looking into allowing convert-cf-to-llvm to handle these blocks to more precisely behave as you expected and not create an error in your example, but note that it’s probably in your interest to not execute a partial conversion at such a late stage as when going to LLVMIR.

This situation is hopefully improved with: [mlir] Only conditionally lower CF branching ops to LLVM · llvm/llvm-project@448adfe · GitHub

Note, that this would not make your original example succeed, but it should provide insights into the reason when running with --debug and create less confusion as the ops would fail to lower to LLVM in the first place.