648 lines · plain
1// RUN: mlir-opt -split-input-file -finalize-memref-to-llvm %s | FileCheck %s2// RUN: mlir-opt -split-input-file -finalize-memref-to-llvm='use-aligned-alloc=1' %s | FileCheck %s --check-prefix=ALIGNED-ALLOC3// RUN: mlir-opt -split-input-file -finalize-memref-to-llvm='index-bitwidth=32' %s | FileCheck --check-prefix=CHECK32 %s4 5// CHECK-LABEL: func @mixed_alloc(6// CHECK: %[[Marg:.*]]: index, %[[Narg:.*]]: index)7func.func @mixed_alloc(%arg0: index, %arg1: index) -> memref<?x42x?xf32> {8// CHECK-DAG: %[[M:.*]] = builtin.unrealized_conversion_cast %[[Marg]]9// CHECK-DAG: %[[N:.*]] = builtin.unrealized_conversion_cast %[[Narg]]10// CHECK: %[[c42:.*]] = llvm.mlir.constant(42 : index) : i6411// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : i6412// CHECK-NEXT: %[[st0:.*]] = llvm.mul %[[N]], %[[c42]] : i6413// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[st0]], %[[M]] : i6414// CHECK-NEXT: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr15// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr, i64) -> !llvm.ptr, f3216// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to i6417// CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (i64) -> !llvm.ptr18// CHECK-NEXT: llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>19// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>20// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>21// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : i6422// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>23// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>24// CHECK-NEXT: llvm.insertvalue %[[c42]], %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>25// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>26// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>27// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>28// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>29 %0 = memref.alloc(%arg0, %arg1) : memref<?x42x?xf32>30 return %0 : memref<?x42x?xf32>31}32 33// -----34 35// CHECK-LABEL: func @mixed_dealloc36func.func @mixed_dealloc(%arg0: memref<?x42x?xf32>) {37// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>38// CHECK-NEXT: llvm.call @free(%[[ptr]]) : (!llvm.ptr) -> ()39 memref.dealloc %arg0 : memref<?x42x?xf32>40 return41}42 43// -----44 45// CHECK-LABEL: func @unranked_dealloc46func.func @unranked_dealloc(%arg0: memref<*xf32>) {47// CHECK: %[[memref:.*]] = llvm.extractvalue %{{.*}} : !llvm.struct<(i64, ptr)>48// CHECK: %[[ptr:.*]] = llvm.load %[[memref]]49// CHECK-NEXT: llvm.call @free(%[[ptr]])50 memref.dealloc %arg0 : memref<*xf32>51 return52}53 54// -----55 56// CHECK-LABEL: func @dynamic_alloc(57// CHECK: %[[Marg:.*]]: index, %[[Narg:.*]]: index)58func.func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> {59// CHECK-DAG: %[[M:.*]] = builtin.unrealized_conversion_cast %[[Marg]]60// CHECK-DAG: %[[N:.*]] = builtin.unrealized_conversion_cast %[[Narg]]61// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : i6462// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[N]], %[[M]] : i6463// CHECK-NEXT: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr64// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr, i64) -> !llvm.ptr, f3265// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to i6466// CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (i64) -> !llvm.ptr67// CHECK-NEXT: llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>68// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>69// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>70// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : i6471// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>72// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>73// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>74// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>75// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>76 %0 = memref.alloc(%arg0, %arg1) : memref<?x?xf32>77 return %0 : memref<?x?xf32>78}79 80// -----81 82// CHECK-LABEL: func @dynamic_alloca83// CHECK: %[[Marg:.*]]: index, %[[Narg:.*]]: index)84func.func @dynamic_alloca(%arg0: index, %arg1: index) -> memref<?x?xf32> {85// CHECK-DAG: %[[M:.*]] = builtin.unrealized_conversion_cast %[[Marg]]86// CHECK-DAG: %[[N:.*]] = builtin.unrealized_conversion_cast %[[Narg]]87// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : i6488// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %[[N]], %[[M]] : i6489// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[num_elems]] x f32 : (i64) -> !llvm.ptr90// CHECK-NEXT: llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>91// CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>92// CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>93// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : i6494// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>95// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>96// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>97// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>98// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>99 %0 = memref.alloca(%arg0, %arg1) : memref<?x?xf32>100 101// Test with explicitly specified alignment. llvm.alloca takes care of the102// alignment. The same pointer is thus used for allocation and aligned103// accesses.104// CHECK: %[[alloca_aligned:.*]] = llvm.alloca %{{.*}} x f32 {alignment = 32 : i64} : (i64) -> !llvm.ptr105// CHECK: %[[desc:.*]] = llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>106// CHECK: %[[desc1:.*]] = llvm.insertvalue %[[alloca_aligned]], %[[desc]][0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>107// CHECK: llvm.insertvalue %[[alloca_aligned]], %[[desc1]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>108 memref.alloca(%arg0, %arg1) {alignment = 32} : memref<?x?xf32>109 return %0 : memref<?x?xf32>110}111 112// -----113 114// CHECK-LABEL: func @dynamic_dealloc115func.func @dynamic_dealloc(%arg0: memref<?x?xf32>) {116// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>117// CHECK-NEXT: llvm.call @free(%[[ptr]]) : (!llvm.ptr) -> ()118 memref.dealloc %arg0 : memref<?x?xf32>119 return120}121 122// -----123 124// CHECK-LABEL: func @stdlib_aligned_alloc({{.*}})125// ALIGNED-ALLOC-LABEL: func @stdlib_aligned_alloc({{.*}})126func.func @stdlib_aligned_alloc(%N : index) -> memref<32x18xf32> {127// ALIGNED-ALLOC: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : i64128// ALIGNED-ALLOC-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : i64129// ALIGNED-ALLOC-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : i64130// ALIGNED-ALLOC-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : i64131// ALIGNED-ALLOC-NEXT: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr132// ALIGNED-ALLOC-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32133// ALIGNED-ALLOC-NEXT: %[[bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to i64134// ALIGNED-ALLOC-NEXT: %[[alignment:.*]] = llvm.mlir.constant(32 : index) : i64135// ALIGNED-ALLOC-NEXT: %[[allocated:.*]] = llvm.call @aligned_alloc(%[[alignment]], %[[bytes]]) : (i64, i64) -> !llvm.ptr136 %0 = memref.alloc() {alignment = 32} : memref<32x18xf32>137 // Do another alloc just to test that we have a unique declaration for138 // aligned_alloc.139 // ALIGNED-ALLOC: llvm.call @aligned_alloc140 %1 = memref.alloc() {alignment = 64} : memref<4096xf32>141 142 // Alignment is to element type boundaries (minimum 16 bytes).143 // ALIGNED-ALLOC: %[[c32:.*]] = llvm.mlir.constant(32 : index) : i64144 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c32]]145 %2 = memref.alloc() : memref<4096xvector<8xf32>>146 // The minimum alignment is 16 bytes unless explicitly specified.147 // ALIGNED-ALLOC: %[[c16:.*]] = llvm.mlir.constant(16 : index) : i64148 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c16]],149 %3 = memref.alloc() : memref<4096xvector<2xf32>>150 // ALIGNED-ALLOC: %[[c8:.*]] = llvm.mlir.constant(8 : index) : i64151 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c8]],152 %4 = memref.alloc() {alignment = 8} : memref<1024xvector<4xf32>>153 // Bump the memref allocation size if its size is not a multiple of alignment.154 // ALIGNED-ALLOC: %[[c32:.*]] = llvm.mlir.constant(32 : index) : i64155 // ALIGNED-ALLOC: llvm.mlir.constant(1 : index) : i64156 // ALIGNED-ALLOC-NEXT: llvm.sub157 // ALIGNED-ALLOC-NEXT: llvm.add158 // ALIGNED-ALLOC-NEXT: llvm.urem159 // ALIGNED-ALLOC-NEXT: %[[SIZE_ALIGNED:.*]] = llvm.sub160 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c32]], %[[SIZE_ALIGNED]])161 %5 = memref.alloc() {alignment = 32} : memref<100xf32>162 // Bump alignment to the next power of two if it isn't.163 // ALIGNED-ALLOC: %[[c128:.*]] = llvm.mlir.constant(128 : index) : i64164 // ALIGNED-ALLOC: llvm.call @aligned_alloc(%[[c128]]165 %6 = memref.alloc(%N) : memref<?xvector<18xf32>>166 return %0 : memref<32x18xf32>167}168 169// -----170 171// CHECK-LABEL: func @mixed_load(172// CHECK: %{{.*}}, %[[Iarg:.*]]: index, %[[Jarg:.*]]: index)173func.func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) {174// CHECK-DAG: %[[I:.*]] = builtin.unrealized_conversion_cast %[[Iarg]]175// CHECK-DAG: %[[J:.*]] = builtin.unrealized_conversion_cast %[[Jarg]]176// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>177// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>178// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] overflow<nsw, nuw> : i64179// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] overflow<nsw, nuw> : i64180// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr inbounds|nuw %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32181// CHECK-NEXT: llvm.load %[[addr]] : !llvm.ptr -> f32182 %0 = memref.load %mixed[%i, %j] : memref<42x?xf32>183 return184}185 186// -----187 188// CHECK-LABEL: func @dynamic_load(189// CHECK: %{{.*}}, %[[Iarg:.*]]: index, %[[Jarg:.*]]: index)190func.func @dynamic_load(%dynamic : memref<?x?xf32>, %i : index, %j : index) {191// CHECK-DAG: %[[I:.*]] = builtin.unrealized_conversion_cast %[[Iarg]]192// CHECK-DAG: %[[J:.*]] = builtin.unrealized_conversion_cast %[[Jarg]]193// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>194// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>195// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] overflow<nsw, nuw> : i64196// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] overflow<nsw, nuw> : i64197// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr inbounds|nuw %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32198// CHECK-NEXT: llvm.load %[[addr]] : !llvm.ptr -> f32199 %0 = memref.load %dynamic[%i, %j] : memref<?x?xf32>200 return201}202 203// -----204 205// CHECK-LABEL: func @prefetch206// CHECK: %{{.*}}, %[[Iarg:.*]]: index, %[[Jarg:.*]]: index)207func.func @prefetch(%A : memref<?x?xf32>, %i : index, %j : index) {208// CHECK-DAG: %[[I:.*]] = builtin.unrealized_conversion_cast %[[Iarg]]209// CHECK-DAG: %[[J:.*]] = builtin.unrealized_conversion_cast %[[Jarg]]210// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>211// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>212// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : i64213// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : i64214// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32215// CHECK-NEXT: "llvm.intr.prefetch"(%[[addr]]) <{cache = 1 : i32, hint = 3 : i32, rw = 1 : i32}> : (!llvm.ptr) -> ()216 memref.prefetch %A[%i, %j], write, locality<3>, data : memref<?x?xf32>217// CHECK: "llvm.intr.prefetch"(%{{.*}}) <{cache = 1 : i32, hint = 0 : i32, rw = 0 : i32}> : (!llvm.ptr) -> ()218 memref.prefetch %A[%i, %j], read, locality<0>, data : memref<?x?xf32>219// CHECK: "llvm.intr.prefetch"(%{{.*}}) <{cache = 0 : i32, hint = 2 : i32, rw = 0 : i32}> : (!llvm.ptr) -> ()220 memref.prefetch %A[%i, %j], read, locality<2>, instr : memref<?x?xf32>221 return222}223 224// -----225 226// CHECK-LABEL: func @dynamic_store227// CHECK: %{{.*}}, %[[Iarg:.*]]: index, %[[Jarg:.*]]: index228func.func @dynamic_store(%dynamic : memref<?x?xf32>, %i : index, %j : index, %val : f32) {229// CHECK-DAG: %[[I:.*]] = builtin.unrealized_conversion_cast %[[Iarg]]230// CHECK-DAG: %[[J:.*]] = builtin.unrealized_conversion_cast %[[Jarg]]231// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>232// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>233// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] overflow<nsw, nuw> : i64234// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] overflow<nsw, nuw> : i64235// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr inbounds|nuw %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32236// CHECK-NEXT: llvm.store %{{.*}}, %[[addr]] : f32, !llvm.ptr237 memref.store %val, %dynamic[%i, %j] : memref<?x?xf32>238 return239}240 241// -----242 243// CHECK-LABEL: func @mixed_store244// CHECK: %{{.*}}, %[[Iarg:.*]]: index, %[[Jarg:.*]]: index245func.func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32) {246// CHECK-DAG: %[[I:.*]] = builtin.unrealized_conversion_cast %[[Iarg]]247// CHECK-DAG: %[[J:.*]] = builtin.unrealized_conversion_cast %[[Jarg]]248// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>249// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>250// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] overflow<nsw, nuw> : i64251// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] overflow<nsw, nuw> : i64252// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr inbounds|nuw %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32253// CHECK-NEXT: llvm.store %{{.*}}, %[[addr]] : f32, !llvm.ptr254 memref.store %val, %mixed[%i, %j] : memref<42x?xf32>255 return256}257 258// -----259 260// FIXME: the *ToLLVM passes don't use information from data layouts261// to set address spaces, so the constants below don't reflect the layout262// Update this test once that data layout attribute works how we'd expect it to.263module attributes { dlti.dl_spec = #dlti.dl_spec<264 #dlti.dl_entry<!llvm.ptr, dense<[64, 64, 64]> : vector<3xi64>>,265 #dlti.dl_entry<!llvm.ptr<1>, dense<[32, 32, 32]> : vector<3xi64>>> } {266 // CHECK-LABEL: @memref_memory_space_cast267 func.func @memref_memory_space_cast(%input : memref<*xf32>) -> memref<*xf32, 1> {268 %cast = memref.memory_space_cast %input : memref<*xf32> to memref<*xf32, 1>269 return %cast : memref<*xf32, 1>270 }271}272// CHECK: [[INPUT:%.*]] = builtin.unrealized_conversion_cast %{{.*}} to !llvm.struct<(i64, ptr)>273// CHECK: [[RANK:%.*]] = llvm.extractvalue [[INPUT]][0] : !llvm.struct<(i64, ptr)>274// CHECK: [[SOURCE_DESC:%.*]] = llvm.extractvalue [[INPUT]][1]275// CHECK: [[RESULT_0:%.*]] = llvm.mlir.poison : !llvm.struct<(i64, ptr)>276// CHECK: [[RESULT_1:%.*]] = llvm.insertvalue [[RANK]], [[RESULT_0]][0] : !llvm.struct<(i64, ptr)>277 278// Compute size in bytes to allocate result ranked descriptor279// CHECK: [[C1:%.*]] = llvm.mlir.constant(1 : index) : i64280// CHECK: [[C2:%.*]] = llvm.mlir.constant(2 : index) : i64281// CHECK: [[INDEX_SIZE:%.*]] = llvm.mlir.constant(8 : index) : i64282// CHECK: [[PTR_SIZE:%.*]] = llvm.mlir.constant(8 : index) : i64283// CHECK: [[DOUBLE_PTR_SIZE:%.*]] = llvm.mul [[C2]], [[PTR_SIZE]]284// CHECK: [[DOUBLE_RANK:%.*]] = llvm.mul [[C2]], %{{.*}}285// CHECK: [[NUM_INDEX_VALS:%.*]] = llvm.add [[DOUBLE_RANK]], [[C1]]286// CHECK: [[INDEX_VALS_SIZE:%.*]] = llvm.mul [[NUM_INDEX_VALS]], [[INDEX_SIZE]]287// CHECK: [[DESC_ALLOC_SIZE:%.*]] = llvm.add [[DOUBLE_PTR_SIZE]], [[INDEX_VALS_SIZE]]288// CHECK: [[RESULT_DESC:%.*]] = llvm.alloca [[DESC_ALLOC_SIZE]] x i8289// CHECK: llvm.insertvalue [[RESULT_DESC]], [[RESULT_1]][1]290 291// Cast pointers292// CHECK: [[SOURCE_ALLOC:%.*]] = llvm.load [[SOURCE_DESC]]293// CHECK: [[SOURCE_ALIGN_GEP:%.*]] = llvm.getelementptr [[SOURCE_DESC]][1]294// CHECK: [[SOURCE_ALIGN:%.*]] = llvm.load [[SOURCE_ALIGN_GEP]] : !llvm.ptr295// CHECK: [[RESULT_ALLOC:%.*]] = llvm.addrspacecast [[SOURCE_ALLOC]] : !llvm.ptr to !llvm.ptr<1>296// CHECK: [[RESULT_ALIGN:%.*]] = llvm.addrspacecast [[SOURCE_ALIGN]] : !llvm.ptr to !llvm.ptr<1>297// CHECK: llvm.store [[RESULT_ALLOC]], [[RESULT_DESC]] : !llvm.ptr298// CHECK: [[RESULT_ALIGN_GEP:%.*]] = llvm.getelementptr [[RESULT_DESC]][1]299// CHECK: llvm.store [[RESULT_ALIGN]], [[RESULT_ALIGN_GEP]] : !llvm.ptr300 301// Memcpy remaining values302 303// CHECK: [[SOURCE_OFFSET_GEP:%.*]] = llvm.getelementptr [[SOURCE_DESC]][2]304// CHECK: [[RESULT_OFFSET_GEP:%.*]] = llvm.getelementptr [[RESULT_DESC]][2]305// CHECK: [[SIZEOF_TWO_RESULT_PTRS:%.*]] = llvm.mlir.constant(16 : index) : i64306// CHECK: [[COPY_SIZE:%.*]] = llvm.sub [[DESC_ALLOC_SIZE]], [[SIZEOF_TWO_RESULT_PTRS]]307// CHECK: "llvm.intr.memcpy"([[RESULT_OFFSET_GEP]], [[SOURCE_OFFSET_GEP]], [[COPY_SIZE]]) <{isVolatile = false}>308 309// -----310 311// CHECK-LABEL: func @memref_cast_static_to_dynamic312func.func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) {313// CHECK-NOT: llvm.bitcast314 %0 = memref.cast %static : memref<10x42xf32> to memref<?x?xf32>315 return316}317 318// -----319 320// CHECK-LABEL: func @memref_cast_static_to_mixed321func.func @memref_cast_static_to_mixed(%static : memref<10x42xf32>) {322// CHECK-NOT: llvm.bitcast323 %0 = memref.cast %static : memref<10x42xf32> to memref<?x42xf32>324 return325}326 327// -----328 329// CHECK-LABEL: func @memref_cast_dynamic_to_static330func.func @memref_cast_dynamic_to_static(%dynamic : memref<?x?xf32>) {331// CHECK-NOT: llvm.bitcast332 %0 = memref.cast %dynamic : memref<?x?xf32> to memref<10x12xf32>333 return334}335 336// -----337 338// CHECK-LABEL: func @memref_cast_dynamic_to_mixed339func.func @memref_cast_dynamic_to_mixed(%dynamic : memref<?x?xf32>) {340// CHECK-NOT: llvm.bitcast341 %0 = memref.cast %dynamic : memref<?x?xf32> to memref<?x12xf32>342 return343}344 345// -----346 347// CHECK-LABEL: func @memref_cast_mixed_to_dynamic348func.func @memref_cast_mixed_to_dynamic(%mixed : memref<42x?xf32>) {349// CHECK-NOT: llvm.bitcast350 %0 = memref.cast %mixed : memref<42x?xf32> to memref<?x?xf32>351 return352}353 354// -----355 356// CHECK-LABEL: func @memref_cast_mixed_to_static357func.func @memref_cast_mixed_to_static(%mixed : memref<42x?xf32>) {358// CHECK-NOT: llvm.bitcast359 %0 = memref.cast %mixed : memref<42x?xf32> to memref<42x1xf32>360 return361}362 363// -----364 365// CHECK-LABEL: func @memref_cast_mixed_to_mixed366func.func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) {367// CHECK-NOT: llvm.bitcast368 %0 = memref.cast %mixed : memref<42x?xf32> to memref<?x1xf32>369 return370}371 372// -----373 374// CHECK-LABEL: func @memref_cast_ranked_to_unranked375// CHECK32-LABEL: func @memref_cast_ranked_to_unranked376func.func @memref_cast_ranked_to_unranked(%arg : memref<42x2x?xf32>) {377// CHECK-DAG: %[[c:.*]] = llvm.mlir.constant(1 : index) : i64378// CHECK-DAG: %[[p:.*]] = llvm.alloca %[[c]] x !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> : (i64) -> !llvm.ptr379// CHECK-DAG: llvm.store %{{.*}}, %[[p]] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>, !llvm.ptr380// CHECK-DAG: %[[r:.*]] = llvm.mlir.constant(3 : index) : i64381// CHECK: llvm.mlir.poison : !llvm.struct<(i64, ptr)>382// CHECK-DAG: llvm.insertvalue %[[r]], %{{.*}}[0] : !llvm.struct<(i64, ptr)>383// CHECK-DAG: llvm.insertvalue %[[p]], %{{.*}}[1] : !llvm.struct<(i64, ptr)>384// CHECK32-DAG: %[[c:.*]] = llvm.mlir.constant(1 : index) : i64385// CHECK32-DAG: %[[p:.*]] = llvm.alloca %[[c]] x !llvm.struct<(ptr, ptr, i32, array<3 x i32>, array<3 x i32>)> : (i64) -> !llvm.ptr386// CHECK32-DAG: llvm.store %{{.*}}, %[[p]] : !llvm.struct<(ptr, ptr, i32, array<3 x i32>, array<3 x i32>)>, !llvm.ptr387// CHECK32-DAG: %[[r:.*]] = llvm.mlir.constant(3 : index) : i32388// CHECK32: llvm.mlir.poison : !llvm.struct<(i32, ptr)>389// CHECK32-DAG: llvm.insertvalue %[[r]], %{{.*}}[0] : !llvm.struct<(i32, ptr)>390// CHECK32-DAG: llvm.insertvalue %[[p]], %{{.*}}[1] : !llvm.struct<(i32, ptr)>391 %0 = memref.cast %arg : memref<42x2x?xf32> to memref<*xf32>392 return393}394 395// -----396 397// CHECK-LABEL: func @memref_cast_unranked_to_ranked398func.func @memref_cast_unranked_to_ranked(%arg : memref<*xf32>) {399// CHECK: %[[p:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(i64, ptr)>400 %0 = memref.cast %arg : memref<*xf32> to memref<?x?x10x2xf32>401 return402}403 404// -----405 406// CHECK-LABEL: func @mixed_memref_dim407func.func @mixed_memref_dim(%mixed : memref<42x?x?x13x?xf32>) {408// CHECK: llvm.mlir.constant(42 : index) : i64409 %c0 = arith.constant 0 : index410 %0 = memref.dim %mixed, %c0 : memref<42x?x?x13x?xf32>411// CHECK: llvm.extractvalue %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<5 x i64>, array<5 x i64>)>412 %c1 = arith.constant 1 : index413 %1 = memref.dim %mixed, %c1 : memref<42x?x?x13x?xf32>414// CHECK: llvm.extractvalue %{{.*}}[3, 2] : !llvm.struct<(ptr, ptr, i64, array<5 x i64>, array<5 x i64>)>415 %c2 = arith.constant 2 : index416 %2 = memref.dim %mixed, %c2 : memref<42x?x?x13x?xf32>417// CHECK: llvm.mlir.constant(13 : index) : i64418 %c3 = arith.constant 3 : index419 %3 = memref.dim %mixed, %c3 : memref<42x?x?x13x?xf32>420// CHECK: llvm.extractvalue %{{.*}}[3, 4] : !llvm.struct<(ptr, ptr, i64, array<5 x i64>, array<5 x i64>)>421 %c4 = arith.constant 4 : index422 %4 = memref.dim %mixed, %c4 : memref<42x?x?x13x?xf32>423 return424}425 426// -----427 428// CHECK-LABEL: @memref_dim_with_dyn_index429// CHECK: %{{.*}}, %[[IDXarg:.*]]: index430func.func @memref_dim_with_dyn_index(%arg : memref<3x?xf32>, %idx : index) -> index {431 // CHECK-DAG: %[[IDX:.*]] = builtin.unrealized_conversion_cast %[[IDXarg]]432 // CHECK-DAG: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64433 // CHECK-DAG: %[[SIZES:.*]] = llvm.extractvalue %{{.*}}[3] : ![[DESCR_TY:.*]]434 // CHECK-DAG: %[[SIZES_PTR:.*]] = llvm.alloca %[[C1]] x !llvm.array<2 x i64> : (i64) -> !llvm.ptr435 // CHECK-DAG: llvm.store %[[SIZES]], %[[SIZES_PTR]] : !llvm.array<2 x i64>, !llvm.ptr436 // CHECK-DAG: %[[RESULT_PTR:.*]] = llvm.getelementptr %[[SIZES_PTR]][0, %[[IDX]]] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<2 x i64>437 // CHECK-DAG: %[[RESULT:.*]] = llvm.load %[[RESULT_PTR]] : !llvm.ptr -> i64438 %result = memref.dim %arg, %idx : memref<3x?xf32>439 return %result : index440}441 442// -----443 444// CHECK-LABEL: @memref_reinterpret_cast_ranked_to_static_shape445func.func @memref_reinterpret_cast_ranked_to_static_shape(%input : memref<2x3xf32>) {446 %output = memref.reinterpret_cast %input to447 offset: [0], sizes: [6, 1], strides: [1, 1]448 : memref<2x3xf32> to memref<6x1xf32>449 return450}451// CHECK: [[INPUT:%.*]] = builtin.unrealized_conversion_cast %{{.*}} :452// CHECK: to [[TY:!.*]]453// CHECK: [[OUT_0:%.*]] = llvm.mlir.poison : [[TY]]454// CHECK: [[BASE_PTR:%.*]] = llvm.extractvalue [[INPUT]][0] : [[TY]]455// CHECK: [[ALIGNED_PTR:%.*]] = llvm.extractvalue [[INPUT]][1] : [[TY]]456// CHECK: [[OUT_1:%.*]] = llvm.insertvalue [[BASE_PTR]], [[OUT_0]][0] : [[TY]]457// CHECK: [[OUT_2:%.*]] = llvm.insertvalue [[ALIGNED_PTR]], [[OUT_1]][1] : [[TY]]458// CHECK: [[OFFSET:%.*]] = llvm.mlir.constant(0 : index) : i64459// CHECK: [[OUT_3:%.*]] = llvm.insertvalue [[OFFSET]], [[OUT_2]][2] : [[TY]]460// CHECK: [[SIZE_0:%.*]] = llvm.mlir.constant(6 : index) : i64461// CHECK: [[OUT_4:%.*]] = llvm.insertvalue [[SIZE_0]], [[OUT_3]][3, 0] : [[TY]]462// CHECK: [[SIZE_1:%.*]] = llvm.mlir.constant(1 : index) : i64463// CHECK: [[OUT_5:%.*]] = llvm.insertvalue [[SIZE_1]], [[OUT_4]][4, 0] : [[TY]]464// CHECK: [[STRIDE_0:%.*]] = llvm.mlir.constant(1 : index) : i64465// CHECK: [[OUT_6:%.*]] = llvm.insertvalue [[STRIDE_0]], [[OUT_5]][3, 1] : [[TY]]466// CHECK: [[STRIDE_1:%.*]] = llvm.mlir.constant(1 : index) : i64467// CHECK: [[OUT_7:%.*]] = llvm.insertvalue [[STRIDE_1]], [[OUT_6]][4, 1] : [[TY]]468 469// -----470 471// CHECK-LABEL: @memref_reinterpret_cast_unranked_to_dynamic_shape472func.func @memref_reinterpret_cast_unranked_to_dynamic_shape(%offset: index,473 %size_0 : index,474 %size_1 : index,475 %stride_0 : index,476 %stride_1 : index,477 %input : memref<*xf32>) {478 %output = memref.reinterpret_cast %input to479 offset: [%offset], sizes: [%size_0, %size_1],480 strides: [%stride_0, %stride_1]481 : memref<*xf32> to memref<?x?xf32, strided<[?, ?], offset: ?>>482 return483}484// CHECK-SAME: ([[OFFSETarg:%[a-z,0-9]+]]: index,485// CHECK-SAME: [[SIZE_0arg:%[a-z,0-9]+]]: index, [[SIZE_1arg:%[a-z,0-9]+]]: index,486// CHECK-SAME: [[STRIDE_0arg:%[a-z,0-9]+]]: index, [[STRIDE_1arg:%[a-z,0-9]+]]: index,487// CHECK-DAG: [[OFFSET:%.*]] = builtin.unrealized_conversion_cast [[OFFSETarg]]488// CHECK-DAG: [[SIZE_0:%.*]] = builtin.unrealized_conversion_cast [[SIZE_0arg]]489// CHECK-DAG: [[SIZE_1:%.*]] = builtin.unrealized_conversion_cast [[SIZE_1arg]]490// CHECK-DAG: [[STRIDE_0:%.*]] = builtin.unrealized_conversion_cast [[STRIDE_0arg]]491// CHECK-DAG: [[STRIDE_1:%.*]] = builtin.unrealized_conversion_cast [[STRIDE_1arg]]492// CHECK-DAG: [[INPUT:%.*]] = builtin.unrealized_conversion_cast493// CHECK: [[OUT_0:%.*]] = llvm.mlir.poison : [[TY:!.*]]494// CHECK: [[DESCRIPTOR:%.*]] = llvm.extractvalue [[INPUT]][1] : !llvm.struct<(i64, ptr)>495// CHECK: [[BASE_PTR:%.*]] = llvm.load [[DESCRIPTOR]] : !llvm.ptr -> !llvm.ptr496// CHECK: [[ALIGNED_PTR_PTR:%.*]] = llvm.getelementptr [[DESCRIPTOR]]{{\[}}1]497// CHECK-SAME: : (!llvm.ptr) -> !llvm.ptr, !llvm.ptr498// CHECK: [[ALIGNED_PTR:%.*]] = llvm.load [[ALIGNED_PTR_PTR]] : !llvm.ptr -> !llvm.ptr499// CHECK: [[OUT_1:%.*]] = llvm.insertvalue [[BASE_PTR]], [[OUT_0]][0] : [[TY]]500// CHECK: [[OUT_2:%.*]] = llvm.insertvalue [[ALIGNED_PTR]], [[OUT_1]][1] : [[TY]]501// CHECK: [[OUT_3:%.*]] = llvm.insertvalue [[OFFSET]], [[OUT_2]][2] : [[TY]]502// CHECK: [[OUT_4:%.*]] = llvm.insertvalue [[SIZE_0]], [[OUT_3]][3, 0] : [[TY]]503// CHECK: [[OUT_5:%.*]] = llvm.insertvalue [[STRIDE_0]], [[OUT_4]][4, 0] : [[TY]]504// CHECK: [[OUT_6:%.*]] = llvm.insertvalue [[SIZE_1]], [[OUT_5]][3, 1] : [[TY]]505// CHECK: [[OUT_7:%.*]] = llvm.insertvalue [[STRIDE_1]], [[OUT_6]][4, 1] : [[TY]]506 507// -----508 509// CHECK-LABEL: @memref_reshape(510// CHECK-SAME: %[[ARG0:.*]]: memref<2x3xf32>, %[[ARG1:.*]]: memref<?xindex>)511func.func @memref_reshape(%input : memref<2x3xf32>, %shape : memref<?xindex>) {512 %output = memref.reshape %input(%shape)513 : (memref<2x3xf32>, memref<?xindex>) -> memref<*xf32>514 return515}516// CHECK-DAG: [[INPUT:%.*]] = builtin.unrealized_conversion_cast %[[ARG0]] : {{.*}} to [[INPUT_TY:!.*]]517// CHECK-DAG: [[SHAPE:%.*]] = builtin.unrealized_conversion_cast %[[ARG1]] : {{.*}} to [[SHAPE_TY:!.*]]518// CHECK: [[RANK:%.*]] = llvm.extractvalue [[SHAPE]][3, 0] : [[SHAPE_TY]]519// CHECK: [[UNRANKED_OUT_O:%.*]] = llvm.mlir.poison : !llvm.struct<(i64, ptr)>520// CHECK: [[UNRANKED_OUT_1:%.*]] = llvm.insertvalue [[RANK]], [[UNRANKED_OUT_O]][0] : !llvm.struct<(i64, ptr)>521 522// Compute size in bytes to allocate result ranked descriptor523// CHECK: [[C1:%.*]] = llvm.mlir.constant(1 : index) : i64524// CHECK: [[C2:%.*]] = llvm.mlir.constant(2 : index) : i64525// CHECK: [[INDEX_SIZE:%.*]] = llvm.mlir.constant(8 : index) : i64526// CHECK: [[PTR_SIZE:%.*]] = llvm.mlir.constant(8 : index) : i64527// CHECK: [[DOUBLE_PTR_SIZE:%.*]] = llvm.mul [[C2]], [[PTR_SIZE]] : i64528// CHECK: [[DESC_ALLOC_SIZE:%.*]] = llvm.add [[DOUBLE_PTR_SIZE]], %{{.*}}529// CHECK: [[UNDERLYING_DESC:%.*]] = llvm.alloca [[DESC_ALLOC_SIZE]] x i8530// CHECK: llvm.insertvalue [[UNDERLYING_DESC]], [[UNRANKED_OUT_1]][1]531 532// Set allocated, aligned pointers and offset.533// CHECK: [[ALLOC_PTR:%.*]] = llvm.extractvalue [[INPUT]][0] : [[INPUT_TY]]534// CHECK: [[ALIGN_PTR:%.*]] = llvm.extractvalue [[INPUT]][1] : [[INPUT_TY]]535// CHECK: [[OFFSET:%.*]] = llvm.extractvalue [[INPUT]][2] : [[INPUT_TY]]536// CHECK: llvm.store [[ALLOC_PTR]], [[UNDERLYING_DESC]] : !llvm.ptr, !llvm.ptr537// CHECK: [[ALIGNED_PTR_PTR:%.*]] = llvm.getelementptr [[UNDERLYING_DESC]]{{\[}}1]538// CHECK: llvm.store [[ALIGN_PTR]], [[ALIGNED_PTR_PTR]] : !llvm.ptr, !llvm.ptr539// CHECK: [[OFFSET_PTR:%.*]] = llvm.getelementptr [[UNDERLYING_DESC]]{{\[}}2]540// CHECK: llvm.store [[OFFSET]], [[OFFSET_PTR]] : i64, !llvm.ptr541 542// Iterate over shape operand in reverse order and set sizes and strides.543// CHECK: [[SIZES_PTR:%.*]] = llvm.getelementptr [[UNDERLYING_DESC]]{{\[}}0, 3]544// CHECK: [[STRIDES_PTR:%.*]] = llvm.getelementptr [[SIZES_PTR]]{{\[}}[[RANK]]]545// CHECK: [[SHAPE_IN_PTR:%.*]] = llvm.extractvalue [[SHAPE]][1] : [[SHAPE_TY]]546// CHECK: [[C1_:%.*]] = llvm.mlir.constant(1 : index) : i64547// CHECK: [[RANK_MIN_1:%.*]] = llvm.sub [[RANK]], [[C1_]] : i64548// CHECK: llvm.br ^bb1([[RANK_MIN_1]], [[C1_]] : i64, i64)549 550// CHECK: ^bb1([[DIM:%.*]]: i64, [[CUR_STRIDE:%.*]]: i64):551// CHECK: [[C0_:%.*]] = llvm.mlir.constant(0 : index) : i64552// CHECK: [[COND:%.*]] = llvm.icmp "sge" [[DIM]], [[C0_]] : i64553// CHECK: llvm.cond_br [[COND]], ^bb2, ^bb3554 555// CHECK: ^bb2:556// CHECK: [[SIZE_PTR:%.*]] = llvm.getelementptr [[SHAPE_IN_PTR]]{{\[}}[[DIM]]]557// CHECK: [[SIZE:%.*]] = llvm.load [[SIZE_PTR]] : !llvm.ptr -> i64558// CHECK: [[TARGET_SIZE_PTR:%.*]] = llvm.getelementptr [[SIZES_PTR]]{{\[}}[[DIM]]]559// CHECK: llvm.store [[SIZE]], [[TARGET_SIZE_PTR]] : i64, !llvm.ptr560// CHECK: [[TARGET_STRIDE_PTR:%.*]] = llvm.getelementptr [[STRIDES_PTR]]{{\[}}[[DIM]]]561// CHECK: llvm.store [[CUR_STRIDE]], [[TARGET_STRIDE_PTR]] : i64, !llvm.ptr562// CHECK: [[UPDATE_STRIDE:%.*]] = llvm.mul [[CUR_STRIDE]], [[SIZE]] : i64563// CHECK: [[STRIDE_COND:%.*]] = llvm.sub [[DIM]], [[C1_]] : i64564// CHECK: llvm.br ^bb1([[STRIDE_COND]], [[UPDATE_STRIDE]] : i64, i64)565 566// CHECK: ^bb3:567// CHECK: return568 569// -----570 571// ALIGNED-ALLOC-LABEL: @memref_of_memref572func.func @memref_of_memref() {573 // Sizeof computation is as usual.574 // ALIGNED-ALLOC: %[[NULL:.*]] = llvm.mlir.zero575 // ALIGNED-ALLOC: %[[PTR:.*]] = llvm.getelementptr576 // ALIGNED-ALLOC: %[[SIZEOF:.*]] = llvm.ptrtoint577 578 // Static alignment should be computed as ceilPowerOf2(2 * sizeof(pointer) +579 // (1 + 2 * rank) * sizeof(index) = ceilPowerOf2(2 * 8 + 3 * 8) = 64.580 // ALIGNED-ALLOC: llvm.mlir.constant(64 : index)581 582 // Check that the types are converted as expected.583 // ALIGNED-ALLOC: llvm.call @aligned_alloc584 // ALIGNED-ALLOC: llvm.mlir.poison585 // ALIGNED-ALLOC-SAME: !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>586 %0 = memref.alloc() : memref<1xmemref<1xf32>>587 return588}589 590// -----591 592module attributes { dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<index, 32>> } {593 // ALIGNED-ALLOC-LABEL: @memref_of_memref_32594 func.func @memref_of_memref_32() {595 // Sizeof computation is as usual.596 // ALIGNED-ALLOC: %[[NULL:.*]] = llvm.mlir.zero597 // ALIGNED-ALLOC: %[[PTR:.*]] = llvm.getelementptr598 // ALIGNED-ALLOC: %[[SIZEOF:.*]] = llvm.ptrtoint599 600 // Static alignment should be computed as ceilPowerOf2(2 * sizeof(pointer) +601 // (1 + 2 * rank) * sizeof(index) = ceilPowerOf2(2 * 8 + 3 * 4) = 32.602 // ALIGNED-ALLOC: llvm.mlir.constant(32 : index)603 604 // Check that the types are converted as expected.605 // ALIGNED-ALLOC: llvm.call @aligned_alloc606 // ALIGNED-ALLOC: llvm.mlir.poison607 // ALIGNED-ALLOC-SAME: !llvm.struct<(ptr, ptr, i32, array<1 x i32>, array<1 x i32>)>608 %0 = memref.alloc() : memref<1xmemref<1xf32>>609 return610 }611}612 613 614// -----615 616// ALIGNED-ALLOC-LABEL: @memref_of_memref_of_memref617func.func @memref_of_memref_of_memref() {618 // Sizeof computation is as usual, also check the type.619 // ALIGNED-ALLOC: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr620 // ALIGNED-ALLOC: %[[PTR:.*]] = llvm.getelementptr621 // ALIGNED-ALLOC: %[[SIZEOF:.*]] = llvm.ptrtoint622 623 // Static alignment should be computed as ceilPowerOf2(2 * sizeof(pointer) +624 // (1 + 2 * rank) * sizeof(index) = ceilPowerOf2(2 * 8 + 3 * 8) = 64.625 // ALIGNED-ALLOC: llvm.mlir.constant(64 : index)626 // ALIGNED-ALLOC: llvm.call @aligned_alloc627 %0 = memref.alloc() : memref<1 x memref<2 x memref<3 x f32>>>628 return629}630 631// -----632 633// ALIGNED-ALLOC-LABEL: @ranked_unranked634func.func @ranked_unranked() {635 // ALIGNED-ALLOC: llvm.mlir.zero636 // ALIGNED-ALLOC-SAME: !llvm.ptr637 // ALIGNED-ALLOC: llvm.getelementptr638 // ALIGNED-ALLOC: llvm.ptrtoint639 640 // Static alignment should be computed as ceilPowerOf2(sizeof(index) +641 // sizeof(pointer)) = 16.642 // ALIGNED-ALLOC: llvm.mlir.constant(16 : index)643 // ALIGNED-ALLOC: llvm.call @aligned_alloc644 %0 = memref.alloc() : memref<1 x memref<* x f32>>645 memref.cast %0 : memref<1 x memref<* x f32>> to memref<* x memref<* x f32>>646 return647}648