1// RUN: mlir-opt -convert-std-to-llvm %s | FileCheck %s 2// RUN: mlir-opt -convert-std-to-llvm='use-aligned-alloc=1' %s | FileCheck %s --check-prefix=ALIGNED-ALLOC 3 4// CHECK-LABEL: func @check_strided_memref_arguments( 5// CHECK-COUNT-2: !llvm.ptr<float> 6// CHECK-COUNT-5: !llvm.i64 7// CHECK-COUNT-2: !llvm.ptr<float> 8// CHECK-COUNT-5: !llvm.i64 9// CHECK-COUNT-2: !llvm.ptr<float> 10// CHECK-COUNT-5: !llvm.i64 11func @check_strided_memref_arguments(%static: memref<10x20xf32, affine_map<(i,j)->(20 * i + j + 1)>>, 12 %dynamic : memref<?x?xf32, affine_map<(i,j)[M]->(M * i + j + 1)>>, 13 %mixed : memref<10x?xf32, affine_map<(i,j)[M]->(M * i + j + 1)>>) { 14 return 15} 16 17// CHECK-LABEL: func @check_arguments 18// CHECK-COUNT-2: !llvm.ptr<float> 19// CHECK-COUNT-5: !llvm.i64 20// CHECK-COUNT-2: !llvm.ptr<float> 21// CHECK-COUNT-5: !llvm.i64 22// CHECK-COUNT-2: !llvm.ptr<float> 23// CHECK-COUNT-5: !llvm.i64 24func @check_arguments(%static: memref<10x20xf32>, %dynamic : memref<?x?xf32>, %mixed : memref<10x?xf32>) { 25 return 26} 27 28// CHECK-LABEL: func @mixed_alloc( 29// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> { 30func @mixed_alloc(%arg0: index, %arg1: index) -> memref<?x42x?xf32> { 31// CHECK: %[[c42:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 32// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 33// CHECK-NEXT: %[[st0:.*]] = llvm.mul %[[N]], %[[c42]] : !llvm.i64 34// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[st0]], %[[M]] : !llvm.i64 35// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 36// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 37// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 38// CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8> 39// CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float> 40// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 41// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 42// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 43// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 44// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 45// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 46// CHECK-NEXT: llvm.insertvalue %[[c42]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 47// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 48// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 49// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 50// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 51 %0 = alloc(%arg0, %arg1) : memref<?x42x?xf32> 52// CHECK-NEXT: llvm.return %{{.*}} : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 53 return %0 : memref<?x42x?xf32> 54} 55 56// CHECK-LABEL: func @mixed_dealloc 57func @mixed_dealloc(%arg0: memref<?x42x?xf32>) { 58// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 59// CHECK-NEXT: %[[ptri8:.*]] = llvm.bitcast %[[ptr]] : !llvm.ptr<float> to !llvm.ptr<i8> 60// CHECK-NEXT: llvm.call @free(%[[ptri8]]) : (!llvm.ptr<i8>) -> () 61 dealloc %arg0 : memref<?x42x?xf32> 62// CHECK-NEXT: llvm.return 63 return 64} 65 66// CHECK-LABEL: func @dynamic_alloc( 67// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> { 68func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> { 69// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 70// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[N]], %[[M]] : !llvm.i64 71// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 72// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 73// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 74// CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8> 75// CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float> 76// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 77// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 78// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 79// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 80// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 81// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 82// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 83// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 84// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 85 %0 = alloc(%arg0, %arg1) : memref<?x?xf32> 86// CHECK-NEXT: llvm.return %{{.*}} : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 87 return %0 : memref<?x?xf32> 88} 89 90// ----- 91 92// CHECK-LABEL: func @dynamic_alloca 93// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> { 94func @dynamic_alloca(%arg0: index, %arg1: index) -> memref<?x?xf32> { 95// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 96// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %[[N]], %[[M]] : !llvm.i64 97// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 98// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 99// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 100// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[sz_bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr<float> 101// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 102// CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 103// CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 104// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 105// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 106// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 107// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 108// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 109// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 110 %0 = alloca(%arg0, %arg1) : memref<?x?xf32> 111 112// Test with explicitly specified alignment. llvm.alloca takes care of the 113// alignment. The same pointer is thus used for allocation and aligned 114// accesses. 115// CHECK: %[[alloca_aligned:.*]] = llvm.alloca %{{.*}} x !llvm.float {alignment = 32 : i64} : (!llvm.i64) -> !llvm.ptr<float> 116// CHECK: %[[desc:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 117// CHECK: %[[desc1:.*]] = llvm.insertvalue %[[alloca_aligned]], %[[desc]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 118// CHECK: llvm.insertvalue %[[alloca_aligned]], %[[desc1]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 119 alloca(%arg0, %arg1) {alignment = 32} : memref<?x?xf32> 120 return %0 : memref<?x?xf32> 121} 122 123// CHECK-LABEL: func @dynamic_dealloc 124func @dynamic_dealloc(%arg0: memref<?x?xf32>) { 125// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 126// CHECK-NEXT: %[[ptri8:.*]] = llvm.bitcast %[[ptr]] : !llvm.ptr<float> to !llvm.ptr<i8> 127// CHECK-NEXT: llvm.call @free(%[[ptri8]]) : (!llvm.ptr<i8>) -> () 128 dealloc %arg0 : memref<?x?xf32> 129 return 130} 131 132// CHECK-LABEL: func @stdlib_aligned_alloc({{.*}}) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> { 133// ALIGNED-ALLOC-LABEL: func @stdlib_aligned_alloc({{.*}}) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> { 134func @stdlib_aligned_alloc(%N : index) -> memref<32x18xf32> { 135// ALIGNED-ALLOC-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 136// ALIGNED-ALLOC-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 137// ALIGNED-ALLOC-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 138// ALIGNED-ALLOC-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 139// ALIGNED-ALLOC-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 140// ALIGNED-ALLOC-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 141// ALIGNED-ALLOC-NEXT: %[[bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 142// ALIGNED-ALLOC-NEXT: %[[alignment:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 143// ALIGNED-ALLOC-NEXT: %[[allocated:.*]] = llvm.call @aligned_alloc(%[[alignment]], %[[bytes]]) : (!llvm.i64, !llvm.i64) -> !llvm.ptr<i8> 144// ALIGNED-ALLOC-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr<i8> to !llvm.ptr<float> 145 %0 = alloc() {alignment = 32} : memref<32x18xf32> 146 // Do another alloc just to test that we have a unique declaration for 147 // aligned_alloc. 148 // ALIGNED-ALLOC: llvm.call @aligned_alloc 149 %1 = alloc() {alignment = 64} : memref<4096xf32> 150 151 // Alignment is to element type boundaries (minimum 16 bytes). 152 // ALIGNED-ALLOC: %[[c32:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 153 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c32]] 154 %2 = alloc() : memref<4096xvector<8xf32>> 155 // The minimum alignment is 16 bytes unless explicitly specified. 156 // ALIGNED-ALLOC: %[[c16:.*]] = llvm.mlir.constant(16 : index) : !llvm.i64 157 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c16]], 158 %3 = alloc() : memref<4096xvector<2xf32>> 159 // ALIGNED-ALLOC: %[[c8:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 160 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c8]], 161 %4 = alloc() {alignment = 8} : memref<1024xvector<4xf32>> 162 // Bump the memref allocation size if its size is not a multiple of alignment. 163 // ALIGNED-ALLOC: %[[c32:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 164 // ALIGNED-ALLOC-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64 165 // ALIGNED-ALLOC-NEXT: llvm.sub 166 // ALIGNED-ALLOC-NEXT: llvm.add 167 // ALIGNED-ALLOC-NEXT: llvm.urem 168 // ALIGNED-ALLOC-NEXT: %[[SIZE_ALIGNED:.*]] = llvm.sub 169 // ALIGNED-ALLOC-NEXT: llvm.call @aligned_alloc(%[[c32]], %[[SIZE_ALIGNED]]) 170 %5 = alloc() {alignment = 32} : memref<100xf32> 171 // Bump alignment to the next power of two if it isn't. 172 // ALIGNED-ALLOC: %[[c128:.*]] = llvm.mlir.constant(128 : index) : !llvm.i64 173 // ALIGNED-ALLOC: llvm.call @aligned_alloc(%[[c128]] 174 %6 = alloc(%N) : memref<?xvector<18xf32>> 175 return %0 : memref<32x18xf32> 176} 177 178// CHECK-LABEL: func @mixed_load( 179// CHECK-COUNT-2: !llvm.ptr<float>, 180// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64 181// CHECK: %[[I:.*]]: !llvm.i64, 182// CHECK: %[[J:.*]]: !llvm.i64) 183func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) { 184// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 185// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 186// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 187// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 188// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 189// CHECK-NEXT: llvm.load %[[addr]] : !llvm.ptr<float> 190 %0 = load %mixed[%i, %j] : memref<42x?xf32> 191 return 192} 193 194// CHECK-LABEL: func @dynamic_load( 195// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float> 196// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float> 197// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 198// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 199// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 200// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 201// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 202// CHECK-SAME: %[[I:[a-zA-Z0-9]*]]: !llvm.i64 203// CHECK-SAME: %[[J:[a-zA-Z0-9]*]]: !llvm.i64 204func @dynamic_load(%dynamic : memref<?x?xf32>, %i : index, %j : index) { 205// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 206// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 207// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 208// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 209// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 210// CHECK-NEXT: llvm.load %[[addr]] : !llvm.ptr<float> 211 %0 = load %dynamic[%i, %j] : memref<?x?xf32> 212 return 213} 214 215// CHECK-LABEL: func @prefetch 216// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float> 217// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float> 218// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 219// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 220// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 221// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 222// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 223// CHECK-SAME: %[[I:[a-zA-Z0-9]*]]: !llvm.i64 224// CHECK-SAME: %[[J:[a-zA-Z0-9]*]]: !llvm.i64 225func @prefetch(%A : memref<?x?xf32>, %i : index, %j : index) { 226// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 227// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 228// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 229// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 230// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 231// CHECK-NEXT: [[C1:%.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 232// CHECK-NEXT: [[C3:%.*]] = llvm.mlir.constant(3 : i32) : !llvm.i32 233// CHECK-NEXT: [[C1_1:%.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 234// CHECK-NEXT: "llvm.intr.prefetch"(%[[addr]], [[C1]], [[C3]], [[C1_1]]) : (!llvm.ptr<float>, !llvm.i32, !llvm.i32, !llvm.i32) -> () 235 prefetch %A[%i, %j], write, locality<3>, data : memref<?x?xf32> 236// CHECK: [[C0:%.*]] = llvm.mlir.constant(0 : i32) : !llvm.i32 237// CHECK: [[C0_1:%.*]] = llvm.mlir.constant(0 : i32) : !llvm.i32 238// CHECK: [[C1_2:%.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 239// CHECK: "llvm.intr.prefetch"(%{{.*}}, [[C0]], [[C0_1]], [[C1_2]]) : (!llvm.ptr<float>, !llvm.i32, !llvm.i32, !llvm.i32) -> () 240 prefetch %A[%i, %j], read, locality<0>, data : memref<?x?xf32> 241// CHECK: [[C0_2:%.*]] = llvm.mlir.constant(0 : i32) : !llvm.i32 242// CHECK: [[C2:%.*]] = llvm.mlir.constant(2 : i32) : !llvm.i32 243// CHECK: [[C0_3:%.*]] = llvm.mlir.constant(0 : i32) : !llvm.i32 244// CHECK: "llvm.intr.prefetch"(%{{.*}}, [[C0_2]], [[C2]], [[C0_3]]) : (!llvm.ptr<float>, !llvm.i32, !llvm.i32, !llvm.i32) -> () 245 prefetch %A[%i, %j], read, locality<2>, instr : memref<?x?xf32> 246 return 247} 248 249// CHECK-LABEL: func @dynamic_store 250// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float> 251// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float> 252// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 253// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 254// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 255// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 256// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 257// CHECK-SAME: %[[I:[a-zA-Z0-9]*]]: !llvm.i64 258// CHECK-SAME: %[[J:[a-zA-Z0-9]*]]: !llvm.i64 259func @dynamic_store(%dynamic : memref<?x?xf32>, %i : index, %j : index, %val : f32) { 260// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 261// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 262// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 263// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 264// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 265// CHECK-NEXT: llvm.store %{{.*}}, %[[addr]] : !llvm.ptr<float> 266 store %val, %dynamic[%i, %j] : memref<?x?xf32> 267 return 268} 269 270// CHECK-LABEL: func @mixed_store 271// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float> 272// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float> 273// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 274// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 275// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 276// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 277// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 278// CHECK-SAME: %[[I:[a-zA-Z0-9]*]]: !llvm.i64 279// CHECK-SAME: %[[J:[a-zA-Z0-9]*]]: !llvm.i64 280func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32) { 281// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 282// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 283// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 284// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 285// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 286// CHECK-NEXT: llvm.store %{{.*}}, %[[addr]] : !llvm.ptr<float> 287 store %val, %mixed[%i, %j] : memref<42x?xf32> 288 return 289} 290 291// CHECK-LABEL: func @memref_cast_static_to_dynamic 292func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) { 293// CHECK-NOT: llvm.bitcast 294 %0 = memref_cast %static : memref<10x42xf32> to memref<?x?xf32> 295 return 296} 297 298// CHECK-LABEL: func @memref_cast_static_to_mixed 299func @memref_cast_static_to_mixed(%static : memref<10x42xf32>) { 300// CHECK-NOT: llvm.bitcast 301 %0 = memref_cast %static : memref<10x42xf32> to memref<?x42xf32> 302 return 303} 304 305// CHECK-LABEL: func @memref_cast_dynamic_to_static 306func @memref_cast_dynamic_to_static(%dynamic : memref<?x?xf32>) { 307// CHECK-NOT: llvm.bitcast 308 %0 = memref_cast %dynamic : memref<?x?xf32> to memref<10x12xf32> 309 return 310} 311 312// CHECK-LABEL: func @memref_cast_dynamic_to_mixed 313func @memref_cast_dynamic_to_mixed(%dynamic : memref<?x?xf32>) { 314// CHECK-NOT: llvm.bitcast 315 %0 = memref_cast %dynamic : memref<?x?xf32> to memref<?x12xf32> 316 return 317} 318 319// CHECK-LABEL: func @memref_cast_mixed_to_dynamic 320func @memref_cast_mixed_to_dynamic(%mixed : memref<42x?xf32>) { 321// CHECK-NOT: llvm.bitcast 322 %0 = memref_cast %mixed : memref<42x?xf32> to memref<?x?xf32> 323 return 324} 325 326// CHECK-LABEL: func @memref_cast_mixed_to_static 327func @memref_cast_mixed_to_static(%mixed : memref<42x?xf32>) { 328// CHECK-NOT: llvm.bitcast 329 %0 = memref_cast %mixed : memref<42x?xf32> to memref<42x1xf32> 330 return 331} 332 333// CHECK-LABEL: func @memref_cast_mixed_to_mixed 334func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) { 335// CHECK-NOT: llvm.bitcast 336 %0 = memref_cast %mixed : memref<42x?xf32> to memref<?x1xf32> 337 return 338} 339 340// CHECK-LABEL: func @memref_cast_ranked_to_unranked 341func @memref_cast_ranked_to_unranked(%arg : memref<42x2x?xf32>) { 342// CHECK-DAG: %[[c:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 343// CHECK-DAG: %[[p:.*]] = llvm.alloca %[[c]] x !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> : (!llvm.i64) -> !llvm.ptr<struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>> 344// CHECK-DAG: llvm.store %{{.*}}, %[[p]] : !llvm.ptr<struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>> 345// CHECK-DAG: %[[p2:.*]] = llvm.bitcast %[[p]] : !llvm.ptr<struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>> to !llvm.ptr<i8> 346// CHECK-DAG: %[[r:.*]] = llvm.mlir.constant(3 : i64) : !llvm.i64 347// CHECK : llvm.mlir.undef : !llvm.struct<(i64, ptr<i8>)> 348// CHECK-DAG: llvm.insertvalue %[[r]], %{{.*}}[0] : !llvm.struct<(i64, ptr<i8>)> 349// CHECK-DAG: llvm.insertvalue %[[p2]], %{{.*}}[1] : !llvm.struct<(i64, ptr<i8>)> 350 %0 = memref_cast %arg : memref<42x2x?xf32> to memref<*xf32> 351 return 352} 353 354// CHECK-LABEL: func @memref_cast_unranked_to_ranked 355func @memref_cast_unranked_to_ranked(%arg : memref<*xf32>) { 356// CHECK: %[[p:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(i64, ptr<i8>)> 357// CHECK-NEXT: llvm.bitcast %[[p]] : !llvm.ptr<i8> to !llvm.ptr<struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>> 358 %0 = memref_cast %arg : memref<*xf32> to memref<?x?x10x2xf32> 359 return 360} 361 362// CHECK-LABEL: func @mixed_memref_dim 363func @mixed_memref_dim(%mixed : memref<42x?x?x13x?xf32>) { 364// CHECK: llvm.mlir.constant(42 : index) : !llvm.i64 365 %c0 = constant 0 : index 366 %0 = dim %mixed, %c0 : memref<42x?x?x13x?xf32> 367// CHECK: llvm.extractvalue %[[ld:.*]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 368 %c1 = constant 1 : index 369 %1 = dim %mixed, %c1 : memref<42x?x?x13x?xf32> 370// CHECK: llvm.extractvalue %[[ld]][3, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 371 %c2 = constant 2 : index 372 %2 = dim %mixed, %c2 : memref<42x?x?x13x?xf32> 373// CHECK: llvm.mlir.constant(13 : index) : !llvm.i64 374 %c3 = constant 3 : index 375 %3 = dim %mixed, %c3 : memref<42x?x?x13x?xf32> 376// CHECK: llvm.extractvalue %[[ld]][3, 4] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 377 %c4 = constant 4 : index 378 %4 = dim %mixed, %c4 : memref<42x?x?x13x?xf32> 379 return 380} 381 382// CHECK-LABEL: @memref_dim_with_dyn_index 383// CHECK-SAME: %[[ALLOC_PTR:.*]]: !llvm.ptr<float>, %[[ALIGN_PTR:.*]]: !llvm.ptr<float>, %[[OFFSET:.*]]: !llvm.i64, %[[SIZE0:.*]]: !llvm.i64, %[[SIZE1:.*]]: !llvm.i64, %[[STRIDE0:.*]]: !llvm.i64, %[[STRIDE1:.*]]: !llvm.i64, %[[IDX:.*]]: !llvm.i64) -> !llvm.i64 384func @memref_dim_with_dyn_index(%arg : memref<3x?xf32>, %idx : index) -> index { 385 // CHECK-NEXT: %[[DESCR0:.*]] = llvm.mlir.undef : [[DESCR_TY:!llvm.struct<\(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>\)>]] 386 // CHECK-NEXT: %[[DESCR1:.*]] = llvm.insertvalue %[[ALLOC_PTR]], %[[DESCR0]][0] : [[DESCR_TY]] 387 // CHECK-NEXT: %[[DESCR2:.*]] = llvm.insertvalue %[[ALIGN_PTR]], %[[DESCR1]][1] : [[DESCR_TY]] 388 // CHECK-NEXT: %[[DESCR3:.*]] = llvm.insertvalue %[[OFFSET]], %[[DESCR2]][2] : [[DESCR_TY]] 389 // CHECK-NEXT: %[[DESCR4:.*]] = llvm.insertvalue %[[SIZE0]], %[[DESCR3]][3, 0] : [[DESCR_TY]] 390 // CHECK-NEXT: %[[DESCR5:.*]] = llvm.insertvalue %[[STRIDE0]], %[[DESCR4]][4, 0] : [[DESCR_TY]] 391 // CHECK-NEXT: %[[DESCR6:.*]] = llvm.insertvalue %[[SIZE1]], %[[DESCR5]][3, 1] : [[DESCR_TY]] 392 // CHECK-NEXT: %[[DESCR7:.*]] = llvm.insertvalue %[[STRIDE1]], %[[DESCR6]][4, 1] : [[DESCR_TY]] 393 // CHECK-DAG: %[[C0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 394 // CHECK-DAG: %[[C1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 395 // CHECK-DAG: %[[SIZES:.*]] = llvm.extractvalue %[[DESCR7]][3] : [[DESCR_TY]] 396 // CHECK-DAG: %[[SIZES_PTR:.*]] = llvm.alloca %[[C1]] x !llvm.array<2 x i64> : (!llvm.i64) -> !llvm.ptr<array<2 x i64>> 397 // CHECK-DAG: llvm.store %[[SIZES]], %[[SIZES_PTR]] : !llvm.ptr<array<2 x i64>> 398 // CHECK-DAG: %[[RESULT_PTR:.*]] = llvm.getelementptr %[[SIZES_PTR]][%[[C0]], %[[IDX]]] : (!llvm.ptr<array<2 x i64>>, !llvm.i64, !llvm.i64) -> !llvm.ptr<i64> 399 // CHECK-DAG: %[[RESULT:.*]] = llvm.load %[[RESULT_PTR]] : !llvm.ptr<i64> 400 // CHECK-DAG: llvm.return %[[RESULT]] : !llvm.i64 401 %result = dim %arg, %idx : memref<3x?xf32> 402 return %result : index 403} 404 405// CHECK-LABEL: @memref_reinterpret_cast_ranked_to_static_shape 406func @memref_reinterpret_cast_ranked_to_static_shape(%input : memref<2x3xf32>) { 407 %output = memref_reinterpret_cast %input to 408 offset: [0], sizes: [6, 1], strides: [1, 1] 409 : memref<2x3xf32> to memref<6x1xf32> 410 return 411} 412// CHECK: [[INPUT:%.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : [[TY:!.*]] 413// CHECK: [[OUT_0:%.*]] = llvm.mlir.undef : [[TY]] 414// CHECK: [[BASE_PTR:%.*]] = llvm.extractvalue [[INPUT]][0] : [[TY]] 415// CHECK: [[ALIGNED_PTR:%.*]] = llvm.extractvalue [[INPUT]][1] : [[TY]] 416// CHECK: [[OUT_1:%.*]] = llvm.insertvalue [[BASE_PTR]], [[OUT_0]][0] : [[TY]] 417// CHECK: [[OUT_2:%.*]] = llvm.insertvalue [[ALIGNED_PTR]], [[OUT_1]][1] : [[TY]] 418// CHECK: [[OFFSET:%.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 419// CHECK: [[OUT_3:%.*]] = llvm.insertvalue [[OFFSET]], [[OUT_2]][2] : [[TY]] 420// CHECK: [[SIZE_0:%.*]] = llvm.mlir.constant(6 : index) : !llvm.i64 421// CHECK: [[OUT_4:%.*]] = llvm.insertvalue [[SIZE_0]], [[OUT_3]][3, 0] : [[TY]] 422// CHECK: [[SIZE_1:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 423// CHECK: [[OUT_5:%.*]] = llvm.insertvalue [[SIZE_1]], [[OUT_4]][4, 0] : [[TY]] 424// CHECK: [[STRIDE_0:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 425// CHECK: [[OUT_6:%.*]] = llvm.insertvalue [[STRIDE_0]], [[OUT_5]][3, 1] : [[TY]] 426// CHECK: [[STRIDE_1:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 427// CHECK: [[OUT_7:%.*]] = llvm.insertvalue [[STRIDE_1]], [[OUT_6]][4, 1] : [[TY]] 428 429// CHECK-LABEL: @memref_reinterpret_cast_unranked_to_dynamic_shape 430func @memref_reinterpret_cast_unranked_to_dynamic_shape(%offset: index, 431 %size_0 : index, 432 %size_1 : index, 433 %stride_0 : index, 434 %stride_1 : index, 435 %input : memref<*xf32>) { 436 %output = memref_reinterpret_cast %input to 437 offset: [%offset], sizes: [%size_0, %size_1], 438 strides: [%stride_0, %stride_1] 439 : memref<*xf32> to memref<?x?xf32, offset: ?, strides: [?, ?]> 440 return 441} 442// CHECK-SAME: ([[OFFSET:%[a-z,0-9]+]]: !llvm.i64, 443// CHECK-SAME: [[SIZE_0:%[a-z,0-9]+]]: !llvm.i64, [[SIZE_1:%[a-z,0-9]+]]: !llvm.i64, 444// CHECK-SAME: [[STRIDE_0:%[a-z,0-9]+]]: !llvm.i64, [[STRIDE_1:%[a-z,0-9]+]]: !llvm.i64, 445// CHECK: [[INPUT:%.*]] = llvm.insertvalue {{.*}}[1] : !llvm.struct<(i64, ptr<i8>)> 446// CHECK: [[OUT_0:%.*]] = llvm.mlir.undef : [[TY:!.*]] 447// CHECK: [[DESCRIPTOR:%.*]] = llvm.extractvalue [[INPUT]][1] : !llvm.struct<(i64, ptr<i8>)> 448// CHECK: [[BASE_PTR_PTR:%.*]] = llvm.bitcast [[DESCRIPTOR]] : !llvm.ptr<i8> to !llvm.ptr<ptr<float>> 449// CHECK: [[BASE_PTR:%.*]] = llvm.load [[BASE_PTR_PTR]] : !llvm.ptr<ptr<float>> 450// CHECK: [[BASE_PTR_PTR_:%.*]] = llvm.bitcast [[DESCRIPTOR]] : !llvm.ptr<i8> to !llvm.ptr<ptr<float>> 451// CHECK: [[C1:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 452// CHECK: [[ALIGNED_PTR_PTR:%.*]] = llvm.getelementptr [[BASE_PTR_PTR_]]{{\[}}[[C1]]] 453// CHECK-SAME: : (!llvm.ptr<ptr<float>>, !llvm.i64) -> !llvm.ptr<ptr<float>> 454// CHECK: [[ALIGNED_PTR:%.*]] = llvm.load [[ALIGNED_PTR_PTR]] : !llvm.ptr<ptr<float>> 455// CHECK: [[OUT_1:%.*]] = llvm.insertvalue [[BASE_PTR]], [[OUT_0]][0] : [[TY]] 456// CHECK: [[OUT_2:%.*]] = llvm.insertvalue [[ALIGNED_PTR]], [[OUT_1]][1] : [[TY]] 457// CHECK: [[OUT_3:%.*]] = llvm.insertvalue [[OFFSET]], [[OUT_2]][2] : [[TY]] 458// CHECK: [[OUT_4:%.*]] = llvm.insertvalue [[SIZE_0]], [[OUT_3]][3, 0] : [[TY]] 459// CHECK: [[OUT_5:%.*]] = llvm.insertvalue [[STRIDE_0]], [[OUT_4]][4, 0] : [[TY]] 460// CHECK: [[OUT_6:%.*]] = llvm.insertvalue [[SIZE_1]], [[OUT_5]][3, 1] : [[TY]] 461// CHECK: [[OUT_7:%.*]] = llvm.insertvalue [[STRIDE_1]], [[OUT_6]][4, 1] : [[TY]] 462 463// CHECK-LABEL: @memref_reshape 464func @memref_reshape(%input : memref<2x3xf32>, %shape : memref<?xindex>) { 465 %output = memref_reshape %input(%shape) 466 : (memref<2x3xf32>, memref<?xindex>) -> memref<*xf32> 467 return 468} 469// CHECK: [[INPUT:%.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : [[INPUT_TY:!.*]] 470// CHECK: [[SHAPE:%.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : [[SHAPE_TY:!.*]] 471// CHECK: [[RANK:%.*]] = llvm.extractvalue [[SHAPE]][3, 0] : [[SHAPE_TY]] 472// CHECK: [[UNRANKED_OUT_O:%.*]] = llvm.mlir.undef : !llvm.struct<(i64, ptr<i8>)> 473// CHECK: [[UNRANKED_OUT_1:%.*]] = llvm.insertvalue [[RANK]], [[UNRANKED_OUT_O]][0] : !llvm.struct<(i64, ptr<i8>)> 474 475// Compute size in bytes to allocate result ranked descriptor 476// CHECK: [[C1:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 477// CHECK: [[C2:%.*]] = llvm.mlir.constant(2 : index) : !llvm.i64 478// CHECK: [[PTR_SIZE:%.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 479// CHECK: [[INDEX_SIZE:%.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 480// CHECK: [[DOUBLE_PTR_SIZE:%.*]] = llvm.mul [[C2]], [[PTR_SIZE]] : !llvm.i64 481// CHECK: [[DESC_ALLOC_SIZE:%.*]] = llvm.add [[DOUBLE_PTR_SIZE]], %{{.*}} 482// CHECK: [[UNDERLYING_DESC:%.*]] = llvm.alloca [[DESC_ALLOC_SIZE]] x !llvm.i8 483// CHECK: llvm.insertvalue [[UNDERLYING_DESC]], [[UNRANKED_OUT_1]][1] 484 485// Set allocated, aligned pointers and offset. 486// CHECK: [[ALLOC_PTR:%.*]] = llvm.extractvalue [[INPUT]][0] : [[INPUT_TY]] 487// CHECK: [[ALIGN_PTR:%.*]] = llvm.extractvalue [[INPUT]][1] : [[INPUT_TY]] 488// CHECK: [[OFFSET:%.*]] = llvm.extractvalue [[INPUT]][2] : [[INPUT_TY]] 489// CHECK: [[BASE_PTR_PTR:%.*]] = llvm.bitcast [[UNDERLYING_DESC]] 490// CHECK-SAME: !llvm.ptr<i8> to !llvm.ptr<ptr<float>> 491// CHECK: llvm.store [[ALLOC_PTR]], [[BASE_PTR_PTR]] : !llvm.ptr<ptr<float>> 492// CHECK: [[BASE_PTR_PTR_:%.*]] = llvm.bitcast [[UNDERLYING_DESC]] : !llvm.ptr<i8> to !llvm.ptr<ptr<float>> 493// CHECK: [[C1:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 494// CHECK: [[ALIGNED_PTR_PTR:%.*]] = llvm.getelementptr [[BASE_PTR_PTR_]]{{\[}}[[C1]]] 495// CHECK: llvm.store [[ALIGN_PTR]], [[ALIGNED_PTR_PTR]] : !llvm.ptr<ptr<float>> 496// CHECK: [[BASE_PTR_PTR__:%.*]] = llvm.bitcast [[UNDERLYING_DESC]] : !llvm.ptr<i8> to !llvm.ptr<ptr<float>> 497// CHECK: [[C2:%.*]] = llvm.mlir.constant(2 : index) : !llvm.i64 498// CHECK: [[OFFSET_PTR_:%.*]] = llvm.getelementptr [[BASE_PTR_PTR__]]{{\[}}[[C2]]] 499// CHECK: [[OFFSET_PTR:%.*]] = llvm.bitcast [[OFFSET_PTR_]] 500// CHECK: llvm.store [[OFFSET]], [[OFFSET_PTR]] : !llvm.ptr<i64> 501 502// Iterate over shape operand in reverse order and set sizes and strides. 503// CHECK: [[STRUCT_PTR:%.*]] = llvm.bitcast [[UNDERLYING_DESC]] 504// CHECK-SAME: !llvm.ptr<i8> to !llvm.ptr<struct<(ptr<float>, ptr<float>, i64, i64)>> 505// CHECK: [[C0:%.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 506// CHECK: [[C3_I32:%.*]] = llvm.mlir.constant(3 : i32) : !llvm.i32 507// CHECK: [[SIZES_PTR:%.*]] = llvm.getelementptr [[STRUCT_PTR]]{{\[}}[[C0]], [[C3_I32]]] 508// CHECK: [[STRIDES_PTR:%.*]] = llvm.getelementptr [[SIZES_PTR]]{{\[}}[[RANK]]] 509// CHECK: [[SHAPE_IN_PTR:%.*]] = llvm.extractvalue [[SHAPE]][1] : [[SHAPE_TY]] 510// CHECK: [[C1_:%.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 511// CHECK: [[RANK_MIN_1:%.*]] = llvm.sub [[RANK]], [[C1_]] : !llvm.i64 512// CHECK: llvm.br ^bb1([[RANK_MIN_1]], [[C1_]] : !llvm.i64, !llvm.i64) 513 514// CHECK: ^bb1([[DIM:%.*]]: !llvm.i64, [[CUR_STRIDE:%.*]]: !llvm.i64): 515// CHECK: [[C0_:%.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 516// CHECK: [[COND:%.*]] = llvm.icmp "sge" [[DIM]], [[C0_]] : !llvm.i64 517// CHECK: llvm.cond_br [[COND]], ^bb2, ^bb3 518 519// CHECK: ^bb2: 520// CHECK: [[SIZE_PTR:%.*]] = llvm.getelementptr [[SHAPE_IN_PTR]]{{\[}}[[DIM]]] 521// CHECK: [[SIZE:%.*]] = llvm.load [[SIZE_PTR]] : !llvm.ptr<i64> 522// CHECK: [[TARGET_SIZE_PTR:%.*]] = llvm.getelementptr [[SIZES_PTR]]{{\[}}[[DIM]]] 523// CHECK: llvm.store [[SIZE]], [[TARGET_SIZE_PTR]] : !llvm.ptr<i64> 524// CHECK: [[TARGET_STRIDE_PTR:%.*]] = llvm.getelementptr [[STRIDES_PTR]]{{\[}}[[DIM]]] 525// CHECK: llvm.store [[CUR_STRIDE]], [[TARGET_STRIDE_PTR]] : !llvm.ptr<i64> 526// CHECK: [[UPDATE_STRIDE:%.*]] = llvm.mul [[CUR_STRIDE]], [[SIZE]] : !llvm.i64 527// CHECK: [[STRIDE_COND:%.*]] = llvm.sub [[DIM]], [[C1_]] : !llvm.i64 528// CHECK: llvm.br ^bb1([[STRIDE_COND]], [[UPDATE_STRIDE]] : !llvm.i64, !llvm.i64) 529 530// CHECK: ^bb3: 531// CHECK: llvm.return 532