1// RUN: mlir-opt %s -finalizing-bufferize -split-input-file -verify-diagnostics | FileCheck %s
2
3// CHECK-LABEL:   func @eliminate_materializations(
4// CHECK-SAME:                                     %[[ARG:.*]]: memref<f32>) -> memref<f32> {
5// CHECK:           return %[[ARG]] : memref<f32>
6func.func @eliminate_materializations(%arg0: memref<f32>) -> memref<f32> {
7  %0 = bufferization.to_tensor %arg0 : memref<f32>
8  %1 = bufferization.to_memref %0 : memref<f32>
9  return %1 : memref<f32>
10}
11
12// -----
13
14func.func @unable_to_convert_lone_buffer_cast() -> memref<f32> {
15  // expected-error @+1 {{failed to legalize operation 'test.source'}}
16  %0 = "test.source"() : () -> tensor<f32>
17  %1 = bufferization.to_memref %0 : memref<f32>
18  return %1 : memref<f32>
19}
20
21// -----
22
23func.func @unable_to_convert_lone_tensor_load(%arg0: memref<f32>) {
24  %0 = bufferization.to_tensor %arg0 : memref<f32>
25  // expected-error @+1 {{failed to legalize operation 'test.sink'}}
26  "test.sink"(%0) : (tensor<f32>) -> ()
27  return
28}
29
30// -----
31
32//       CHECK: #[[$map1:.*]] = affine_map<(d0)[s0] -> (d0 + s0)>
33// CHECK-LABEL: func @dyn_layout_to_no_layout_cast(
34//  CHECK-SAME:     %[[arg:.*]]: memref<?xf32, #[[$map1]]>)
35//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
36//       CHECK:   %[[dim:.*]] = memref.dim %[[arg]], %[[c0]]
37//       CHECK:   %[[alloc:.*]] = memref.alloc(%[[dim]]) : memref<?xf32>
38//       CHECK:   memref.copy %[[arg]], %[[alloc]]
39//       CHECK:   return %[[alloc]]
40#map1 = affine_map<(d0)[s0] -> (d0 + s0)>
41func.func @dyn_layout_to_no_layout_cast(%m: memref<?xf32, #map1>) -> memref<?xf32> {
42  %0 = bufferization.to_tensor %m : memref<?xf32, #map1>
43  %1 = bufferization.to_memref %0 : memref<?xf32>
44  return %1 : memref<?xf32>
45}
46
47// -----
48
49//       CHECK: #[[$map2:.*]] = affine_map<(d0)[s0] -> (d0 * 100 + s0)>
50// CHECK-LABEL: func @fancy_layout_to_no_layout_cast(
51//  CHECK-SAME:     %[[arg:.*]]: memref<?xf32, #[[$map2]]>)
52//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
53//       CHECK:   %[[dim:.*]] = memref.dim %[[arg]], %[[c0]]
54//       CHECK:   %[[alloc:.*]] = memref.alloc(%[[dim]]) : memref<?xf32>
55//       CHECK:   memref.copy %[[arg]], %[[alloc]]
56//       CHECK:   return %[[alloc]]
57#map2 = affine_map<(d0)[s0] -> (d0 * 100 + s0)>
58func.func @fancy_layout_to_no_layout_cast(%m: memref<?xf32, #map2>) -> memref<?xf32> {
59  %0 = bufferization.to_tensor %m : memref<?xf32, #map2>
60  %1 = bufferization.to_memref %0 : memref<?xf32>
61  return %1 : memref<?xf32>
62}
63
64// -----
65
66//       CHECK: #[[$map3:.*]] = affine_map<(d0)[s0] -> (d0 + 25)>
67// CHECK-LABEL: func @static_layout_to_no_layout_cast(
68//  CHECK-SAME:     %[[arg:.*]]: memref<?xf32, #[[$map3]]>)
69//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
70//       CHECK:   %[[dim:.*]] = memref.dim %[[arg]], %[[c0]]
71//       CHECK:   %[[alloc:.*]] = memref.alloc(%[[dim]]) : memref<?xf32>
72//       CHECK:   memref.copy %[[arg]], %[[alloc]]
73//       CHECK:   return %[[alloc]]
74#map3 = affine_map<(d0)[s0] -> (d0 + 25)>
75func.func @static_layout_to_no_layout_cast(%m: memref<?xf32, #map3>) -> memref<?xf32> {
76  %0 = bufferization.to_tensor %m : memref<?xf32, #map3>
77  %1 = bufferization.to_memref %0 : memref<?xf32>
78  return %1 : memref<?xf32>
79}
80
81// -----
82
83// TODO: to_memref with layout maps not supported yet. This should fold to a
84// memref.cast.
85#map4 = affine_map<(d0)[s0] -> (d0 + s0)>
86func.func @no_layout_to_dyn_layout_cast(%m: memref<?xf32>) -> memref<?xf32, #map4> {
87  %0 = bufferization.to_tensor %m : memref<?xf32>
88  // expected-error @+1 {{failed to materialize conversion for result #0 of operation 'bufferization.to_memref' that remained live after conversion}}
89  %1 = bufferization.to_memref %0 : memref<?xf32, #map4>
90  // expected-note @+1 {{see existing live user here}}
91  return %1 : memref<?xf32, #map4>
92}
93
94// -----
95
96func.func @illegal_unranked_to_rank(%m: memref<*xf32>) -> memref<?xf32> {
97  // expected-note @+1 {{prior use here}}
98  %0 = bufferization.to_tensor %m : memref<*xf32>
99  // expected-error @+1 {{expects different type than prior uses: 'tensor<?xf32>' vs 'tensor<*xf32>'}}
100  %1 = bufferization.to_memref %0 : memref<?xf32>
101  return %1 : memref<?xf32>
102}
103