diff --git a/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h b/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h --- a/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h +++ b/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h @@ -532,11 +532,15 @@ /// Returns the type of a pointer to an element of the memref. Type getElementPtrType(MemRefType type) const; - /// Determines sizes to be used in the memref descriptor. + /// Determines sizes, strides and buffer size in bytes of a memref with + /// identity layout. The memref may have dynamic shape, and the size of the + /// dynamic dimensions are taken from `dynamicSizes`. void getMemRefDescriptorSizes(Location loc, MemRefType memRefType, - ArrayRef dynSizes, + ArrayRef dynamicSizes, ConversionPatternRewriter &rewriter, - SmallVectorImpl &sizes) const; + SmallVectorImpl &sizes, + SmallVectorImpl &strides, + Value &sizeBytes) const; /// Computes the size of type in bytes. Value getSizeInBytes(Location loc, Type type, @@ -546,18 +550,11 @@ Value getNumElements(Location loc, ArrayRef shape, ConversionPatternRewriter &rewriter) const; - /// Computes total size in bytes of to store the given shape. - Value getCumulativeSizeInBytes(Location loc, Type elementType, - ArrayRef shape, - ConversionPatternRewriter &rewriter) const; - - /// Creates and populates the memref descriptor struct given all its fields. - /// 'strides' can be either dynamic (kDynamicStrideOrOffset) or static, but - /// not a mix of the two. + /// Creates and populates a canonical memref descriptor struct. MemRefDescriptor createMemRefDescriptor(Location loc, MemRefType memRefType, - Value allocatedPtr, Value alignedPtr, uint64_t offset, - ArrayRef strides, ArrayRef sizes, + Value allocatedPtr, Value alignedPtr, + ArrayRef sizes, ArrayRef strides, ConversionPatternRewriter &rewriter) const; protected: diff --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertLaunchFuncToLLVMCalls.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertLaunchFuncToLLVMCalls.cpp --- a/mlir/lib/Conversion/SPIRVToLLVM/ConvertLaunchFuncToLLVMCalls.cpp +++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertLaunchFuncToLLVMCalls.cpp @@ -211,10 +211,10 @@ // Calculate the size of the memref and get the pointer to the allocated // buffer. SmallVector sizes; + SmallVector strides; + Value sizeBytes; getMemRefDescriptorSizes(loc, memRefType, operand.value(), rewriter, - sizes); - Value size = getCumulativeSizeInBytes(loc, memRefType.getElementType(), - sizes, rewriter); + sizes, strides, sizeBytes); MemRefDescriptor descriptor(operand.value()); Value src = descriptor.allocatedPtr(rewriter, loc); @@ -244,12 +244,12 @@ // src, dst and size so that we can copy data back after emulating the // kernel call. Value dst = rewriter.create(loc, dstGlobal); - copy(loc, dst, src, size, rewriter); + copy(loc, dst, src, sizeBytes, rewriter); CopyInfo info; info.dst = dst; info.src = src; - info.size = size; + info.size = sizeBytes; copyInfo.push_back(info); } // Create a call to the kernel and copy the data back. diff --git a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp --- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp @@ -1111,14 +1111,51 @@ } void ConvertToLLVMPattern::getMemRefDescriptorSizes( - Location loc, MemRefType memRefType, ArrayRef dynSizes, - ConversionPatternRewriter &rewriter, SmallVectorImpl &sizes) const { + Location loc, MemRefType memRefType, ArrayRef dynamicSizes, + ConversionPatternRewriter &rewriter, SmallVectorImpl &sizes, + SmallVectorImpl &strides, Value &sizeBytes) const { + assert(isSupportedMemRefType(memRefType) && + "layout maps must have been normalized away"); + sizes.reserve(memRefType.getRank()); - unsigned i = 0; - for (int64_t s : memRefType.getShape()) - sizes.push_back(s == ShapedType::kDynamicSize - ? dynSizes[i++] - : createIndexConstant(rewriter, loc, s)); + unsigned dynamicIndex = 0; + for (int64_t size : memRefType.getShape()) { + sizes.push_back(size == ShapedType::kDynamicSize + ? dynamicSizes[dynamicIndex++] + : createIndexConstant(rewriter, loc, size)); + } + + // Strides: iterate sizes in reverse order and multiply. + int64_t stride = 1; + Value runningStride = createIndexConstant(rewriter, loc, 1); + strides.resize(memRefType.getRank()); + for (auto i = memRefType.getRank(); i-- > 0;) { + strides[i] = runningStride; + + int64_t size = memRefType.getShape()[i]; + if (size == 0) + continue; + bool useSizeAsStride = stride == 1; + if (size == ShapedType::kDynamicSize) + stride = ShapedType::kDynamicSize; + if (stride != ShapedType::kDynamicSize) + stride *= size; + + if (useSizeAsStride) + runningStride = sizes[i]; + else if (stride == ShapedType::kDynamicSize) + runningStride = + rewriter.create(loc, runningStride, sizes[i]); + else + runningStride = createIndexConstant(rewriter, loc, stride); + } + + // Buffer size in bytes. + Type elementPtrType = getElementPtrType(memRefType); + Value nullPtr = rewriter.create(loc, elementPtrType); + Value gepPtr = rewriter.create( + loc, elementPtrType, ArrayRef{nullPtr, runningStride}); + sizeBytes = rewriter.create(loc, getIndexType(), gepPtr); } Value ConvertToLLVMPattern::getSizeInBytes( @@ -1148,18 +1185,10 @@ return numElements; } -Value ConvertToLLVMPattern::getCumulativeSizeInBytes( - Location loc, Type elementType, ArrayRef shape, - ConversionPatternRewriter &rewriter) const { - Value numElements = this->getNumElements(loc, shape, rewriter); - Value elementSize = this->getSizeInBytes(loc, elementType, rewriter); - return rewriter.create(loc, numElements, elementSize); -} - /// Creates and populates the memref descriptor struct given all its fields. MemRefDescriptor ConvertToLLVMPattern::createMemRefDescriptor( Location loc, MemRefType memRefType, Value allocatedPtr, Value alignedPtr, - uint64_t offset, ArrayRef strides, ArrayRef sizes, + ArrayRef sizes, ArrayRef strides, ConversionPatternRewriter &rewriter) const { auto structType = typeConverter.convertType(memRefType); auto memRefDescriptor = MemRefDescriptor::undef(rewriter, loc, structType); @@ -1172,37 +1201,16 @@ // Field 3: Offset in aligned pointer. memRefDescriptor.setOffset(rewriter, loc, - createIndexConstant(rewriter, loc, offset)); - - if (memRefType.getRank() == 0) - // No size/stride descriptor in memref, return the descriptor value. - return memRefDescriptor; - - // Fields 4 and 5: sizes and strides of the strided MemRef. - // Store all sizes in the descriptor. Only dynamic sizes are passed in as - // operands to AllocOp. - Value runningStride = nullptr; - // Iterate strides in reverse order, compute runningStride and strideValues. - auto nStrides = strides.size(); - SmallVector strideValues(nStrides, nullptr); - for (unsigned i = 0; i < nStrides; ++i) { - int64_t index = nStrides - 1 - i; - if (strides[index] == MemRefType::getDynamicStrideOrOffset()) - // Identity layout map is enforced in the match function, so we compute: - // `runningStride *= sizes[index + 1]` - runningStride = runningStride ? rewriter.create( - loc, runningStride, sizes[index + 1]) - : createIndexConstant(rewriter, loc, 1); - else - runningStride = createIndexConstant(rewriter, loc, strides[index]); - strideValues[index] = runningStride; - } - // Fill size and stride descriptors in memref. - for (auto indexedSize : llvm::enumerate(sizes)) { - int64_t index = indexedSize.index(); - memRefDescriptor.setSize(rewriter, loc, index, indexedSize.value()); - memRefDescriptor.setStride(rewriter, loc, index, strideValues[index]); - } + createIndexConstant(rewriter, loc, 0)); + + // Fields 4: Sizes. + for (auto en : llvm::enumerate(sizes)) + memRefDescriptor.setSize(rewriter, loc, en.index(), en.value()); + + // Field 5: Strides. + for (auto en : llvm::enumerate(strides)) + memRefDescriptor.setStride(rewriter, loc, en.index(), en.value()); + return memRefDescriptor; } @@ -1970,15 +1978,11 @@ return rewriter.create(loc, ptrType, allocatedPtr); } - /// Returns if buffer allocation needs buffer size to be computed. This size - /// feeds into the `bufferSize` argument of `allocateBuffer`. - virtual bool needsBufferSize() const { return true; } - /// Allocates the underlying buffer. Returns the allocated pointer and the /// aligned pointer. virtual std::tuple allocateBuffer(ConversionPatternRewriter &rewriter, Location loc, - Value bufferSize, Operation *op) const = 0; + Value sizeBytes, Operation *op) const = 0; private: static MemRefType getMemRefResultType(Operation *op) { @@ -2015,37 +2019,20 @@ // values and dynamic sizes are passed to 'alloc' as operands. In case of // zero-dimensional memref, assume a scalar (size 1). SmallVector sizes; - this->getMemRefDescriptorSizes(loc, memRefType, operands, rewriter, sizes); - - Value bufferSize; - if (needsBufferSize()) - bufferSize = this->getCumulativeSizeInBytes( - loc, memRefType.getElementType(), sizes, rewriter); + SmallVector strides; + Value sizeBytes; + this->getMemRefDescriptorSizes(loc, memRefType, operands, rewriter, sizes, + strides, sizeBytes); // Allocate the underlying buffer. Value allocatedPtr; Value alignedPtr; std::tie(allocatedPtr, alignedPtr) = - this->allocateBuffer(rewriter, loc, bufferSize, op); - - int64_t offset; - SmallVector strides; - auto successStrides = getStridesAndOffset(memRefType, strides, offset); - (void)successStrides; - assert(succeeded(successStrides) && "unexpected non-strided memref"); - assert(offset != MemRefType::getDynamicStrideOrOffset() && - "unexpected dynamic offset"); - - // 0-D memref corner case: they have size 1. - assert( - ((memRefType.getRank() == 0 && strides.empty() && sizes.size() == 1) || - (strides.size() == sizes.size())) && - "unexpected number of strides"); + this->allocateBuffer(rewriter, loc, sizeBytes, op); // Create the MemRef descriptor. - auto memRefDescriptor = - this->createMemRefDescriptor(loc, memRefType, allocatedPtr, alignedPtr, - offset, strides, sizes, rewriter); + auto memRefDescriptor = this->createMemRefDescriptor( + loc, memRefType, allocatedPtr, alignedPtr, sizes, strides, rewriter); // Return the final value of the descriptor. rewriter.replaceOp(op, {memRefDescriptor}); @@ -2057,7 +2044,7 @@ : AllocLikeOpLowering(AllocOp::getOperationName(), converter) {} std::tuple allocateBuffer(ConversionPatternRewriter &rewriter, - Location loc, Value bufferSize, + Location loc, Value sizeBytes, Operation *op) const override { // Heap allocations. AllocOp allocOp = cast(op); @@ -2076,14 +2063,14 @@ if (alignment) { // Adjust the allocation size to consider alignment. - bufferSize = rewriter.create(loc, bufferSize, alignment); + sizeBytes = rewriter.create(loc, sizeBytes, alignment); } // Allocate the underlying buffer and store a pointer to it in the MemRef // descriptor. Type elementPtrType = this->getElementPtrType(memRefType); Value allocatedPtr = - createAllocCall(loc, "malloc", elementPtrType, {bufferSize}, + createAllocCall(loc, "malloc", elementPtrType, {sizeBytes}, allocOp.getParentOfType(), rewriter); Value alignedPtr = allocatedPtr; @@ -2150,7 +2137,7 @@ } std::tuple allocateBuffer(ConversionPatternRewriter &rewriter, - Location loc, Value bufferSize, + Location loc, Value sizeBytes, Operation *op) const override { // Heap allocations. AllocOp allocOp = cast(op); @@ -2161,11 +2148,11 @@ // aligned_alloc requires size to be a multiple of alignment; we will pad // the size to the next multiple if necessary. if (!isMemRefSizeMultipleOf(memRefType, alignment)) - bufferSize = createAligned(rewriter, loc, bufferSize, allocAlignment); + sizeBytes = createAligned(rewriter, loc, sizeBytes, allocAlignment); Type elementPtrType = this->getElementPtrType(memRefType); Value allocatedPtr = createAllocCall( - loc, "aligned_alloc", elementPtrType, {allocAlignment, bufferSize}, + loc, "aligned_alloc", elementPtrType, {allocAlignment, sizeBytes}, allocOp.getParentOfType(), rewriter); return std::make_tuple(allocatedPtr, allocatedPtr); @@ -2186,7 +2173,7 @@ /// is set to null for stack allocations. `accessAlignment` is set if /// alignment is needed post allocation (for eg. in conjunction with malloc). std::tuple allocateBuffer(ConversionPatternRewriter &rewriter, - Location loc, Value bufferSize, + Location loc, Value sizeBytes, Operation *op) const override { // With alloca, one gets a pointer to the element type right away. @@ -2195,7 +2182,7 @@ auto elementPtrType = this->getElementPtrType(allocaOp.getType()); auto allocatedElementPtr = rewriter.create( - loc, elementPtrType, bufferSize, + loc, elementPtrType, sizeBytes, allocaOp.alignment() ? *allocaOp.alignment() : 0); return std::make_tuple(allocatedElementPtr, allocatedElementPtr); @@ -2470,14 +2457,10 @@ GetGlobalMemrefOpLowering(LLVMTypeConverter &converter) : AllocLikeOpLowering(GetGlobalMemrefOp::getOperationName(), converter) {} - /// Allocation for GetGlobalMemrefOp just returns the GV pointer, so no need - /// to compute buffer size. - bool needsBufferSize() const override { return false; } - /// Buffer "allocation" for get_global_memref op is getting the address of /// the global variable referenced. std::tuple allocateBuffer(ConversionPatternRewriter &rewriter, - Location loc, Value bufferSize, + Location loc, Value sizeBytes, Operation *op) const override { auto getGlobalOp = cast(op); MemRefType type = getGlobalOp.result().getType().cast(); diff --git a/mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir b/mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir --- a/mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir @@ -29,13 +29,12 @@ // CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> { func @mixed_alloc(%arg0: index, %arg1: index) -> memref { // CHECK: %[[c42:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 -// CHECK-NEXT: llvm.mul %[[M]], %[[c42]] : !llvm.i64 -// CHECK-NEXT: %[[sz:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64 -// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[sz]], %[[sizeof]] : !llvm.i64 +// CHECK-NEXT: %[[st0:.*]] = llvm.mul %[[N]], %[[c42]] : !llvm.i64 +// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[st0]], %[[M]] : !llvm.i64 +// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 // CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm.ptr // CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm.ptr to !llvm.ptr // CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> @@ -43,15 +42,12 @@ // CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> -// CHECK-NEXT: %[[st2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[st1:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[c42]] : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> -// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[c42]], %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> -// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> -// CHECK-NEXT: llvm.insertvalue %[[st2]], %{{.*}}[4, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> +// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> +// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> +// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> %0 = alloc(%arg0, %arg1) : memref // CHECK-NEXT: llvm.return %{{.*}} : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> return %0 : memref @@ -70,12 +66,11 @@ // CHECK-LABEL: func @dynamic_alloc( // CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> { func @dynamic_alloc(%arg0: index, %arg1: index) -> memref { -// CHECK: %[[sz:.*]] = llvm.mul %[[M]], %[[N]] : !llvm.i64 -// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[sz]], %[[sizeof]] : !llvm.i64 +// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[N]], %[[M]] : !llvm.i64 +// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 // CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm.ptr // CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm.ptr to !llvm.ptr // CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> @@ -83,12 +78,10 @@ // CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> -// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> -// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> -// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> +// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> +// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> %0 = alloc(%arg0, %arg1) : memref // CHECK-NEXT: llvm.return %{{.*}} : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> return %0 : memref @@ -99,23 +92,20 @@ // CHECK-LABEL: func @dynamic_alloca // CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> { func @dynamic_alloca(%arg0: index, %arg1: index) -> memref { -// CHECK: %[[num_elems:.*]] = llvm.mul %[[M]], %[[N]] : !llvm.i64 +// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 +// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %[[N]], %[[M]] : !llvm.i64 // CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr -// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64 +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 // CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[sz_bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr // CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> -// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> -// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> +// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> %0 = alloca(%arg0, %arg1) : memref @@ -144,12 +134,11 @@ func @stdlib_aligned_alloc(%N : index) -> memref<32x18xf32> { // ALIGNED-ALLOC-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 // ALIGNED-ALLOC-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 -// ALIGNED-ALLOC-NEXT: %[[num_elems:.*]] = llvm.mul %0, %1 : !llvm.i64 -// ALIGNED-ALLOC-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // ALIGNED-ALLOC-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// ALIGNED-ALLOC-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// ALIGNED-ALLOC-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// ALIGNED-ALLOC-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64 +// ALIGNED-ALLOC-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 +// ALIGNED-ALLOC-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr +// ALIGNED-ALLOC-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// ALIGNED-ALLOC-NEXT: %[[bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 // ALIGNED-ALLOC-NEXT: %[[alignment:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 // ALIGNED-ALLOC-NEXT: %[[allocated:.*]] = llvm.call @aligned_alloc(%[[alignment]], %[[bytes]]) : (!llvm.i64, !llvm.i64) -> !llvm.ptr // ALIGNED-ALLOC-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr to !llvm.ptr diff --git a/mlir/test/Conversion/StandardToLLVM/convert-static-memref-ops.mlir b/mlir/test/Conversion/StandardToLLVM/convert-static-memref-ops.mlir --- a/mlir/test/Conversion/StandardToLLVM/convert-static-memref-ops.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-static-memref-ops.mlir @@ -70,13 +70,11 @@ // CHECK-LABEL: func @zero_d_alloc() -> !llvm.struct<(ptr, ptr, i64)> { // BAREPTR-LABEL: func @zero_d_alloc() -> !llvm.ptr { func @zero_d_alloc() -> memref { -// CHECK-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 +// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64 -// CHECK-NEXT: llvm.call @malloc(%{{.*}}) : (!llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 +// CHECK-NEXT: llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr // CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr to !llvm.ptr // CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64)> // CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64)> @@ -84,13 +82,11 @@ // CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64)> -// BAREPTR-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64 -// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 +// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr // BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// BAREPTR-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// BAREPTR-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64 -// BAREPTR-NEXT: llvm.call @malloc(%{{.*}}) : (!llvm.i64) -> !llvm.ptr +// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 +// BAREPTR-NEXT: llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr // BAREPTR-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr to !llvm.ptr // BAREPTR-NEXT: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64)> // BAREPTR-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64)> @@ -122,14 +118,13 @@ // CHECK-LABEL: func @aligned_1d_alloc( // BAREPTR-LABEL: func @aligned_1d_alloc( func @aligned_1d_alloc() -> memref<42xf32> { -// CHECK: llvm.mlir.constant(42 : index) : !llvm.i64 +// CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 +// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr -// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64 +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 // CHECK-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 -// CHECK-NEXT: %[[allocsize:.*]] = llvm.add {{.*}}, %[[alignment]] : !llvm.i64 +// CHECK-NEXT: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : !llvm.i64 // CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm.ptr // CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr to !llvm.ptr // CHECK-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr to !llvm.i64 @@ -145,14 +140,13 @@ // CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> -// BAREPTR-NEXT: llvm.mlir.constant(42 : index) : !llvm.i64 +// BAREPTR-NEXT: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 +// BAREPTR-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr -// BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// BAREPTR-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// BAREPTR-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64 +// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 // BAREPTR-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 -// BAREPTR-NEXT: %[[allocsize:.*]] = llvm.add {{.*}}, %[[alignment]] : !llvm.i64 +// BAREPTR-NEXT: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : !llvm.i64 // BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm.ptr // BAREPTR-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr to !llvm.ptr // BAREPTR-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr to !llvm.i64 @@ -176,26 +170,18 @@ // CHECK-LABEL: func @static_alloc() -> !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> { // BAREPTR-LABEL: func @static_alloc() -> !llvm.ptr { func @static_alloc() -> memref<32x18xf32> { -// CHECK: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 -// CHECK-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 -// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %0, %1 : !llvm.i64 +// CHECK: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 // CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr -// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64 -// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[bytes]]) : (!llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 +// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr // CHECK-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr to !llvm.ptr -// BAREPTR-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 -// BAREPTR-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 -// BAREPTR-NEXT: %[[num_elems:.*]] = llvm.mul %[[sz1]], %[[sz2]] : !llvm.i64 +// BAREPTR: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 // BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr -// BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// BAREPTR-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// BAREPTR-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64 -// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[bytes]]) : (!llvm.i64) -> !llvm.ptr +// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 +// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr // BAREPTR-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr to !llvm.ptr %0 = alloc() : memref<32x18xf32> return %0 : memref<32x18xf32> @@ -207,13 +193,12 @@ func @static_alloca() -> memref<32x18xf32> { // CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 // CHECK-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 -// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %0, %1 : !llvm.i64 +// CHECK-NEXT: %[[st2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 +// CHECK-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64 // CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr -// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr -// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 -// CHECK-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64 -// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, !llvm.i64) -> !llvm.ptr +// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to !llvm.i64 +// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[size_bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr %0 = alloca() : memref<32x18xf32> // Test with explicitly specified alignment. llvm.alloca takes care of the diff --git a/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir b/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir --- a/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir +++ b/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir @@ -142,6 +142,7 @@ func @get_gv0_memref() { %0 = get_global_memref @gv0 : memref<2xf32> // CHECK: %[[DIM:.*]] = llvm.mlir.constant(2 : index) : !llvm.i64 + // CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @gv0 : !llvm.ptr> // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ADDR]][%[[ZERO]], %[[ZERO]]] : (!llvm.ptr>, !llvm.i64, !llvm.i64) -> !llvm.ptr @@ -152,7 +153,6 @@ // CHECK: llvm.insertvalue %[[GEP]], {{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> // CHECK: %[[OFFSET:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK: llvm.insertvalue %[[OFFSET]], {{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> - // CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK: llvm.insertvalue %[[DIM]], {{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> // CHECK: llvm.insertvalue %[[STRIDE]], {{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> return @@ -163,6 +163,7 @@ func @get_gv2_memref() { // CHECK: %[[DIM0:.*]] = llvm.mlir.constant(2 : index) : !llvm.i64 // CHECK: %[[DIM1:.*]] = llvm.mlir.constant(3 : index) : !llvm.i64 + // CHECK: %[[STRIDE1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @gv2 : !llvm.ptr>> // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ADDR]][%[[ZERO]], %[[ZERO]], %[[ZERO]]] : (!llvm.ptr>>, !llvm.i64, !llvm.i64, !llvm.i64) -> !llvm.ptr @@ -173,11 +174,9 @@ // CHECK: llvm.insertvalue %[[GEP]], {{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK: %[[OFFSET:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK: llvm.insertvalue %[[OFFSET]], {{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> - // CHECK: %[[STRIDE1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: %[[STRIDE0:.*]] = llvm.mlir.constant(3 : index) : !llvm.i64 // CHECK: llvm.insertvalue %[[DIM0]], {{.*}}[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> - // CHECK: llvm.insertvalue %[[STRIDE0]], {{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK: llvm.insertvalue %[[DIM1]], {{.*}}[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> + // CHECK: llvm.insertvalue %[[DIM1]], {{.*}}[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> // CHECK: llvm.insertvalue %[[STRIDE1]], {{.*}}[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)> %0 = get_global_memref @gv2 : memref<2x3xf32>