Failed to legalize operation 'affine.vector_load'

I am trying to lowering toy lang to Vector.

  %cst = constant 1.000000e+00 : f64
    %cst_0 = constant 2.000000e+00 : f64
    %0 = memref.alloc() : memref<2x1xf64>
    %1 = memref.alloc() : memref<1x2xf64>
    affine.store %cst_0, %1[0, 0] : memref<1x2xf64>
    affine.store %cst, %1[0, 1] : memref<1x2xf64>
    affine.store %cst, %0[0, 0] : memref<2x1xf64>
    affine.store %cst_0, %0[1, 0] : memref<2x1xf64>
    %c0 = constant 0 : index
    %2 = affine.vector_load %0[%c0, %c0] : memref<2x1xf64>, vector<2xf64>
    %3 = affine.vector_load %1[%c0, %c0] : memref<1x2xf64>, vector<2xf64>
    %4 = vector.matrix_multiply %2, %3 {lhs_columns = 1 : i32, lhs_rows = 2 : i32, rhs_columns = 2 : i32} : (vector<2xf64>, vector<2xf64>) -> vector<4xf64>
    vector.print %4 : vector<4xf64>
    memref.dealloc %1 : memref<1x2xf64>
    memref.dealloc %0 : memref<2x1xf64>

I think vector_load is Grammarly correct. And I not know where issue is.

It’s unclear what you are trying to achieve, but the IR is perfectly valid. Affine operations can be lowered to a mix of SCF+Vector+Standard dialects using the -lower-affine (see mlir::createLowerAffinePass) pass.

1 Like

Now I got

builtin.module  {
  llvm.func @free(!llvm.ptr<i8>)
  llvm.func @printNewline()
  llvm.func @printClose()
  llvm.func @printComma()
  llvm.func @printOpen()
  llvm.func @printF64(f64)
  llvm.func @malloc(i64) -> !llvm.ptr<i8>
  llvm.func @main() {
    %0 = llvm.mlir.constant(1.000000e+00 : f64) : f64
    %1 = llvm.mlir.constant(2 : index) : i64
    %2 = llvm.mlir.constant(2 : index) : i64
    %3 = llvm.mlir.constant(1 : index) : i64
    %4 = llvm.mlir.constant(4 : index) : i64
    %5 = llvm.mlir.null : !llvm.ptr<f64>
    %6 = llvm.getelementptr %5[%4] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    %7 = llvm.ptrtoint %6 : !llvm.ptr<f64> to i64
    %8 = llvm.call @malloc(%7) : (i64) -> !llvm.ptr<i8>
    %9 = llvm.bitcast %8 : !llvm.ptr<i8> to !llvm.ptr<f64>
    %10 = llvm.mlir.undef : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %11 = llvm.insertvalue %9, %10[0] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %12 = llvm.insertvalue %9, %11[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %13 = llvm.mlir.constant(0 : index) : i64
    %14 = llvm.insertvalue %13, %12[2] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %15 = llvm.insertvalue %1, %14[3, 0] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %16 = llvm.insertvalue %2, %15[3, 1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %17 = llvm.insertvalue %2, %16[4, 0] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %18 = llvm.insertvalue %3, %17[4, 1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %19 = llvm.mlir.constant(0 : index) : i64
    %20 = llvm.mlir.constant(0 : index) : i64
    %21 = llvm.extractvalue %18[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %22 = llvm.mlir.constant(2 : index) : i64
    %23 = llvm.mul %19, %22  : i64
    %24 = llvm.add %23, %20  : i64
    %25 = llvm.getelementptr %21[%24] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    llvm.store %0, %25 : !llvm.ptr<f64>
    %26 = llvm.mlir.constant(0 : index) : i64
    %27 = llvm.mlir.constant(1 : index) : i64
    %28 = llvm.extractvalue %18[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %29 = llvm.mlir.constant(2 : index) : i64
    %30 = llvm.mul %26, %29  : i64
    %31 = llvm.add %30, %27  : i64
    %32 = llvm.getelementptr %28[%31] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    llvm.store %0, %32 : !llvm.ptr<f64>
    %33 = llvm.mlir.constant(1 : index) : i64
    %34 = llvm.mlir.constant(0 : index) : i64
    %35 = llvm.extractvalue %18[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %36 = llvm.mlir.constant(2 : index) : i64
    %37 = llvm.mul %33, %36  : i64
    %38 = llvm.add %37, %34  : i64
    %39 = llvm.getelementptr %35[%38] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    llvm.store %0, %39 : !llvm.ptr<f64>
    %40 = llvm.mlir.constant(1 : index) : i64
    %41 = llvm.mlir.constant(1 : index) : i64
    %42 = llvm.extractvalue %18[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %43 = llvm.mlir.constant(2 : index) : i64
    %44 = llvm.mul %40, %43  : i64
    %45 = llvm.add %44, %41  : i64
    %46 = llvm.getelementptr %42[%45] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    llvm.store %0, %46 : !llvm.ptr<f64>
    %47 = llvm.mlir.constant(0 : index) : i64
    %48 = llvm.extractvalue %18[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %49 = llvm.mlir.constant(2 : index) : i64
    %50 = llvm.mul %47, %49  : i64
    %51 = llvm.add %50, %47  : i64
    %52 = llvm.getelementptr %48[%51] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    %53 = llvm.bitcast %52 : !llvm.ptr<f64> to !llvm.ptr<vector<4xf64>>
    %54 = llvm.load %53 {alignment = 8 : i64} : !llvm.ptr<vector<4xf64>>
    %55 = llvm.extractvalue %18[1] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %56 = llvm.mlir.constant(2 : index) : i64
    %57 = llvm.mul %47, %56  : i64
    %58 = llvm.add %57, %47  : i64
    %59 = llvm.getelementptr %55[%58] : (!llvm.ptr<f64>, i64) -> !llvm.ptr<f64>
    %60 = llvm.bitcast %59 : !llvm.ptr<f64> to !llvm.ptr<vector<4xf64>>
    %61 = llvm.load %60 {alignment = 8 : i64} : !llvm.ptr<vector<4xf64>>
    %62 = llvm.intr.matrix.multiply %54, %61 {lhs_columns = 2 : i32, lhs_rows = 2 : i32, rhs_columns = 2 : i32} : (vector<4xf64>, vector<4xf64>) -> vector<4xf64>
    llvm.call @printOpen() : () -> ()
    %63 = llvm.mlir.constant(0 : index) : i64
    %64 = llvm.extractelement %62[%63 : i64] : vector<4xf64>
    llvm.call @printF64(%64) : (f64) -> ()
    llvm.call @printComma() : () -> ()
    %65 = llvm.mlir.constant(1 : index) : i64
    %66 = llvm.extractelement %62[%65 : i64] : vector<4xf64>
    llvm.call @printF64(%66) : (f64) -> ()
    llvm.call @printComma() : () -> ()
    %67 = llvm.mlir.constant(2 : index) : i64
    %68 = llvm.extractelement %62[%67 : i64] : vector<4xf64>
    llvm.call @printF64(%68) : (f64) -> ()
    llvm.call @printComma() : () -> ()
    %69 = llvm.mlir.constant(3 : index) : i64
    %70 = llvm.extractelement %62[%69 : i64] : vector<4xf64>
    llvm.call @printF64(%70) : (f64) -> ()
    llvm.call @printClose() : () -> ()
    llvm.call @printNewline() : () -> ()
    %71 = llvm.extractvalue %18[0] : !llvm.struct<(ptr<f64>, ptr<f64>, i64, array<2 x i64>, array<2 x i64>)>
    %72 = llvm.bitcast %71 : !llvm.ptr<f64> to !llvm.ptr<i8>
    llvm.call @free(%72) : (!llvm.ptr<i8>) -> ()
    llvm.return
  }
}

Is there Any pass can remove this?

builtin.module

mlir-cpu-runner says custom op 'builtin.module' is unknown

This works for me, as it should. Which version of MLIR are you using? Does mlir-cpu-runner come from the same version as mlir-opt? There has been recently a change that prefixes module with builtin and older versions may not understand it.

Thank lot. I rebuild mlir and it works!!! :tada: