Skip to content

[MLIR] Incorrect fusion pass behavior with -test-loop-fusion=test-loop-fusion-transformation #132172

Open
@Lambor24

Description

@Lambor24

My git version is 6003c30.

Description:

I am experiencing an inconsistent result when executing the same MLIR program with and without the -test-loop-fusion=test-loop-fusion-transformation.

Steps to Reproduce:

1. MLIR Program (test.mlir):

test.mlir:

module {
  memref.global "private" constant @__constant_5x1x2x3xi16 : memref<5x1x2x3xi16> = dense<81> {alignment = 64 : i64}
  func.func private @printMemrefI16(memref<*xi16>) attributes {llvm.emit_c_interface}
  func.func @main() {
    %c81_i16 = arith.constant 81 : i16
    %c1_i16 = arith.constant 1 : i16
    %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x2x3xi16>
    affine.for %arg0 = 0 to 1 {
      affine.for %arg1 = 0 to 2 {
        affine.for %arg2 = 0 to 3 {
          affine.store %c1_i16, %alloc[%arg0, %arg1, %arg2] : memref<1x2x3xi16>
        }
      }
    }
    affine.for %arg0 = 0 to 5 {
      affine.for %arg1 = 0 to 1 {
        affine.for %arg2 = 0 to 2 {
          affine.for %arg3 = 0 to 3 {
            %0 = affine.load %alloc[%arg1, %arg2, %arg3] : memref<1x2x3xi16>
            %1 = arith.muli %0, %c81_i16 : i16
            affine.store %1, %alloc[%arg1, %arg2, %arg3] : memref<1x2x3xi16>
          }
        }
      }
    }
    %expand_shape = memref.expand_shape %alloc [[0, 1], [2], [3]] output_shape [1, 1, 2, 3] : memref<1x2x3xi16> into memref<1x1x2x3xi16>
    %cast = memref.cast %expand_shape : memref<1x1x2x3xi16> to memref<*xi16>
    call @printMemrefI16(%cast) : (memref<*xi16>) -> ()
    return
  }
}

output:

module {
  memref.global "private" constant @__constant_5x1x2x3xi16 : memref<5x1x2x3xi16> = dense<81> {alignment = 64 : i64}
  func.func private @printMemrefI16(memref<*xi16>) attributes {llvm.emit_c_interface}
  func.func @main() {
    %c0 = arith.constant 0 : index
    %c81_i16 = arith.constant 81 : i16
    %c1_i16 = arith.constant 1 : i16
    %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x2x3xi16>
    affine.for %arg0 = 0 to 5 {
      affine.for %arg1 = 0 to 1 {
        affine.for %arg2 = 0 to 2 {
          affine.for %arg3 = 0 to 3 {
            affine.store %c1_i16, %alloc[%c0, %arg2, %arg3] : memref<1x2x3xi16>
            %0 = affine.load %alloc[%arg1, %arg2, %arg3] : memref<1x2x3xi16>
            %1 = arith.muli %0, %c81_i16 : i16
            affine.store %1, %alloc[%arg1, %arg2, %arg3] : memref<1x2x3xi16>
          }
        }
      }
    }
    %expand_shape = memref.expand_shape %alloc [[0, 1], [2], [3]] output_shape [1, 1, 2, 3] : memref<1x2x3xi16> into memref<1x1x2x3xi16>
    %cast = memref.cast %expand_shape : memref<1x1x2x3xi16> to memref<*xi16>
    call @printMemrefI16(%cast) : (memref<*xi16>) -> ()
    return
  }
}

Obviously, the two nested loops here should not fuse together.

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