Skip to content

[MLIR] ArithToLLVM fails to convert arith.index_cast operations with memref operands #92377

Open
@andidr

Description

@andidr

The ArithToLLVM pass fails with an error message when the IR contains an arith.index_cast operation with a memref operand and an integer element type type that does not match the width of the index type. E.g., on AMD64:

$ cat debug/index_cast_i32.mlir
module {
  func.func @main(%arg0: memref<3xi32>) -> memref<3xindex> {
    %0 = arith.index_cast %arg0 : memref<3xi32> to memref<3xindex>
    return %0 : memref<3xindex>
  }
}
$ mlir-opt debug/index_cast_i32.mlir --convert-func-to-llvm
debug/index_cast_i32.mlir:3:10: error: 'llvm.sext' op operand #0 must be integer or LLVM dialect-compatible vector of integer, but got '!llvm.struct<(ptr<i32>, ptr<i32>, i64, array<1 x i64>, array<1 x i64>)>'
    %0 = arith.index_cast %arg0 : memref<3xi32> to memref<3xindex>
         ^
debug/sext_i32.mlir:3:10: note: see current operation: %6 = "llvm.sext"(%5) : (!llvm.struct<(ptr<i32>, ptr<i32>, i64, array<1 x i64>, array<1 x i64>)>) -> !llvm.struct<(ptr<i64>, ptr<i64>, i64, array<1 x i64>, array<1 x i64>)>

This is because the code of the rewriting pattern from IndexCastOpLowering<OpTy, ExtCastTy>::matchAndRewrite() in mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp only handles scalar and vector operands. Memref operands are treated the same way as scalars, resulting in an llvm.sext operation with the converted type of a memref, i.e., an !llvm.struct<...>, which fails verification later on.

I'd love to extend the pattern so that it also handles operations with memref operands, but the semantics of arith.index_cast operating on memrefs are unclear to me. I wouldn't expect the operation to allocate a new memref, but since there is no "output" operand, this is the only option to store the result. However, allocation of a new buffer would have consequences on memory management that cannot be treated directly in the pass, which would make it no longer self-contained.

Maybe @Mogball can clarify the semantics?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions