Skip to content

[MLIR] Conversion from cf to llvm dialect fails for basic blocks with index arguments #55301

Closed
@andidr

Description

@andidr

The pass cf-to-llvm fails for IR containing basic blocks with index arguments. The error occurs upon the invocation of the legalizer after the generation of cf.br ops during dialect conversion in OneToOneLLVMTerminatorLowering<cf::BranchOp, LLVM::BrOp>::matchAndRewrite() here. The cause seems to be an unrealized conversion cast that was generated as an unrealized target materialization.

The following example IR filling a single memref<2xi64> with the value 1:

module {
  func @foo(%arg0: memref<2xi64>) {
    %c0 = arith.constant 0 : index
    %c1 = arith.constant 1 : index
    %c2 = arith.constant 2 : index
    %c1_i64 = arith.constant 1 : i64
    cf.br ^bb1(%c0 : index)
  ^bb1(%0: index):  // 2 preds: ^bb0, ^bb2
    %1 = arith.cmpi slt, %0, %c2 : index
    cf.cond_br %1, ^bb2, ^bb3
  ^bb2:  // pred: ^bb1
    memref.store %c1_i64, %arg0[%0] : memref<2xi64>
    %2 = arith.addi %0, %c1 : index
    cf.br ^bb1(%2 : index)
  ^bb3:  // pred: ^bb1
    return
  }
}

triggers the error when running mlir-opt --convert-cf-to-llvm fill-memref.cf.mlir:

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

The last IR dump right before exiting with an error is:

// *** IR Dump After Pattern Application ***
"func.func"() ({
^bb0(%arg0: memref<2xi64>):
  %0 = "arith.constant"() {value = 0 : index} : () -> index
  %1 = "builtin.unrealized_conversion_cast"(%0) : (index) -> i64
  %2 = "arith.constant"() {value = 1 : index} : () -> index
  %3 = "arith.constant"() {value = 2 : index} : () -> index
  %4 = "arith.constant"() {value = 1 : i64} : () -> i64
  "llvm.br"(%1)[^bb1] : (i64) -> ()
  "cf.br"(%0)[^bb1] : (index) -> ()
^bb1(%5: index):  // 4 preds: ^bb0, ^bb0, ^bb2, ^bb2
  %6 = "arith.cmpi"(%5, %3) {predicate = 2 : i64} : (index, index) -> i1
  "llvm.cond_br"(%6)[^bb2, ^bb3] {operand_segment_sizes = dense<[1, 0, 0]> : vector<3xi32>} : (i1) -> ()
  "cf.cond_br"(%6)[^bb2, ^bb3] {operand_segment_sizes = dense<[1, 0, 0]> : vector<3xi32>} : (i1) -> ()
^bb2:  // 2 preds: ^bb1, ^bb1
  "memref.store"(%4, %arg0, %5) : (i64, memref<2xi64>, index) -> ()
  %7 = "arith.addi"(%5, %2) : (index, index) -> index
  %8 = "builtin.unrealized_conversion_cast"(%7) : (index) -> i64
  "llvm.br"(%8)[^bb1] : (i64) -> ()
  "cf.br"(%7)[^bb1] : (index) -> ()
^bb3:  // 2 preds: ^bb1, ^bb1
  "func.return"() : () -> ()
}) {function_type = (memref<2xi64>) -> (), sym_name = "foo"} : () -> ()

Tested with commit a65afce.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions