1// RUN: mlir-opt -convert-std-to-llvm %s | FileCheck %s 2// RUN: mlir-opt -convert-std-to-llvm='use-bare-ptr-memref-call-conv=1' -split-input-file %s | FileCheck %s --check-prefix=BAREPTR 3 4// BAREPTR-LABEL: func @check_noalias 5// BAREPTR-SAME: %{{.*}}: !llvm.ptr<float> {llvm.noalias = true}, %{{.*}}: !llvm.ptr<float> {llvm.noalias = true} 6func @check_noalias(%static : memref<2xf32> {llvm.noalias = true}, %other : memref<2xf32> {llvm.noalias = true}) { 7 return 8} 9 10// ----- 11 12// CHECK-LABEL: func @check_static_return 13// CHECK-COUNT-2: !llvm.ptr<float> 14// CHECK-COUNT-5: !llvm.i64 15// CHECK-SAME: -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 16// BAREPTR-LABEL: func @check_static_return 17// BAREPTR-SAME: (%[[arg:.*]]: !llvm.ptr<float>) -> !llvm.ptr<float> { 18func @check_static_return(%static : memref<32x18xf32>) -> memref<32x18xf32> { 19// CHECK: llvm.return %{{.*}} : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 20 21// BAREPTR: %[[udf:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 22// BAREPTR-NEXT: %[[base0:.*]] = llvm.insertvalue %[[arg]], %[[udf]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 23// BAREPTR-NEXT: %[[aligned:.*]] = llvm.insertvalue %[[arg]], %[[base0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 24// BAREPTR-NEXT: %[[val0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 25// BAREPTR-NEXT: %[[ins0:.*]] = llvm.insertvalue %[[val0]], %[[aligned]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 26// BAREPTR-NEXT: %[[val1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 27// BAREPTR-NEXT: %[[ins1:.*]] = llvm.insertvalue %[[val1]], %[[ins0]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 28// BAREPTR-NEXT: %[[val2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 29// BAREPTR-NEXT: %[[ins2:.*]] = llvm.insertvalue %[[val2]], %[[ins1]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 30// BAREPTR-NEXT: %[[val3:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 31// BAREPTR-NEXT: %[[ins3:.*]] = llvm.insertvalue %[[val3]], %[[ins2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 32// BAREPTR-NEXT: %[[val4:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 33// BAREPTR-NEXT: %[[ins4:.*]] = llvm.insertvalue %[[val4]], %[[ins3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 34// BAREPTR-NEXT: %[[base1:.*]] = llvm.extractvalue %[[ins4]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 35// BAREPTR-NEXT: llvm.return %[[base1]] : !llvm.ptr<float> 36 return %static : memref<32x18xf32> 37} 38 39// ----- 40 41// CHECK-LABEL: func @check_static_return_with_offset 42// CHECK-COUNT-2: !llvm.ptr<float> 43// CHECK-COUNT-5: !llvm.i64 44// CHECK-SAME: -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 45// BAREPTR-LABEL: func @check_static_return_with_offset 46// BAREPTR-SAME: (%[[arg:.*]]: !llvm.ptr<float>) -> !llvm.ptr<float> { 47func @check_static_return_with_offset(%static : memref<32x18xf32, offset:7, strides:[22,1]>) -> memref<32x18xf32, offset:7, strides:[22,1]> { 48// CHECK: llvm.return %{{.*}} : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 49 50// BAREPTR: %[[udf:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 51// BAREPTR-NEXT: %[[base0:.*]] = llvm.insertvalue %[[arg]], %[[udf]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 52// BAREPTR-NEXT: %[[aligned:.*]] = llvm.insertvalue %[[arg]], %[[base0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 53// BAREPTR-NEXT: %[[val0:.*]] = llvm.mlir.constant(7 : index) : !llvm.i64 54// BAREPTR-NEXT: %[[ins0:.*]] = llvm.insertvalue %[[val0]], %[[aligned]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 55// BAREPTR-NEXT: %[[val1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 56// BAREPTR-NEXT: %[[ins1:.*]] = llvm.insertvalue %[[val1]], %[[ins0]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 57// BAREPTR-NEXT: %[[val2:.*]] = llvm.mlir.constant(22 : index) : !llvm.i64 58// BAREPTR-NEXT: %[[ins2:.*]] = llvm.insertvalue %[[val2]], %[[ins1]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 59// BAREPTR-NEXT: %[[val3:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 60// BAREPTR-NEXT: %[[ins3:.*]] = llvm.insertvalue %[[val3]], %[[ins2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 61// BAREPTR-NEXT: %[[val4:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 62// BAREPTR-NEXT: %[[ins4:.*]] = llvm.insertvalue %[[val4]], %[[ins3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 63// BAREPTR-NEXT: %[[base1:.*]] = llvm.extractvalue %[[ins4]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 64// BAREPTR-NEXT: llvm.return %[[base1]] : !llvm.ptr<float> 65 return %static : memref<32x18xf32, offset:7, strides:[22,1]> 66} 67 68// ----- 69 70// CHECK-LABEL: func @zero_d_alloc() -> !llvm.struct<(ptr<float>, ptr<float>, i64)> { 71// BAREPTR-LABEL: func @zero_d_alloc() -> !llvm.ptr<float> { 72func @zero_d_alloc() -> memref<f32> { 73// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 74// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 75// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 76// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 77// CHECK-NEXT: llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8> 78// CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float> 79// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64)> 80// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 81// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 82// CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 83// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 84 85// BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 86// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 87// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 88// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 89// BAREPTR-NEXT: llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8> 90// BAREPTR-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float> 91// BAREPTR-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64)> 92// BAREPTR-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 93// BAREPTR-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 94// BAREPTR-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 95// BAREPTR-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 96 %0 = alloc() : memref<f32> 97 return %0 : memref<f32> 98} 99 100// ----- 101 102// CHECK-LABEL: func @zero_d_dealloc 103// BAREPTR-LABEL: func @zero_d_dealloc(%{{.*}}: !llvm.ptr<float>) { 104func @zero_d_dealloc(%arg0: memref<f32>) { 105// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 106// CHECK-NEXT: %[[bc:.*]] = llvm.bitcast %[[ptr]] : !llvm.ptr<float> to !llvm.ptr<i8> 107// CHECK-NEXT: llvm.call @free(%[[bc]]) : (!llvm.ptr<i8>) -> () 108 109// BAREPTR: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 110// BAREPTR-NEXT: %[[bc:.*]] = llvm.bitcast %[[ptr]] : !llvm.ptr<float> to !llvm.ptr<i8> 111// BAREPTR-NEXT: llvm.call @free(%[[bc]]) : (!llvm.ptr<i8>) -> () 112 dealloc %arg0 : memref<f32> 113 return 114} 115 116// ----- 117 118// CHECK-LABEL: func @aligned_1d_alloc( 119// BAREPTR-LABEL: func @aligned_1d_alloc( 120func @aligned_1d_alloc() -> memref<42xf32> { 121// CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 122// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 123// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 124// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 125// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 126// CHECK-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 127// CHECK-NEXT: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : !llvm.i64 128// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm.ptr<i8> 129// CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float> 130// CHECK-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr<float> to !llvm.i64 131// CHECK-NEXT: %[[one_1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 132// CHECK-NEXT: %[[bump:.*]] = llvm.sub %[[alignment]], %[[one_1]] : !llvm.i64 133// CHECK-NEXT: %[[bumped:.*]] = llvm.add %[[allocatedAsInt]], %[[bump]] : !llvm.i64 134// CHECK-NEXT: %[[mod:.*]] = llvm.urem %[[bumped]], %[[alignment]] : !llvm.i64 135// CHECK-NEXT: %[[aligned:.*]] = llvm.sub %[[bumped]], %[[mod]] : !llvm.i64 136// CHECK-NEXT: %[[alignedBitCast:.*]] = llvm.inttoptr %[[aligned]] : !llvm.i64 to !llvm.ptr<float> 137// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 138// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 139// CHECK-NEXT: llvm.insertvalue %[[alignedBitCast]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 140// CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 141// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 142 143// BAREPTR-NEXT: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 144// BAREPTR-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 145// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 146// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 147// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 148// BAREPTR-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 149// BAREPTR-NEXT: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : !llvm.i64 150// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm.ptr<i8> 151// BAREPTR-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float> 152// BAREPTR-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr<float> to !llvm.i64 153// BAREPTR-NEXT: %[[one_2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 154// BAREPTR-NEXT: %[[bump:.*]] = llvm.sub %[[alignment]], %[[one_2]] : !llvm.i64 155// BAREPTR-NEXT: %[[bumped:.*]] = llvm.add %[[allocatedAsInt]], %[[bump]] : !llvm.i64 156// BAREPTR-NEXT: %[[mod:.*]] = llvm.urem %[[bumped]], %[[alignment]] : !llvm.i64 157// BAREPTR-NEXT: %[[aligned:.*]] = llvm.sub %[[bumped]], %[[mod]] : !llvm.i64 158// BAREPTR-NEXT: %[[alignedBitCast:.*]] = llvm.inttoptr %[[aligned]] : !llvm.i64 to !llvm.ptr<float> 159// BAREPTR-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 160// BAREPTR-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 161// BAREPTR-NEXT: llvm.insertvalue %[[alignedBitCast]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 162// BAREPTR-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 163// BAREPTR-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 164 %0 = alloc() {alignment = 8} : memref<42xf32> 165 return %0 : memref<42xf32> 166} 167 168// ----- 169 170// CHECK-LABEL: func @static_alloc() -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> { 171// BAREPTR-LABEL: func @static_alloc() -> !llvm.ptr<float> { 172func @static_alloc() -> memref<32x18xf32> { 173// CHECK: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 174// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 175// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 176// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 177// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8> 178// CHECK-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr<i8> to !llvm.ptr<float> 179 180// BAREPTR: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 181// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 182// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 183// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 184// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8> 185// BAREPTR-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr<i8> to !llvm.ptr<float> 186 %0 = alloc() : memref<32x18xf32> 187 return %0 : memref<32x18xf32> 188} 189 190// ----- 191 192// CHECK-LABEL: func @static_alloca() -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> { 193func @static_alloca() -> memref<32x18xf32> { 194// CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 195// CHECK-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 196// CHECK-NEXT: %[[st2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 197// CHECK-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 198// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float> 199// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 200// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64 201// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[size_bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr<float> 202 %0 = alloca() : memref<32x18xf32> 203 204 // Test with explicitly specified alignment. llvm.alloca takes care of the 205 // alignment. The same pointer is thus used for allocation and aligned 206 // accesses. 207 // CHECK: %[[alloca_aligned:.*]] = llvm.alloca %{{.*}} x !llvm.float {alignment = 32 : i64} : (!llvm.i64) -> !llvm.ptr<float> 208 // CHECK: %[[desc:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 209 // CHECK: %[[desc1:.*]] = llvm.insertvalue %[[alloca_aligned]], %[[desc]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 210 // CHECK: llvm.insertvalue %[[alloca_aligned]], %[[desc1]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 211 alloca() {alignment = 32} : memref<32x18xf32> 212 return %0 : memref<32x18xf32> 213} 214 215// ----- 216 217// CHECK-LABEL: func @static_dealloc 218// BAREPTR-LABEL: func @static_dealloc(%{{.*}}: !llvm.ptr<float>) { 219func @static_dealloc(%static: memref<10x8xf32>) { 220// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 221// CHECK-NEXT: %[[bc:.*]] = llvm.bitcast %[[ptr]] : !llvm.ptr<float> to !llvm.ptr<i8> 222// CHECK-NEXT: llvm.call @free(%[[bc]]) : (!llvm.ptr<i8>) -> () 223 224// BAREPTR: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 225// BAREPTR-NEXT: %[[bc:.*]] = llvm.bitcast %[[ptr]] : !llvm.ptr<float> to !llvm.ptr<i8> 226// BAREPTR-NEXT: llvm.call @free(%[[bc]]) : (!llvm.ptr<i8>) -> () 227 dealloc %static : memref<10x8xf32> 228 return 229} 230 231// ----- 232 233// CHECK-LABEL: func @zero_d_load 234// BAREPTR-LABEL: func @zero_d_load(%{{.*}}: !llvm.ptr<float>) -> !llvm.float 235func @zero_d_load(%arg0: memref<f32>) -> f32 { 236// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 237// CHECK-NEXT: %{{.*}} = llvm.load %[[ptr]] : !llvm.ptr<float> 238 239// BAREPTR: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 240// BAREPTR-NEXT: llvm.load %[[ptr:.*]] : !llvm.ptr<float> 241 %0 = load %arg0[] : memref<f32> 242 return %0 : f32 243} 244 245// ----- 246 247// CHECK-LABEL: func @static_load( 248// CHECK-COUNT-2: !llvm.ptr<float>, 249// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64 250// CHECK: %[[I:.*]]: !llvm.i64, 251// CHECK: %[[J:.*]]: !llvm.i64) 252// BAREPTR-LABEL: func @static_load 253// BAREPTR-SAME: (%[[A:.*]]: !llvm.ptr<float>, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64) { 254func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) { 255// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 256// CHECK-NEXT: %[[st0:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 257// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 258// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 259// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 260// CHECK-NEXT: llvm.load %[[addr]] : !llvm.ptr<float> 261 262// BAREPTR: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 263// BAREPTR-NEXT: %[[st0:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 264// BAREPTR-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 265// BAREPTR-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 266// BAREPTR-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 267// BAREPTR-NEXT: llvm.load %[[addr]] : !llvm.ptr<float> 268 %0 = load %static[%i, %j] : memref<10x42xf32> 269 return 270} 271 272// ----- 273 274// CHECK-LABEL: func @zero_d_store 275// BAREPTR-LABEL: func @zero_d_store 276// BAREPTR-SAME: (%[[A:.*]]: !llvm.ptr<float>, %[[val:.*]]: !llvm.float) 277func @zero_d_store(%arg0: memref<f32>, %arg1: f32) { 278// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 279// CHECK-NEXT: llvm.store %{{.*}}, %[[ptr]] : !llvm.ptr<float> 280 281// BAREPTR: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 282// BAREPTR-NEXT: llvm.store %[[val]], %[[ptr]] : !llvm.ptr<float> 283 store %arg1, %arg0[] : memref<f32> 284 return 285} 286 287// ----- 288 289// CHECK-LABEL: func @static_store 290// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float> 291// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float> 292// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 293// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 294// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 295// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 296// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 297// CHECK-SAME: %[[I:[a-zA-Z0-9]*]]: !llvm.i64 298// CHECK-SAME: %[[J:[a-zA-Z0-9]*]]: !llvm.i64 299// BAREPTR-LABEL: func @static_store 300// BAREPTR-SAME: %[[A:.*]]: !llvm.ptr<float> 301// BAREPTR-SAME: %[[I:[a-zA-Z0-9]*]]: !llvm.i64 302// BAREPTR-SAME: %[[J:[a-zA-Z0-9]*]]: !llvm.i64 303func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f32) { 304// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 305// CHECK-NEXT: %[[st0:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 306// CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 307// CHECK-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 308// CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 309// CHECK-NEXT: llvm.store %{{.*}}, %[[addr]] : !llvm.ptr<float> 310 311// BAREPTR: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 312// BAREPTR-NEXT: %[[st0:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 313// BAREPTR-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 314// BAREPTR-NEXT: %[[off1:.*]] = llvm.add %[[offI]], %[[J]] : !llvm.i64 315// BAREPTR-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float> 316// BAREPTR-NEXT: llvm.store %{{.*}}, %[[addr]] : !llvm.ptr<float> 317 store %val, %static[%i, %j] : memref<10x42xf32> 318 return 319} 320 321// ----- 322 323// CHECK-LABEL: func @static_memref_dim 324// BAREPTR-LABEL: func @static_memref_dim(%{{.*}}: !llvm.ptr<float>) { 325func @static_memref_dim(%static : memref<42x32x15x13x27xf32>) { 326// CHECK: llvm.mlir.constant(42 : index) : !llvm.i64 327// BAREPTR: llvm.insertvalue %{{.*}}, %{{.*}}[4, 4] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 328// BAREPTR: llvm.mlir.constant(42 : index) : !llvm.i64 329 %c0 = constant 0 : index 330 %0 = dim %static, %c0 : memref<42x32x15x13x27xf32> 331// CHECK: llvm.mlir.constant(32 : index) : !llvm.i64 332// BAREPTR: llvm.mlir.constant(32 : index) : !llvm.i64 333 %c1 = constant 1 : index 334 %1 = dim %static, %c1 : memref<42x32x15x13x27xf32> 335// CHECK: llvm.mlir.constant(15 : index) : !llvm.i64 336// BAREPTR: llvm.mlir.constant(15 : index) : !llvm.i64 337 %c2 = constant 2 : index 338 %2 = dim %static, %c2 : memref<42x32x15x13x27xf32> 339// CHECK: llvm.mlir.constant(13 : index) : !llvm.i64 340// BAREPTR: llvm.mlir.constant(13 : index) : !llvm.i64 341 %c3 = constant 3 : index 342 %3 = dim %static, %c3 : memref<42x32x15x13x27xf32> 343// CHECK: llvm.mlir.constant(27 : index) : !llvm.i64 344// BAREPTR: llvm.mlir.constant(27 : index) : !llvm.i64 345 %c4 = constant 4 : index 346 %4 = dim %static, %c4 : memref<42x32x15x13x27xf32> 347 return 348} 349 350// ----- 351 352// BAREPTR: llvm.func @foo(!llvm.ptr<i8>) -> !llvm.ptr<i8> 353func private @foo(memref<10xi8>) -> memref<20xi8> 354 355// BAREPTR-LABEL: func @check_memref_func_call 356// BAREPTR-SAME: %[[in:.*]]: !llvm.ptr<i8>) -> !llvm.ptr<i8> 357func @check_memref_func_call(%in : memref<10xi8>) -> memref<20xi8> { 358 // BAREPTR: %[[inDesc:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] 359 // BAREPTR-NEXT: %[[barePtr:.*]] = llvm.extractvalue %[[inDesc]][1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 360 // BAREPTR-NEXT: %[[call:.*]] = llvm.call @foo(%[[barePtr]]) : (!llvm.ptr<i8>) -> !llvm.ptr<i8> 361 // BAREPTR-NEXT: %[[desc0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 362 // BAREPTR-NEXT: %[[desc1:.*]] = llvm.insertvalue %[[call]], %[[desc0]][0] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 363 // BAREPTR-NEXT: %[[desc2:.*]] = llvm.insertvalue %[[call]], %[[desc1]][1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 364 // BAREPTR-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 365 // BAREPTR-NEXT: %[[desc4:.*]] = llvm.insertvalue %[[c0]], %[[desc2]][2] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 366 // BAREPTR-NEXT: %[[c20:.*]] = llvm.mlir.constant(20 : index) : !llvm.i64 367 // BAREPTR-NEXT: %[[desc6:.*]] = llvm.insertvalue %[[c20]], %[[desc4]][3, 0] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 368 // BAREPTR-NEXT: %[[c1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 369 // BAREPTR-NEXT: %[[outDesc:.*]] = llvm.insertvalue %[[c1]], %[[desc6]][4, 0] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 370 %res = call @foo(%in) : (memref<10xi8>) -> (memref<20xi8>) 371 // BAREPTR-NEXT: %[[res:.*]] = llvm.extractvalue %[[outDesc]][1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 372 // BAREPTR-NEXT: llvm.return %[[res]] : !llvm.ptr<i8> 373 return %res : memref<20xi8> 374} 375 376// ----- 377 378// BAREPTR: llvm.func @goo(!llvm.float) -> !llvm.float 379func private @goo(f32) -> f32 380 381// BAREPTR-LABEL: func @check_scalar_func_call 382// BAREPTR-SAME: %[[in:.*]]: !llvm.float) 383func @check_scalar_func_call(%in : f32) { 384 // BAREPTR-NEXT: %[[call:.*]] = llvm.call @goo(%[[in]]) : (!llvm.float) -> !llvm.float 385 %res = call @goo(%in) : (f32) -> (f32) 386 return 387} 388 389// ----- 390 391// Unranked memrefs are currently not supported in the bare-ptr calling 392// convention. Check that the conversion to the LLVM-IR dialect doesn't happen 393// in the presence of unranked memrefs when using such a calling convention. 394 395// BAREPTR: func private @hoo(memref<*xi8>) -> memref<*xi8> 396func private @hoo(memref<*xi8>) -> memref<*xi8> 397 398// BAREPTR-LABEL: func @check_unranked_memref_func_call(%{{.*}}: memref<*xi8>) -> memref<*xi8> 399func @check_unranked_memref_func_call(%in: memref<*xi8>) -> memref<*xi8> { 400 // BAREPTR-NEXT: call @hoo(%{{.*}}) : (memref<*xi8>) -> memref<*xi8> 401 %res = call @hoo(%in) : (memref<*xi8>) -> memref<*xi8> 402 // BAREPTR-NEXT: return %{{.*}} : memref<*xi8> 403 return %res : memref<*xi8> 404} 405