Description
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.