Why aren't these vector ops converted to LLVM?

Hello,

I see some vector.transfer_read ops in my code that never get converted to LLVM. I’m not sure whether it’s me or MLIR doing something wrong :slight_smile: I’ve extracted a couple of small repro:

//  `vector.transfer_read` _is_ converted
func.func @transfer_read(%A : memref<27xf32>, %C: index, %D: f32) -> vector<17xf32> {
  %f = vector.transfer_read %A[%C], %D : memref<27xf32>, vector<17xf32>
  return %f: vector<17xf32>
}

// -----

//  `vector.transfer_read` _is not_ converted
func.func @transfer_read(%A : tensor<27xf32>,  %C : index, %D : f32) -> vector<17xf32> {
  %f = vector.transfer_read %A[%C], %D : tensor<27xf32>, vector<17xf32>
  return %f: vector<17xf32>
}

You can run it like this:

mlir-opt -one-shot-bufferize -func-bufferize  -convert-vector-to-llvm -split-input-file file.mlir

In the first case vector.transfer_read is replaced with ops from the LLVM dialect, but in the 2nd it remains intact. I have other cases too, but this is the most basic one.

Your pointers are much appreciated!
-Andrzej

The problem is that bufferization won’t know the stride of the memref passed to the function therefore we end up with a memref with a dynamic stride and the lowering of transfer_read doesn’t support that right now.

 func.func @transfer_read(%arg0: memref<27xf32> {bufferization.buffer_layout = affine_map<(d0) -> (d0)>}, %arg1: index, %arg2: f32) -> vector<17xf32> {
    %0 = bufferization.to_tensor %arg0 : memref<27xf32>
    %1 = bufferization.to_memref %0 : memref<27xf32, strided<[?], offset: ?>>
    %2 = vector.transfer_read %1[%arg1], %arg2 : memref<27xf32, strided<[?], offset: ?>>, vector<17xf32>
    return %2 : vector<17xf32>
  }

To avoid that you can add annotations, for instance this would work:

func.func @transfer_read(%A : tensor<27xf32> {bufferization.buffer_layout = affine_map<(d0) -> (d0)>},  %C : index, %D : f32) -> vector<17xf32> {
  %f = vector.transfer_read %A[%C], %D : tensor<27xf32>, vector<17xf32>
  return %f: vector<17xf32>
}

with this command line:
mlir-opt -one-shot-bufferize="bufferize-function-boundaries" -canonicalize -func-bufferize -convert-vector-to-llvm

Note that the best way to debug those problem is usually to use -debug command line option to see what patterns are failing.

1 Like