From: Nicolas Vasilache Date: Tue, 12 Nov 2019 15:06:18 +0000 (-0800) Subject: Add support for alignment attribute in std.alloc. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f51a15533729cddc9907320b5ab963f7fc037aa0;p=platform%2Fupstream%2Fllvm.git Add support for alignment attribute in std.alloc. This CL adds an extra pointer to the memref descriptor to allow specifying alignment. In a previous implementation, we used 2 types: `linalg.buffer` and `view` where the buffer type was the unit of allocation/deallocation/alignment and `view` was the unit of indexing. After multiple discussions it was decided to use a single type, which conflates both, so the memref descriptor now needs to carry both pointers. This is consistent with the [RFC-Proposed Changes to MemRef and Tensor MLIR Types](https://groups.google.com/a/tensorflow.org/forum/#!searchin/mlir/std.view%7Csort:date/mlir/-wKHANzDNTg/4K6nUAp8AAAJ). PiperOrigin-RevId: 279959463 --- diff --git a/mlir/g3doc/ConversionToLLVMDialect.md b/mlir/g3doc/ConversionToLLVMDialect.md index 2703542..ffc47ba 100644 --- a/mlir/g3doc/ConversionToLLVMDialect.md +++ b/mlir/g3doc/ConversionToLLVMDialect.md @@ -57,15 +57,17 @@ converted to a descriptor that is only dependent on the rank of the memref. The descriptor contains: 1. the pointer to the data buffer, followed by -2. a lowered `index`-type integer containing the distance between the beginning +2. the pointer to properly aligned data payload that the memref indexes, + followed by +3. a lowered `index`-type integer containing the distance between the beginning of the buffer and the first element to be accessed through the memref, followed by -3. an array containing as many `index`-type integers as the rank of the memref: +4. an array containing as many `index`-type integers as the rank of the memref: the array represents the size, in number of elements, of the memref along the given dimension. For constant MemRef dimensions, the corresponding size entry is a constant whose runtime value must match the static value, followed by -4. a second array containing as many 64-bit integers as the rank of the MemRef: +5. a second array containing as many 64-bit integers as the rank of the MemRef: the second array represents the "stride" (in tensor abstraction sense), i.e. the number of consecutive elements of the underlying buffer. @@ -73,19 +75,19 @@ For constant memref dimensions, the corresponding size entry is a constant whose runtime value matches the static value. This normalization serves as an ABI for the memref type to interoperate with externally linked functions. In the particular case of rank `0` memrefs, the size and stride arrays are omitted, -resulting in a struct containing a pointer + offset. +resulting in a struct containing two pointers + offset. Examples: ```mlir {.mlir} -memref -> !llvm.type<"{ float*, i64 }"> -memref<1 x f32> -> !llvm.type<"{ float*, i64, [1 x i64], [1 x i64] }"> -memref -> !llvm.type<"{ float*, i64, [1 x i64], [1 x i64] }"> -memref<10x42x42x43x123 x f32> -> !llvm.type<"{ float*, i64, [5 x i64], [5 x i64] }"> -memref<10x?x42x?x123 x f32> -> !llvm.type<"{ float*, i64, [5 x i64], [5 x i64] }"> +memref -> !llvm.type<"{ float*, float*, i64 }"> +memref<1 x f32> -> !llvm.type<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +memref -> !llvm.type<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +memref<10x42x42x43x123 x f32> -> !llvm.type<"{ float*, float*, i64, [5 x i64], [5 x i64] }"> +memref<10x?x42x?x123 x f32> -> !llvm.type<"{ float*, float*, i64, [5 x i64], [5 x i64] }"> // Memref types can have vectors as element types -memref<1x? x vector<4xf32>> -> !llvm.type<"{ <4 x float>*, i64, [1 x i64], [1 x i64] }"> +memref<1x? x vector<4xf32>> -> !llvm.type<"{ <4 x float>*, <4 x float>*, i64, [1 x i64], [1 x i64] }"> ``` ### Function Types diff --git a/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h b/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h index bd21c35..0fb973b 100644 --- a/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h +++ b/mlir/include/mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h @@ -82,10 +82,11 @@ public: Value *promoteOneMemRefDescriptor(Location loc, Value *operand, OpBuilder &builder); - static constexpr unsigned kPtrPosInMemRefDescriptor = 0; - static constexpr unsigned kOffsetPosInMemRefDescriptor = 1; - static constexpr unsigned kSizePosInMemRefDescriptor = 2; - static constexpr unsigned kStridePosInMemRefDescriptor = 3; + static constexpr unsigned kAllocatedPtrPosInMemRefDescriptor = 0; + static constexpr unsigned kAlignedPtrPosInMemRefDescriptor = 1; + static constexpr unsigned kOffsetPosInMemRefDescriptor = 2; + static constexpr unsigned kSizePosInMemRefDescriptor = 3; + static constexpr unsigned kStridePosInMemRefDescriptor = 4; protected: /// LLVM IR module used to parse/create types. diff --git a/mlir/include/mlir/Dialect/StandardOps/Ops.td b/mlir/include/mlir/Dialect/StandardOps/Ops.td index fa72306..57d77f7 100644 --- a/mlir/include/mlir/Dialect/StandardOps/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/Ops.td @@ -165,18 +165,35 @@ def AllocOp : Std_Op<"alloc"> { This operation returns a single ssa value of memref type, which can be used by subsequent load and store operations. + + The optional `alignment` attribute may be specified to ensure that the + region of memory that will be indexed is aligned at the specified byte + boundary. TODO(b/144281289) optional alignment attribute to MemRefType. + + %0 = alloc()[%s] {alignment = 8} : + memref<8x64xf32, (d0, d1)[s0] -> ((d0 + s0), d1), 1> }]; - let arguments = (ins Variadic:$value); + let arguments = (ins Variadic:$value, + Confined, [IntMinValue<0>]>:$alignment); let results = (outs AnyMemRef); let builders = [OpBuilder< "Builder *builder, OperationState &result, MemRefType memrefType", [{ result.types.push_back(memrefType); - }] - >]; + }]>, + OpBuilder< + "Builder *builder, OperationState &result, MemRefType memrefType, " # + "ArrayRef operands, IntegerAttr alignment = IntegerAttr()", [{ + result.addOperands(operands); + result.types.push_back(memrefType); + if (alignment) + result.addAttribute(getAlignmentAttrName(), alignment); + }]>]; let extraClassDeclaration = [{ + static StringRef getAlignmentAttrName() { return "alignment"; } + MemRefType getType() { return getResult()->getType().cast(); } /// Returns the number of symbolic operands (the ones in square brackets), diff --git a/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp index 1584bd4..84eba82 100644 --- a/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp @@ -151,12 +151,14 @@ LLVM::LLVMType LLVMTypeConverter::convertFunctionSignature( // // template // struct { -// Elem *ptr; +// Elem *allocatedPtr; +// Elem *alignedPtr; // int64_t offset; // int64_t sizes[Rank]; // omitted when rank == 0 // int64_t strides[Rank]; // omitted when rank == 0 // }; -constexpr unsigned LLVMTypeConverter::kPtrPosInMemRefDescriptor; +constexpr unsigned LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor; +constexpr unsigned LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor; constexpr unsigned LLVMTypeConverter::kOffsetPosInMemRefDescriptor; constexpr unsigned LLVMTypeConverter::kSizePosInMemRefDescriptor; constexpr unsigned LLVMTypeConverter::kStridePosInMemRefDescriptor; @@ -175,9 +177,9 @@ Type LLVMTypeConverter::convertMemRefType(MemRefType type) { auto rank = type.getRank(); if (rank > 0) { auto arrayTy = LLVM::LLVMType::getArrayTy(indexTy, type.getRank()); - return LLVM::LLVMType::getStructTy(ptrTy, indexTy, arrayTy, arrayTy); + return LLVM::LLVMType::getStructTy(ptrTy, ptrTy, indexTy, arrayTy, arrayTy); } - return LLVM::LLVMType::getStructTy(ptrTy, indexTy); + return LLVM::LLVMType::getStructTy(ptrTy, ptrTy, indexTy); } // Convert an n-D vector type to an LLVM vector type via (n-1)-D array type when @@ -276,14 +278,27 @@ public: return builder.create(loc, getIndexType(), attr); } - // Extract raw data pointer value from a value representing a memref. - static Value *extractMemRefElementPtr(ConversionPatternRewriter &builder, - Location loc, Value *memref, - Type elementTypePtr) { + // Extract allocated data pointer value from a value representing a memref. + static Value * + extractAllocatedMemRefElementPtr(ConversionPatternRewriter &builder, + Location loc, Value *memref, + Type elementTypePtr) { return builder.create( loc, elementTypePtr, memref, - builder.getIndexArrayAttr( - LLVMTypeConverter::kPtrPosInMemRefDescriptor)); + builder.getI64ArrayAttr( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor)); + } + + // Extract properly aligned data pointer value from a value representing a + // memref. + static Value * + extractAlignedMemRefElementPtr(ConversionPatternRewriter &builder, + Location loc, Value *memref, + Type elementTypePtr) { + return builder.create( + loc, elementTypePtr, memref, + builder.getI64ArrayAttr( + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor)); } protected: @@ -442,7 +457,7 @@ void nDVectorIterate(const NDVectorTypeInfo &info, OpBuilder &builder, if (coords.empty()) break; assert(coords.size() == info.arraySizes.size()); - auto position = builder.getIndexArrayAttr(coords); + auto position = builder.getI64ArrayAttr(coords); fun(position); } } @@ -488,7 +503,7 @@ struct OneToOneLLVMOpLowering : public LLVMLegalizationPattern { auto type = this->lowering.convertType(op->getResult(i)->getType()); results.push_back(rewriter.create( op->getLoc(), type, newOp.getOperation()->getResult(0), - rewriter.getIndexArrayAttr(i))); + rewriter.getI64ArrayAttr(i))); } rewriter.replaceOp(op, results); return this->matchSuccess(); @@ -650,9 +665,16 @@ static bool isSupportedMemRefType(MemRefType type) { // An `alloc` is converted into a definition of a memref descriptor value and // a call to `malloc` to allocate the underlying data buffer. The memref -// descriptor is of the LLVM structure type where the first element is a pointer -// to the (typed) data buffer, and the remaining elements serve to store -// dynamic sizes of the memref using LLVM-converted `index` type. +// descriptor is of the LLVM structure type where: +// 1. the first element is a pointer to the allocated (typed) data buffer, +// 2. the second element is a pointer to the (typed) payload, aligned to the +// specified alignment, +// 3. the remaining elements serve to store all the sizes and strides of the +// memref using LLVM-converted `index` type. +// +// Alignment is obtained by allocating `alignment - 1` more bytes than requested +// and shifting the aligned pointer relative to the allocated memory. If +// alignment is unspecified, the two pointers are equal. struct AllocOpLowering : public LLVMLegalizationPattern { using LLVMLegalizationPattern::LLVMLegalizationPattern; @@ -678,6 +700,7 @@ struct AllocOpLowering : public LLVMLegalizationPattern { void rewrite(Operation *op, ArrayRef operands, ConversionPatternRewriter &rewriter) const override { + auto loc = op->getLoc(); auto allocOp = cast(op); MemRefType type = allocOp.getType(); @@ -689,16 +712,15 @@ struct AllocOpLowering : public LLVMLegalizationPattern { unsigned i = 0; for (int64_t s : type.getShape()) sizes.push_back(s == -1 ? operands[i++] - : createIndexConstant(rewriter, op->getLoc(), s)); + : createIndexConstant(rewriter, loc, s)); if (sizes.empty()) - sizes.push_back(createIndexConstant(rewriter, op->getLoc(), 1)); + sizes.push_back(createIndexConstant(rewriter, loc, 1)); // Compute the total number of memref elements. Value *cumulativeSize = sizes.front(); for (unsigned i = 1, e = sizes.size(); i < e; ++i) cumulativeSize = rewriter.create( - op->getLoc(), getIndexType(), - ArrayRef{cumulativeSize, sizes[i]}); + loc, getIndexType(), ArrayRef{cumulativeSize, sizes[i]}); // Compute the size of an individual element. This emits the MLIR equivalent // of the following sizeof(...) implementation in LLVM IR: @@ -708,16 +730,14 @@ struct AllocOpLowering : public LLVMLegalizationPattern { auto elementType = type.getElementType(); auto convertedPtrType = lowering.convertType(elementType).cast().getPointerTo(); - auto nullPtr = - rewriter.create(op->getLoc(), convertedPtrType); - auto one = createIndexConstant(rewriter, op->getLoc(), 1); - auto gep = rewriter.create(op->getLoc(), convertedPtrType, + auto nullPtr = rewriter.create(loc, convertedPtrType); + auto one = createIndexConstant(rewriter, loc, 1); + auto gep = rewriter.create(loc, convertedPtrType, ArrayRef{nullPtr, one}); auto elementSize = - rewriter.create(op->getLoc(), getIndexType(), gep); + rewriter.create(loc, getIndexType(), gep); cumulativeSize = rewriter.create( - op->getLoc(), getIndexType(), - ArrayRef{cumulativeSize, elementSize}); + loc, getIndexType(), ArrayRef{cumulativeSize, elementSize}); // Insert the `malloc` declaration if it is not already present. auto module = op->getParentOfType(); @@ -732,17 +752,24 @@ struct AllocOpLowering : public LLVMLegalizationPattern { // Allocate the underlying buffer and store a pointer to it in the MemRef // descriptor. + Value *align = nullptr; + if (auto alignAttr = allocOp.alignment()) { + align = createIndexConstant(rewriter, loc, + alignAttr.getValue().getSExtValue()); + cumulativeSize = rewriter.create( + loc, rewriter.create(loc, cumulativeSize, align), one); + } Value *allocated = rewriter - .create(op->getLoc(), getVoidPtrType(), + .create(loc, getVoidPtrType(), rewriter.getSymbolRefAttr(mallocFunc), cumulativeSize) .getResult(0); auto structElementType = lowering.convertType(elementType); auto elementPtrType = structElementType.cast().getPointerTo( type.getMemorySpace()); - allocated = rewriter.create(op->getLoc(), elementPtrType, - ArrayRef(allocated)); + Value *bitcastAllocated = rewriter.create( + loc, elementPtrType, ArrayRef(allocated)); int64_t offset; SmallVector strides; @@ -759,23 +786,44 @@ struct AllocOpLowering : public LLVMLegalizationPattern { // Create the MemRef descriptor. auto structType = lowering.convertType(type); - Value *memRefDescriptor = rewriter.create( - op->getLoc(), structType, ArrayRef{}); + Value *memRefDescriptor = + rewriter.create(loc, structType, ArrayRef{}); + // Field 1: Allocated pointer, used for malloc/free. + memRefDescriptor = rewriter.create( + loc, structType, memRefDescriptor, bitcastAllocated, + rewriter.getI64ArrayAttr( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor)); + // Field 2: Actual aligned pointer to payload. + Value *bitcastAligned = bitcastAllocated; + if (align) { + // offset = (align - (ptr % align))% align + Value *intVal = rewriter.create( + loc, this->getIndexType(), allocated); + Value *ptrModAlign = rewriter.create(loc, intVal, align); + Value *subbed = rewriter.create(loc, align, ptrModAlign); + Value *offset = rewriter.create(loc, subbed, align); + Value *aligned = rewriter.create(loc, allocated->getType(), + allocated, offset); + bitcastAligned = rewriter.create( + loc, elementPtrType, ArrayRef(aligned)); + } memRefDescriptor = rewriter.create( - op->getLoc(), structType, memRefDescriptor, allocated, - rewriter.getIndexArrayAttr( - LLVMTypeConverter::kPtrPosInMemRefDescriptor)); + loc, structType, memRefDescriptor, bitcastAligned, + rewriter.getI64ArrayAttr( + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor)); + // Field 3: Offset in aligned pointer. memRefDescriptor = rewriter.create( - op->getLoc(), structType, memRefDescriptor, - createIndexConstant(rewriter, op->getLoc(), offset), - rewriter.getIndexArrayAttr( + loc, structType, memRefDescriptor, + createIndexConstant(rewriter, loc, offset), + rewriter.getI64ArrayAttr( LLVMTypeConverter::kOffsetPosInMemRefDescriptor)); if (type.getRank() == 0) // No size/stride descriptor in memref, return the descriptor value. return rewriter.replaceOp(op, 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; @@ -787,24 +835,23 @@ struct AllocOpLowering : public LLVMLegalizationPattern { if (strides[index] == MemRefType::getDynamicStrideOrOffset()) // Identity layout map is enforced in the match function, so we compute: // `runningStride *= sizes[index]` - runningStride = runningStride - ? rewriter.create( - op->getLoc(), runningStride, sizes[index]) - : createIndexConstant(rewriter, op->getLoc(), 1); - else runningStride = - createIndexConstant(rewriter, op->getLoc(), strides[index]); + runningStride + ? rewriter.create(loc, runningStride, sizes[index]) + : 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 = rewriter.create( - op->getLoc(), structType, memRefDescriptor, indexedSize.value(), + loc, structType, memRefDescriptor, indexedSize.value(), rewriter.getI64ArrayAttr( {LLVMTypeConverter::kSizePosInMemRefDescriptor, index})); memRefDescriptor = rewriter.create( - op->getLoc(), structType, memRefDescriptor, strideValues[index], + loc, structType, memRefDescriptor, strideValues[index], rewriter.getI64ArrayAttr( {LLVMTypeConverter::kStridePosInMemRefDescriptor, index})); } @@ -861,7 +908,7 @@ struct CallOpInterfaceLowering : public LLVMLegalizationPattern { auto type = this->lowering.convertType(op->getResult(i)->getType()); results.push_back(rewriter.create( op->getLoc(), type, newOp.getOperation()->getResult(0), - rewriter.getIndexArrayAttr(i))); + rewriter.getI64ArrayAttr(i))); } rewriter.replaceOp(op, results); @@ -901,9 +948,9 @@ struct DeallocOpLowering : public LLVMLegalizationPattern { } auto type = transformed.memref()->getType().cast(); - Type elementPtrType = - type.getStructElementType(LLVMTypeConverter::kPtrPosInMemRefDescriptor); - Value *bufferPtr = extractMemRefElementPtr( + Type elementPtrType = type.getStructElementType( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor); + Value *bufferPtr = extractAllocatedMemRefElementPtr( rewriter, op->getLoc(), transformed.memref(), elementPtrType); Value *casted = rewriter.create( op->getLoc(), getVoidPtrType(), bufferPtr); @@ -1016,13 +1063,13 @@ struct LoadStoreOpLowering : public LLVMLegalizationPattern { ArrayRef strides, int64_t offset, ConversionPatternRewriter &rewriter) const { auto indexTy = this->getIndexType(); - Value *base = this->extractMemRefElementPtr(rewriter, loc, memRefDescriptor, - elementTypePtr); + Value *base = this->extractAlignedMemRefElementPtr( + rewriter, loc, memRefDescriptor, elementTypePtr); Value *offsetValue = offset == MemRefType::getDynamicStrideOrOffset() ? rewriter.create( loc, indexTy, memRefDescriptor, - rewriter.getIndexArrayAttr( + rewriter.getI64ArrayAttr( LLVMTypeConverter::kOffsetPosInMemRefDescriptor)) : this->createIndexConstant(rewriter, loc, offset); for (int i = 0, e = indices.size(); i < e; ++i) { @@ -1036,7 +1083,7 @@ struct LoadStoreOpLowering : public LLVMLegalizationPattern { // Use dynamic stride. stride = rewriter.create( loc, indexTy, memRefDescriptor, - rewriter.getIndexArrayAttr( + rewriter.getI64ArrayAttr( {LLVMTypeConverter::kStridePosInMemRefDescriptor, i})); } Value *additionalOffset = @@ -1261,7 +1308,7 @@ struct ReturnOpLowering : public LLVMLegalizationPattern { for (unsigned i = 0; i < numArguments; ++i) { packed = rewriter.create( op->getLoc(), packedType, packed, operands[i], - rewriter.getIndexArrayAttr(i)); + rewriter.getI64ArrayAttr(i)); } rewriter.replaceOpWithNewOp(op, llvm::makeArrayRef(packed), llvm::ArrayRef(), @@ -1436,19 +1483,32 @@ struct ViewOpLowering : public LLVMLegalizationPattern { // Create the descriptor. Value *desc = rewriter.create(loc, targetDescTy); - // Copy the buffer pointer from the old descriptor to the new one. + // Field 1: Copy the allocated pointer, used for malloc/free. Value *sourceDescriptor = adaptor.source(); + Value *extracted = rewriter.create( + loc, sourceElementTy.getPointerTo(), sourceDescriptor, + rewriter.getI64ArrayAttr( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor)); Value *bitcastPtr = rewriter.create( - loc, targetElementTy.getPointerTo(), - rewriter.create( - loc, sourceElementTy.getPointerTo(), sourceDescriptor, - rewriter.getI64ArrayAttr( - LLVMTypeConverter::kPtrPosInMemRefDescriptor))); + loc, targetElementTy.getPointerTo(), extracted); desc = rewriter.create( loc, desc, bitcastPtr, - rewriter.getI64ArrayAttr(LLVMTypeConverter::kPtrPosInMemRefDescriptor)); + rewriter.getI64ArrayAttr( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor)); + + // Field 2: Copy the actual aligned pointer to payload. + extracted = rewriter.create( + loc, sourceElementTy.getPointerTo(), sourceDescriptor, + rewriter.getI64ArrayAttr( + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor)); + bitcastPtr = rewriter.create( + loc, targetElementTy.getPointerTo(), extracted); + desc = rewriter.create( + loc, desc, bitcastPtr, + rewriter.getI64ArrayAttr( + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor)); - // Offset. + // Field 3: Copy the offset in aligned pointer. unsigned numDynamicSizes = llvm::size(viewOp.getDynamicSizes()); (void)numDynamicSizes; auto sizeAndOffsetOperands = adaptor.operands(); @@ -1467,7 +1527,7 @@ struct ViewOpLowering : public LLVMLegalizationPattern { if (viewMemRefType.getRank() == 0) return rewriter.replaceOp(op, desc), matchSuccess(); - // Update sizes and strides. + // Fields 4 and 5: Update sizes and strides. if (strides.back() != 1) return op->emitWarning("cannot cast to non-contiguous shape"), matchFailure(); diff --git a/mlir/lib/Conversion/VectorToLLVM/VectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/VectorToLLVM.cpp index 765c25a..5ccf740 100644 --- a/mlir/lib/Conversion/VectorToLLVM/VectorToLLVM.cpp +++ b/mlir/lib/Conversion/VectorToLLVM/VectorToLLVM.cpp @@ -189,9 +189,9 @@ public: return matchFailure(); Type llvmSourceElementTy = llvmSourceDescriptorTy.getStructElementType( - LLVMTypeConverter::kPtrPosInMemRefDescriptor); + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor); Type llvmTargetElementTy = llvmTargetDescriptorTy.getStructElementType( - LLVMTypeConverter::kPtrPosInMemRefDescriptor); + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor); int64_t offset; SmallVector strides; @@ -215,16 +215,27 @@ public: // Create descriptor. Value *desc = rewriter.create(loc, llvmTargetDescriptorTy); + // Set allocated ptr. + Value *allocated = rewriter.create( + loc, llvmSourceElementTy, sourceMemRef, + rewriter.getIndexArrayAttr( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor)); + allocated = + rewriter.create(loc, llvmTargetElementTy, allocated); + desc = rewriter.create( + op->getLoc(), llvmTargetDescriptorTy, desc, allocated, + rewriter.getIndexArrayAttr( + LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor)); // Set ptr. Value *ptr = rewriter.create( loc, llvmSourceElementTy, sourceMemRef, rewriter.getIndexArrayAttr( - LLVMTypeConverter::kPtrPosInMemRefDescriptor)); + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor)); ptr = rewriter.create(loc, llvmTargetElementTy, ptr); desc = rewriter.create( op->getLoc(), llvmTargetDescriptorTy, desc, ptr, rewriter.getIndexArrayAttr( - LLVMTypeConverter::kPtrPosInMemRefDescriptor)); + LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor)); // Fill offset 0. auto attr = rewriter.getIntegerAttr(rewriter.getIndexType(), 0); auto zero = rewriter.create(loc, int64Ty, attr); diff --git a/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp b/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp index 2dc46bf..05f4bce 100644 --- a/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp @@ -127,14 +127,6 @@ static Type convertLinalgType(Type t, LLVMTypeConverter &lowering) { return Type(); } -static constexpr int kBasePtrPosInBuffer = 0; -static constexpr int kPtrPosInBuffer = 1; -static constexpr int kSizePosInBuffer = 2; -static constexpr int kPtrPosInView = 0; -static constexpr int kOffsetPosInView = 1; -static constexpr int kSizePosInView = 2; -static constexpr int kStridePosInView = 3; - namespace { /// Factor out the common information for all view conversions: /// 1. common types in (standard and LLVM dialects) @@ -224,12 +216,14 @@ public: // TODO(ntv): extract sizes and emit asserts. SmallVector strides(memRefType.getRank()); for (int i = 0, e = memRefType.getRank(); i < e; ++i) - strides[i] = - extractvalue(int64Ty, baseDesc, helper.pos({kStridePosInView, i})); + strides[i] = extractvalue( + int64Ty, baseDesc, + helper.pos({LLVMTypeConverter::kStridePosInMemRefDescriptor, i})); // Compute base offset. - Value *baseOffset = - extractvalue(int64Ty, baseDesc, helper.pos(kOffsetPosInView)); + Value *baseOffset = extractvalue( + int64Ty, baseDesc, + helper.pos(LLVMTypeConverter::kOffsetPosInMemRefDescriptor)); for (int i = 0, e = memRefType.getRank(); i < e; ++i) { Value *indexing = adaptor.indexings()[i]; Value *min = indexing; @@ -238,12 +232,17 @@ public: baseOffset = add(baseOffset, mul(min, strides[i])); } - // Insert base pointer. - auto ptrPos = helper.pos(kPtrPosInView); + // Insert the base and aligned pointers. + auto ptrPos = + helper.pos(LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor); + desc = insertvalue(desc, extractvalue(elementTy, baseDesc, ptrPos), ptrPos); + ptrPos = helper.pos(LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor); desc = insertvalue(desc, extractvalue(elementTy, baseDesc, ptrPos), ptrPos); // Insert base offset. - desc = insertvalue(desc, baseOffset, helper.pos(kOffsetPosInView)); + desc = insertvalue( + desc, baseOffset, + helper.pos(LLVMTypeConverter::kOffsetPosInMemRefDescriptor)); // Corner case, no sizes or strides: early return the descriptor. if (helper.zeroDMemRef) @@ -262,8 +261,9 @@ public: Value *min = extractvalue(int64Ty, rangeDescriptor, helper.pos(0)); Value *max = extractvalue(int64Ty, rangeDescriptor, helper.pos(1)); Value *step = extractvalue(int64Ty, rangeDescriptor, helper.pos(2)); - Value *baseSize = - extractvalue(int64Ty, baseDesc, helper.pos({kSizePosInView, rank})); + Value *baseSize = extractvalue( + int64Ty, baseDesc, + helper.pos({LLVMTypeConverter::kSizePosInMemRefDescriptor, rank})); // Bound upper by base view upper bound. max = llvm_select(llvm_icmp(ICmpPredicate::slt, max, baseSize), max, baseSize); @@ -272,10 +272,14 @@ public: size = llvm_select(llvm_icmp(ICmpPredicate::slt, size, zero), zero, size); Value *stride = mul(strides[rank], step); - desc = - insertvalue(desc, size, helper.pos({kSizePosInView, numNewDims})); - desc = insertvalue(desc, stride, - helper.pos({kStridePosInView, numNewDims})); + desc = insertvalue( + desc, size, + helper.pos( + {LLVMTypeConverter::kSizePosInMemRefDescriptor, numNewDims})); + desc = insertvalue( + desc, stride, + helper.pos( + {LLVMTypeConverter::kStridePosInMemRefDescriptor, numNewDims})); ++numNewDims; } } @@ -316,25 +320,39 @@ public: Value *desc = helper.desc; edsc::ScopedContext context(rewriter, op->getLoc()); - // Copy the base pointer from the old descriptor to the new one. - ArrayAttr ptrPos = helper.pos(kPtrPosInView); + // Copy the base and aligned pointers from the old descriptor to the new + // one. + ArrayAttr ptrPos = + helper.pos(LLVMTypeConverter::kAllocatedPtrPosInMemRefDescriptor); + desc = insertvalue(desc, extractvalue(elementTy, baseDesc, ptrPos), ptrPos); + ptrPos = helper.pos(LLVMTypeConverter::kAlignedPtrPosInMemRefDescriptor); desc = insertvalue(desc, extractvalue(elementTy, baseDesc, ptrPos), ptrPos); // Copy the offset pointer from the old descriptor to the new one. - ArrayAttr offPos = helper.pos(kOffsetPosInView); + ArrayAttr offPos = + helper.pos(LLVMTypeConverter::kOffsetPosInMemRefDescriptor); desc = insertvalue(desc, extractvalue(int64Ty, baseDesc, offPos), offPos); // Iterate over the dimensions and apply size/stride permutation. for (auto en : llvm::enumerate(transposeOp.permutation().getResults())) { int sourcePos = en.index(); int targetPos = en.value().cast().getPosition(); - Value *size = extractvalue(int64Ty, baseDesc, - helper.pos({kSizePosInView, sourcePos})); - desc = insertvalue(desc, size, helper.pos({kSizePosInView, targetPos})); - Value *stride = extractvalue(int64Ty, baseDesc, - helper.pos({kStridePosInView, sourcePos})); + Value *size = extractvalue( + int64Ty, baseDesc, + helper.pos( + {LLVMTypeConverter::kSizePosInMemRefDescriptor, sourcePos})); desc = - insertvalue(desc, stride, helper.pos({kStridePosInView, targetPos})); + insertvalue(desc, size, + helper.pos({LLVMTypeConverter::kSizePosInMemRefDescriptor, + targetPos})); + Value *stride = extractvalue( + int64Ty, baseDesc, + helper.pos( + {LLVMTypeConverter::kStridePosInMemRefDescriptor, sourcePos})); + desc = insertvalue( + desc, stride, + helper.pos( + {LLVMTypeConverter::kStridePosInMemRefDescriptor, targetPos})); } rewriter.replaceOp(op, desc); diff --git a/mlir/lib/Dialect/StandardOps/Ops.cpp b/mlir/lib/Dialect/StandardOps/Ops.cpp index 8c08868..f152ccf 100644 --- a/mlir/lib/Dialect/StandardOps/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/Ops.cpp @@ -438,8 +438,8 @@ struct SimplifyAllocConst : public OpRewritePattern { newMemRefType.getNumDynamicDims()); // Create and insert the alloc op for the new memref. - auto newAlloc = - rewriter.create(alloc.getLoc(), newMemRefType, newOperands); + auto newAlloc = rewriter.create(alloc.getLoc(), newMemRefType, + newOperands, IntegerAttr()); // Insert a cast so we have the same type as the old alloc. auto resultCast = rewriter.create(alloc.getLoc(), newAlloc, alloc.getType()); diff --git a/mlir/test/Conversion/StandardToLLVM/convert-argattrs.mlir b/mlir/test/Conversion/StandardToLLVM/convert-argattrs.mlir index 2c19505..30dc165 100644 --- a/mlir/test/Conversion/StandardToLLVM/convert-argattrs.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-argattrs.mlir @@ -1,21 +1,21 @@ // RUN: mlir-opt -lower-to-llvm %s | FileCheck %s -// CHECK-LABEL: func @check_attributes(%arg0: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> {dialect.a = true, dialect.b = 4 : i64}) { -// CHECK-NEXT: llvm.load %arg0 : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-LABEL: func @check_attributes(%arg0: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> {dialect.a = true, dialect.b = 4 : i64}) { +// CHECK-NEXT: llvm.load %arg0 : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> func @check_attributes(%static: memref<10x20xf32> {dialect.a = true, dialect.b = 4 : i64 }) { %c0 = constant 0 : index %0 = load %static[%c0, %c0]: memref<10x20xf32> return } -// CHECK-LABEL: func @external_func(!llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) -// CHECK: func @call_external(%[[arg:.*]]: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) { -// CHECK: %[[ld:.*]] = llvm.load %[[arg]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-LABEL: func @external_func(!llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) +// CHECK: func @call_external(%[[arg:.*]]: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) { +// CHECK: %[[ld:.*]] = llvm.load %[[arg]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> // CHECK: %[[c1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 -// CHECK: %[[alloca:.*]] = llvm.alloca %[[c1]] x !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> : (!llvm.i64) -> !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK: llvm.store %[[ld]], %[[alloca]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK: call @external_func(%[[alloca]]) : (!llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) -> () +// CHECK: %[[alloca:.*]] = llvm.alloca %[[c1]] x !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> : (!llvm.i64) -> !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK: llvm.store %[[ld]], %[[alloca]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK: call @external_func(%[[alloca]]) : (!llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) -> () func @external_func(memref<10x20xf32>) func @call_external(%static: memref<10x20xf32>) { diff --git a/mlir/test/Conversion/StandardToLLVM/convert-memref-ops.mlir b/mlir/test/Conversion/StandardToLLVM/convert-memref-ops.mlir index 4db4bf9..54e7aaa 100644 --- a/mlir/test/Conversion/StandardToLLVM/convert-memref-ops.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-memref-ops.mlir @@ -1,25 +1,25 @@ // RUN: mlir-opt -lower-to-llvm %s | FileCheck %s -// CHECK-LABEL: func @check_arguments(%arg0: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">, %arg1: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">, %arg2: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) +// CHECK-LABEL: func @check_arguments(%arg0: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">, %arg1: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">, %arg2: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) func @check_arguments(%static: memref<10x20xf32>, %dynamic : memref, %mixed : memref<10x?xf32>) { return } // CHECK-LABEL: func @check_strided_memref_arguments( -// CHECK-COUNT-3: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-COUNT-3: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> func @check_strided_memref_arguments(%static: memref<10x20xf32, (i,j)->(20 * i + j + 1)>, %dynamic : memref(M * i + j + 1)>, %mixed : memref<10x?xf32, (i,j)[M]->(M * i + j + 1)>) { return } -// CHECK-LABEL: func @check_static_return(%arg0: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) -> !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> { +// CHECK-LABEL: func @check_static_return(%arg0: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) -> !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> { func @check_static_return(%static : memref<32x18xf32>) -> memref<32x18xf32> { -// CHECK: llvm.return %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.return %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> return %static : memref<32x18xf32> } -// CHECK-LABEL: func @zero_d_alloc() -> !llvm<"{ float*, i64 }"> { +// CHECK-LABEL: func @zero_d_alloc() -> !llvm<"{ float*, float*, i64 }"> { func @zero_d_alloc() -> memref { // CHECK-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm<"float*"> @@ -29,26 +29,55 @@ func @zero_d_alloc() -> memref { // CHECK-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64 // CHECK-NEXT: llvm.call @malloc(%{{.*}}) : (!llvm.i64) -> !llvm<"i8*"> // CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> -// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, i64 }"> -// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0 : index] : !llvm<"{ float*, i64 }"> +// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, float*, i64 }"> +// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm<"{ float*, float*, i64 }"> +// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[1] : !llvm<"{ float*, float*, i64 }"> // CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[1 : index] : !llvm<"{ float*, i64 }"> +// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm<"{ float*, float*, i64 }"> %0 = alloc() : memref return %0 : memref } -// CHECK-LABEL: func @zero_d_dealloc(%{{.*}}: !llvm<"{ float*, i64 }*">) { +// CHECK-LABEL: func @zero_d_dealloc(%{{.*}}: !llvm<"{ float*, float*, i64 }*">) { func @zero_d_dealloc(%arg0: memref) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64 }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64 }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64 }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0] : !llvm<"{ float*, float*, i64 }"> // CHECK-NEXT: %[[bc:.*]] = llvm.bitcast %[[ptr]] : !llvm<"float*"> to !llvm<"i8*"> // CHECK-NEXT: llvm.call @free(%[[bc]]) : (!llvm<"i8*">) -> () dealloc %arg0 : memref return } +// CHECK-LABEL: func @aligned_1d_alloc( +func @aligned_1d_alloc() -> memref<42xf32> { +// CHECK-NEXT: llvm.mlir.constant(42 : index) : !llvm.i64 +// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm<"float*"> +// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 +// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*"> +// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm<"float*"> to !llvm.i64 +// CHECK-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64 +// CHECK-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64 +// CHECK-NEXT: %[[alignmentMinus1:.*]] = llvm.add {{.*}}, %[[alignment]] : !llvm.i64 +// CHECK-NEXT: %[[allocsize:.*]] = llvm.sub %[[alignmentMinus1]], %[[one]] : !llvm.i64 +// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm<"i8*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> +// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[allocated]] : !llvm<"i8*"> to !llvm.i64 +// CHECK-NEXT: %[[alignAdj1:.*]] = llvm.urem %[[allocatedAsInt]], %[[alignment]] : !llvm.i64 +// CHECK-NEXT: %[[alignAdj2:.*]] = llvm.sub %[[alignment]], %[[alignAdj1]] : !llvm.i64 +// CHECK-NEXT: %[[alignAdj3:.*]] = llvm.urem %[[alignAdj2]], %[[alignment]] : !llvm.i64 +// CHECK-NEXT: %[[aligned:.*]] = llvm.getelementptr %9[%[[alignAdj3]]] : (!llvm<"i8*">, !llvm.i64) -> !llvm<"i8*"> +// CHECK-NEXT: %[[alignedBitCast:.*]] = llvm.bitcast %[[aligned]] : !llvm<"i8*"> to !llvm<"float*"> +// CHECK-NEXT: llvm.insertvalue %[[alignedBitCast]], %{{.*}}[1] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 +// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> + %0 = alloc() {alignment = 8} : memref<42xf32> + return %0 : memref<42xf32> +} + // CHECK-LABEL: func @mixed_alloc( -// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> { +// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> { func @mixed_alloc(%arg0: index, %arg1: index) -> memref { // CHECK-NEXT: %[[c42:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 // CHECK-NEXT: llvm.mul %[[M]], %[[c42]] : !llvm.i64 @@ -60,28 +89,29 @@ func @mixed_alloc(%arg0: index, %arg1: index) -> memref { // CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[sz]], %[[sizeof]] : !llvm.i64 // CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm<"i8*"> // CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> -// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0 : index] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[1 : index] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> // CHECK-NEXT: %[[st2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK-NEXT: %[[st1:.*]] = llvm.mul %{{.*}}, %[[c42]] : !llvm.i64 // CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[M]] : !llvm.i64 -// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[3, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[c42]], %{{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[3, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[st2]], %{{.*}}[3, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[c42]], %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[st2]], %{{.*}}[4, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> %0 = alloc(%arg0, %arg1) : memref -// CHECK-NEXT: llvm.return %{{.*}} : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: llvm.return %{{.*}} : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> return %0 : memref } -// CHECK-LABEL: func @mixed_dealloc(%arg0: !llvm<"{ float*, i64, [3 x i64], [3 x i64] }*">) { +// CHECK-LABEL: func @mixed_dealloc(%arg0: !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }*">) { func @mixed_dealloc(%arg0: memref) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> // CHECK-NEXT: %[[ptri8:.*]] = llvm.bitcast %[[ptr]] : !llvm<"float*"> to !llvm<"i8*"> // CHECK-NEXT: llvm.call @free(%[[ptri8]]) : (!llvm<"i8*">) -> () dealloc %arg0 : memref @@ -90,7 +120,7 @@ func @mixed_dealloc(%arg0: memref) { } // CHECK-LABEL: func @dynamic_alloc( -// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> { +// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> { func @dynamic_alloc(%arg0: index, %arg1: index) -> memref { // CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[M]], %[[N]] : !llvm.i64 // CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm<"float*"> @@ -100,32 +130,33 @@ func @dynamic_alloc(%arg0: index, %arg1: index) -> memref { // CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[sz]], %[[sizeof]] : !llvm.i64 // CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm<"i8*"> // CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> -// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[1 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 // CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[M]] : !llvm.i64 -// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = alloc(%arg0, %arg1) : memref -// CHECK-NEXT: llvm.return %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: llvm.return %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> return %0 : memref } -// CHECK-LABEL: func @dynamic_dealloc(%arg0: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) { +// CHECK-LABEL: func @dynamic_dealloc(%arg0: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) { func @dynamic_dealloc(%arg0: memref) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[ptri8:.*]] = llvm.bitcast %[[ptr]] : !llvm<"float*"> to !llvm<"i8*"> // CHECK-NEXT: llvm.call @free(%[[ptri8]]) : (!llvm<"i8*">) -> () dealloc %arg0 : memref return } -// CHECK-LABEL: func @static_alloc() -> !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> { +// CHECK-LABEL: func @static_alloc() -> !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> { func @static_alloc() -> memref<32x18xf32> { // CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64 // CHECK-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64 @@ -141,20 +172,20 @@ func @static_alloc() -> memref<32x18xf32> { return %0 : memref<32x18xf32> } -// CHECK-LABEL: func @static_dealloc(%{{.*}}: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">) { +// CHECK-LABEL: func @static_dealloc(%{{.*}}: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">) { func @static_dealloc(%static: memref<10x8xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[bc:.*]] = llvm.bitcast %[[ptr]] : !llvm<"float*"> to !llvm<"i8*"> // CHECK-NEXT: llvm.call @free(%[[bc]]) : (!llvm<"i8*">) -> () dealloc %static : memref<10x8xf32> return } -// CHECK-LABEL: func @zero_d_load(%{{.*}}: !llvm<"{ float*, i64 }*">) -> !llvm.float { +// CHECK-LABEL: func @zero_d_load(%{{.*}}: !llvm<"{ float*, float*, i64 }*">) -> !llvm.float { func @zero_d_load(%arg0: memref) -> f32 { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64 }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64 }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64 }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64 }"> // CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[c0]]] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*"> // CHECK-NEXT: %{{.*}} = llvm.load %[[addr]] : !llvm<"float*"> @@ -163,10 +194,10 @@ func @zero_d_load(%arg0: memref) -> f32 { } // CHECK-LABEL: func @static_load( -// CHECK: %[[A:.*]]: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64 +// CHECK: %[[A:.*]]: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64 func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: %[[st0:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 // CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 @@ -181,12 +212,12 @@ func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) { } // CHECK-LABEL: func @mixed_load( -// CHECK: %[[A:.*]]: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64 +// CHECK: %[[A:.*]]: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64 func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][3 : index, 0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 // CHECK-NEXT: %[[off0:.*]] = llvm.add %[[off]], %[[offI]] : !llvm.i64 // CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 @@ -199,12 +230,12 @@ func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) { } // CHECK-LABEL: func @dynamic_load( -// CHECK: %[[A:.*]]: !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*">, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64 +// CHECK: %[[A:.*]]: !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*">, %[[I:.*]]: !llvm.i64, %[[J:.*]]: !llvm.i64 func @dynamic_load(%dynamic : memref, %i : index, %j : index) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][3 : index, 0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 // CHECK-NEXT: %[[off0:.*]] = llvm.add %[[off]], %[[offI]] : !llvm.i64 // CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 @@ -216,10 +247,10 @@ func @dynamic_load(%dynamic : memref, %i : index, %j : index) { return } -// CHECK-LABEL: func @zero_d_store(%arg0: !llvm<"{ float*, i64 }*">, %arg1: !llvm.float) { +// CHECK-LABEL: func @zero_d_store(%arg0: !llvm<"{ float*, float*, i64 }*">, %arg1: !llvm.float) { func @zero_d_store(%arg0: memref, %arg1: f32) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64 }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64 }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64 }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64 }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off]]] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*"> // CHECK-NEXT: llvm.store %arg1, %[[addr]] : !llvm<"float*"> @@ -229,8 +260,8 @@ func @zero_d_store(%arg0: memref, %arg1: f32) { // CHECK-LABEL: func @static_store func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f32) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 // CHECK-NEXT: %[[st0:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64 // CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 @@ -246,10 +277,10 @@ func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f // CHECK-LABEL: func @dynamic_store func @dynamic_store(%dynamic : memref, %i : index, %j : index, %val : f32) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][3 : index, 0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 // CHECK-NEXT: %[[off0:.*]] = llvm.add %[[off]], %[[offI]] : !llvm.i64 // CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 @@ -263,10 +294,10 @@ func @dynamic_store(%dynamic : memref, %i : index, %j : index, %val : f // CHECK-LABEL: func @mixed_store func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: %[[ptr:.*]] = llvm.extractvalue %[[ld]][1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 -// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][3 : index, 0 : index] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[st0:.*]] = llvm.extractvalue %[[ld]][4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: %[[offI:.*]] = llvm.mul %[[I]], %[[st0]] : !llvm.i64 // CHECK-NEXT: %[[off0:.*]] = llvm.add %[[off]], %[[offI]] : !llvm.i64 // CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 @@ -280,79 +311,79 @@ func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32) // CHECK-LABEL: func @memref_cast_static_to_dynamic func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %static : memref<10x42xf32> to memref return } // CHECK-LABEL: func @memref_cast_static_to_mixed func @memref_cast_static_to_mixed(%static : memref<10x42xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %static : memref<10x42xf32> to memref return } // CHECK-LABEL: func @memref_cast_dynamic_to_static func @memref_cast_dynamic_to_static(%dynamic : memref) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %dynamic : memref to memref<10x12xf32> return } // CHECK-LABEL: func @memref_cast_dynamic_to_mixed func @memref_cast_dynamic_to_mixed(%dynamic : memref) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %dynamic : memref to memref return } // CHECK-LABEL: func @memref_cast_mixed_to_dynamic func @memref_cast_mixed_to_dynamic(%mixed : memref<42x?xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %mixed : memref<42x?xf32> to memref return } // CHECK-LABEL: func @memref_cast_mixed_to_static func @memref_cast_mixed_to_static(%mixed : memref<42x?xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %mixed : memref<42x?xf32> to memref<42x1xf32> return } // CHECK-LABEL: func @memref_cast_mixed_to_mixed func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }*"> -// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }*"> +// CHECK-NEXT: llvm.bitcast %[[ld]] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> to !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %0 = memref_cast %mixed : memref<42x?xf32> to memref return } -// CHECK-LABEL: func @mixed_memref_dim(%arg0: !llvm<"{ float*, i64, [5 x i64], [5 x i64] }*">) { +// CHECK-LABEL: func @mixed_memref_dim(%arg0: !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }*">) { func @mixed_memref_dim(%mixed : memref<42x?x?x13x?xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [5 x i64], [5 x i64] }*"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }*"> // CHECK-NEXT: llvm.mlir.constant(42 : index) : !llvm.i64 %0 = dim %mixed, 0 : memref<42x?x?x13x?xf32> -// CHECK-NEXT: llvm.extractvalue %[[ld]][2, 1] : !llvm<"{ float*, i64, [5 x i64], [5 x i64] }"> +// CHECK-NEXT: llvm.extractvalue %[[ld]][3, 1] : !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }"> %1 = dim %mixed, 1 : memref<42x?x?x13x?xf32> -// CHECK-NEXT: llvm.extractvalue %[[ld]][2, 2] : !llvm<"{ float*, i64, [5 x i64], [5 x i64] }"> +// CHECK-NEXT: llvm.extractvalue %[[ld]][3, 2] : !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }"> %2 = dim %mixed, 2 : memref<42x?x?x13x?xf32> // CHECK-NEXT: llvm.mlir.constant(13 : index) : !llvm.i64 %3 = dim %mixed, 3 : memref<42x?x?x13x?xf32> -// CHECK-NEXT: llvm.extractvalue %[[ld]][2, 4] : !llvm<"{ float*, i64, [5 x i64], [5 x i64] }"> +// CHECK-NEXT: llvm.extractvalue %[[ld]][3, 4] : !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }"> %4 = dim %mixed, 4 : memref<42x?x?x13x?xf32> return } -// CHECK-LABEL: func @static_memref_dim(%arg0: !llvm<"{ float*, i64, [5 x i64], [5 x i64] }*">) { +// CHECK-LABEL: func @static_memref_dim(%arg0: !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }*">) { func @static_memref_dim(%static : memref<42x32x15x13x27xf32>) { -// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, i64, [5 x i64], [5 x i64] }*"> +// CHECK-NEXT: %[[ld:.*]] = llvm.load %{{.*}} : !llvm<"{ float*, float*, i64, [5 x i64], [5 x i64] }*"> // CHECK-NEXT: llvm.mlir.constant(42 : index) : !llvm.i64 %0 = dim %static, 0 : memref<42x32x15x13x27xf32> // CHECK-NEXT: llvm.mlir.constant(32 : index) : !llvm.i64 diff --git a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir index a0daac0..e0669dc2 100644 --- a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir @@ -325,23 +325,23 @@ func @more_imperfectly_nested_loops() { func @get_i64() -> (i64) // CHECK-LABEL: func @get_f32() -> !llvm.float func @get_f32() -> (f32) -// CHECK-LABEL: func @get_memref() -> !llvm<"{ float*, i64, [4 x i64], [4 x i64] }"> +// CHECK-LABEL: func @get_memref() -> !llvm<"{ float*, float*, i64, [4 x i64], [4 x i64] }"> func @get_memref() -> (memref<42x?x10x?xf32>) -// CHECK-LABEL: func @multireturn() -> !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> { +// CHECK-LABEL: func @multireturn() -> !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> { func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) { ^bb0: // CHECK-NEXT: {{.*}} = llvm.call @get_i64() : () -> !llvm.i64 // CHECK-NEXT: {{.*}} = llvm.call @get_f32() : () -> !llvm.float -// CHECK-NEXT: {{.*}} = llvm.call @get_memref() : () -> !llvm<"{ float*, i64, [4 x i64], [4 x i64] }"> +// CHECK-NEXT: {{.*}} = llvm.call @get_memref() : () -> !llvm<"{ float*, float*, i64, [4 x i64], [4 x i64] }"> %0 = call @get_i64() : () -> (i64) %1 = call @get_f32() : () -> (f32) %2 = call @get_memref() : () -> (memref<42x?x10x?xf32>) -// CHECK-NEXT: {{.*}} = llvm.mlir.undef : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0 : index] : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1 : index] : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2 : index] : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: llvm.return {{.*}} : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.mlir.undef : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0] : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1] : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: llvm.return {{.*}} : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> return %0, %1, %2 : i64, f32, memref<42x?x10x?xf32> } @@ -349,10 +349,10 @@ func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) { // CHECK-LABEL: func @multireturn_caller() { func @multireturn_caller() { ^bb0: -// CHECK-NEXT: {{.*}} = llvm.call @multireturn() : () -> !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0 : index] : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[1 : index] : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> -// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2 : index] : !llvm<"{ i64, float, { float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.call @multireturn() : () -> !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> +// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm<"{ i64, float, { float*, float*, i64, [4 x i64], [4 x i64] } }"> %0:3 = call @multireturn() : () -> (i64, f32, memref<42x?x10x?xf32>) %1 = constant 42 : i64 // CHECK: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 @@ -570,18 +570,18 @@ func @vec_bin(%arg0: vector<2x2x2xf32>) -> vector<2x2x2xf32> { // CHECK-NEXT: llvm.mlir.undef : !llvm<"[2 x [2 x <2 x float>]]"> // This block appears 2x2 times -// CHECK-NEXT: llvm.extractvalue %{{.*}}[0 : index, 0 : index] : !llvm<"[2 x [2 x <2 x float>]]"> -// CHECK-NEXT: llvm.extractvalue %{{.*}}[0 : index, 0 : index] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK-NEXT: llvm.extractvalue %{{.*}}[0, 0] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK-NEXT: llvm.extractvalue %{{.*}}[0, 0] : !llvm<"[2 x [2 x <2 x float>]]"> // CHECK-NEXT: llvm.fadd %{{.*}} : !llvm<"<2 x float>"> -// CHECK-NEXT: llvm.insertvalue %{{.*}}[0 : index, 0 : index] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}[0, 0] : !llvm<"[2 x [2 x <2 x float>]]"> // We check the proper indexing of extract/insert in the remaining 3 positions. -// CHECK: llvm.extractvalue %{{.*}}[0 : index, 1 : index] : !llvm<"[2 x [2 x <2 x float>]]"> -// CHECK: llvm.insertvalue %{{.*}}[0 : index, 1 : index] : !llvm<"[2 x [2 x <2 x float>]]"> -// CHECK: llvm.extractvalue %{{.*}}[1 : index, 0 : index] : !llvm<"[2 x [2 x <2 x float>]]"> -// CHECK: llvm.insertvalue %{{.*}}[1 : index, 0 : index] : !llvm<"[2 x [2 x <2 x float>]]"> -// CHECK: llvm.extractvalue %{{.*}}[1 : index, 1 : index] : !llvm<"[2 x [2 x <2 x float>]]"> -// CHECK: llvm.insertvalue %{{.*}}[1 : index, 1 : index] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK: llvm.extractvalue %{{.*}}[0, 1] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK: llvm.insertvalue %{{.*}}[0, 1] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK: llvm.extractvalue %{{.*}}[1, 0] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK: llvm.insertvalue %{{.*}}[1, 0] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK: llvm.extractvalue %{{.*}}[1, 1] : !llvm<"[2 x [2 x <2 x float>]]"> +// CHECK: llvm.insertvalue %{{.*}}[1, 1] : !llvm<"[2 x [2 x <2 x float>]]"> // And we're done // CHECK-NEXT: return @@ -606,103 +606,103 @@ func @splat(%a: vector<4xf32>, %b: f32) -> vector<4xf32> { // CHECK: %[[ARG0:.*]]: !llvm.i64, %[[ARG1:.*]]: !llvm.i64, %[[ARG2:.*]]: !llvm.i64 func @view(%arg0 : index, %arg1 : index, %arg2 : index) { // CHECK: llvm.mlir.constant(2048 : index) : !llvm.i64 - // CHECK: llvm.mlir.undef : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> %0 = alloc() : memref<2048xi8> // Test two dynamic sizes and dynamic offset. - // CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG2]], %{{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG2]], %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mul %{{.*}}, %[[ARG1]] - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %1 = view %0[%arg0, %arg1][%arg2] : memref<2048xi8> to memref (d0 * s0 + d1 + s1)> // Test two dynamic sizes and static offset. - // CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(0 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %arg0, %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %arg0, %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mul %{{.*}}, %[[ARG1]] - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %2 = view %0[%arg0, %arg1][] : memref<2048xi8> to memref (d0 * s0 + d1)> // Test one dynamic size and dynamic offset. - // CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG2]], %{{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG2]], %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mul %{{.*}}, %[[ARG1]] - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %3 = view %0[%arg1][%arg2] : memref<2048xi8> to memref<4x?xf32, (d0, d1)[s0, s1] -> (d0 * s0 + d1 + s1)> // Test one dynamic size and static offset. - // CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(0 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(16 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %4 = view %0[%arg0][] : memref<2048xi8> to memref (d0 * 4 + d1)> // Test static sizes and static offset. - // CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(0 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(64 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %5 = view %0[][] : memref<2048xi8> to memref<64x4xf32, (d0, d1) -> (d0 * 4 + d1)> // Test dynamic everything. - // CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i8*, i64, [1 x i64], [1 x i64] }"> + // CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i8*, i8*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.bitcast %{{.*}} : !llvm<"i8*"> to !llvm<"float*"> - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG2]], %{{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG2]], %{{.*}}[2] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: %[[STRIDE_1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 - // CHECK: llvm.insertvalue %[[STRIDE_1]], %{{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> - // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[STRIDE_1]], %{{.*}}[4, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK: llvm.mul %[[STRIDE_1]], %[[ARG1]] : !llvm.i64 - // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> + // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> %6 = view %0[%arg0, %arg1][%arg2] : memref<2048xi8> to memref (d0 * s0 + d1 + s1)> diff --git a/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir b/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir index abbda44..999e66c 100644 --- a/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir +++ b/mlir/test/Conversion/StandardToLLVM/standard-to-llvm.mlir @@ -1,8 +1,8 @@ // RUN: mlir-opt %s -lower-to-llvm -split-input-file -verify-diagnostics | FileCheck %s // CHECK-LABEL: func @address_space( -// CHECK: %{{.*}}: !llvm<"{ float addrspace(7)*, i64, [1 x i64], [1 x i64] }*">) -// CHECK: llvm.load %{{.*}} : !llvm<"{ float addrspace(7)*, i64, [1 x i64], [1 x i64] }*"> +// CHECK: %{{.*}}: !llvm<"{ float addrspace(7)*, float addrspace(7)*, i64, [1 x i64], [1 x i64] }*">) +// CHECK: llvm.load %{{.*}} : !llvm<"{ float addrspace(7)*, float addrspace(7)*, i64, [1 x i64], [1 x i64] }*"> func @address_space(%arg0 : memref<32xf32, (d0) -> (d0), 7>) { %0 = alloc() : memref<32xf32, (d0) -> (d0), 5> %1 = constant 7 : index diff --git a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir index aefeca4..d4bbc05 100644 --- a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir +++ b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir @@ -53,14 +53,17 @@ func @vector_type_cast(%arg0: memref<8x8x8xf32>) -> memref<1xvector<8x8x8xf32>> return %0 : memref<1xvector<8x8x8xf32>> } // CHECK-LABEL: vector_type_cast -// CHECK: llvm.mlir.undef : !llvm<"{ [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> -// CHECK: %[[ptr:.*]] = llvm.extractvalue {{.*}}[0 : index] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: %[[bit:.*]] = llvm.bitcast %[[ptr]] : !llvm<"float*"> to !llvm<"[8 x [8 x <8 x float>]]*"> -// CHECK: llvm.insertvalue %[[bit]], {{.*}}[0 : index] : !llvm<"{ [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.mlir.undef : !llvm<"{ [8 x [8 x <8 x float>]]*, [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> +// CHECK: %[[allocated:.*]] = llvm.extractvalue {{.*}}[0 : index] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: %[[allocatedBit:.*]] = llvm.bitcast %[[allocated]] : !llvm<"float*"> to !llvm<"[8 x [8 x <8 x float>]]*"> +// CHECK: llvm.insertvalue %[[allocatedBit]], {{.*}}[0 : index] : !llvm<"{ [8 x [8 x <8 x float>]]*, [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> +// CHECK: %[[aligned:.*]] = llvm.extractvalue {{.*}}[1 : index] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: %[[alignedBit:.*]] = llvm.bitcast %[[aligned]] : !llvm<"float*"> to !llvm<"[8 x [8 x <8 x float>]]*"> +// CHECK: llvm.insertvalue %[[alignedBit]], {{.*}}[1 : index] : !llvm<"{ [8 x [8 x <8 x float>]]*, [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.mlir.constant(0 : index -// CHECK: llvm.insertvalue {{.*}}[1 : index] : !llvm<"{ [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[2 : index] : !llvm<"{ [8 x [8 x <8 x float>]]*, [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.mlir.constant(1 : index -// CHECK: llvm.insertvalue {{.*}}[2, 0] : !llvm<"{ [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 0] : !llvm<"{ [8 x [8 x <8 x float>]]*, [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.mlir.constant(1 : index -// CHECK: llvm.insertvalue {{.*}}[3, 0] : !llvm<"{ [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[4, 0] : !llvm<"{ [8 x [8 x <8 x float>]]*, [8 x [8 x <8 x float>]]*, i64, [1 x i64], [1 x i64] }"> diff --git a/mlir/test/Dialect/Linalg/llvm.mlir b/mlir/test/Dialect/Linalg/llvm.mlir index e714fda..e354893 100644 --- a/mlir/test/Dialect/Linalg/llvm.mlir +++ b/mlir/test/Dialect/Linalg/llvm.mlir @@ -21,20 +21,20 @@ func @slice(%arg0: memref, %arg1: !linalg.range) } // CHECK-LABEL: func @slice // insert data ptr for slice op -// CHECK: llvm.extractvalue %{{.*}}[3, 0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> -// CHECK-NEXT: llvm.extractvalue %{{.*}}[1] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.extractvalue %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: llvm.extractvalue %{{.*}}[2] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> // CHECK-NEXT: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i64, i64, i64 }"> // CHECK-NEXT: llvm.mul %{{.*}}, %{{.*}} : !llvm.i64 // CHECK-NEXT: llvm.add %{{.*}}, %{{.*}} : !llvm.i64 // insert offset -// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> // CHECK-NEXT: llvm.mlir.constant(0 : index) // CHECK-NEXT: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i64, i64, i64 }"> // CHECK-NEXT: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i64, i64, i64 }"> // CHECK-NEXT: llvm.extractvalue %{{.*}}[2] : !llvm<"{ i64, i64, i64 }"> // get size[0] from parent view -// CHECK-NEXT: llvm.extractvalue %{{.*}}[2, 0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: llvm.extractvalue %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> // CHECK-NEXT: llvm.icmp "slt" %{{.*}}, %{{.*}} : !llvm.i64 // CHECK-NEXT: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : !llvm.i1, !llvm.i64 // compute size[0] bounded by parent view's size[0] @@ -45,16 +45,16 @@ func @slice(%arg0: memref, %arg1: !linalg.range) // compute stride[0] using bounded size // CHECK-NEXT: llvm.mul %{{.*}}, %{{.*}} : !llvm.i64 // insert size and stride -// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[2, 0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> -// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> +// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }"> func @dot(%arg0: memref, %arg1: memref, %arg2: memref) { linalg.dot(%arg0, %arg1, %arg2) : memref, memref, memref return } -// CHECK-LABEL: func @dot(%{{.*}}: !llvm<"{ float*, i64, [1 x i64], [1 x i64] }*">, %{{.*}}: !llvm<"{ float*, i64, [1 x i64], [1 x i64] }*">, %{{.*}}: !llvm<"{ float*, i64 }*">) { +// CHECK-LABEL: func @dot(%{{.*}}: !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }*">, %{{.*}}: !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }*">, %{{.*}}: !llvm<"{ float*, float*, i64 }*">) { // CHECK-COUNT-3: llvm.mlir.constant(1 : index){{.*[[:space:]].*}}llvm.alloca{{.*[[:space:]].*}}llvm.store -// CHECK-NEXT: llvm.call @linalg_dot_viewsxf32_viewsxf32_viewf32(%{{.*}}, %{{.*}}, %{{.*}}) : (!llvm<"{ float*, i64, [1 x i64], [1 x i64] }*">, !llvm<"{ float*, i64, [1 x i64], [1 x i64] }*">, !llvm<"{ float*, i64 }*">) -> () +// CHECK-NEXT: llvm.call @linalg_dot_viewsxf32_viewsxf32_viewf32(%{{.*}}, %{{.*}}, %{{.*}}) : (!llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }*">, !llvm<"{ float*, float*, i64, [1 x i64], [1 x i64] }*">, !llvm<"{ float*, float*, i64 }*">) -> () func @subview(%arg0: memref) { %c0 = constant 0 : index @@ -66,10 +66,10 @@ func @subview(%arg0: memref) { // Subview lowers to range + slice op // CHECK: llvm.mlir.undef : !llvm<"{ i64, i64, i64 }"> // CHECK: llvm.mlir.undef : !llvm<"{ i64, i64, i64 }"> -// CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // // Select occurs in slice op lowering -// CHECK: llvm.extractvalue %{{.*}}[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.extractvalue %{{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: llvm.icmp "slt" %{{.*}}, %{{.*}} : !llvm.i64 // CHECK-NEXT: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : !llvm.i1, !llvm.i64 // CHECK-NEXT: llvm.sub %{{.*}}, %{{.*}} : !llvm.i64 @@ -77,7 +77,7 @@ func @subview(%arg0: memref) { // CHECK-NEXT: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : !llvm.i1, !llvm.i64 // CHECK-NEXT: llvm.mul %{{.*}}, %{{.*}} : !llvm.i64 // -// CHECK: llvm.extractvalue %{{.*}}[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.extractvalue %{{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [2 x i64], [2 x i64] }"> // CHECK-NEXT: llvm.icmp "slt" %{{.*}}, %{{.*}} : !llvm.i64 // CHECK-NEXT: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : !llvm.i1, !llvm.i64 // CHECK-NEXT: llvm.sub %{{.*}}, %{{.*}} : !llvm.i64 @@ -96,38 +96,39 @@ func @view_with_range_and_index(%arg0: memref -// CHECK: llvm.extractvalue %{{.*}}[3, 0] : !llvm<"{ double*, i64, [2 x i64], [2 x i64] }"> -// CHECK: llvm.extractvalue %{{.*}}[3, 1] : !llvm<"{ double*, i64, [2 x i64], [2 x i64] }"> -// CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ double*, i64, [2 x i64], [2 x i64] }"> -// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ double*, i64, [1 x i64], [1 x i64] }"> -// CHECK: llvm.insertvalue %{{.*}}[1] : !llvm<"{ double*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.mlir.undef : !llvm<"{ double*, double*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.extractvalue %{{.*}}[4, 0] : !llvm<"{ double*, double*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.extractvalue %{{.*}}[4, 1] : !llvm<"{ double*, double*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.extractvalue %{{.*}}[2] : !llvm<"{ double*, double*, i64, [2 x i64], [2 x i64] }"> +// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm<"{ double*, double*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue %{{.*}}[2] : !llvm<"{ double*, double*, i64, [1 x i64], [1 x i64] }"> // CHECK: llvm.extractvalue %{{.*}}[0] : !llvm<"{ i64, i64, i64 }"> // CHECK: llvm.extractvalue %{{.*}}[1] : !llvm<"{ i64, i64, i64 }"> -// CHECK: llvm.insertvalue %{{.*}}[2, 0] : !llvm<"{ double*, i64, [1 x i64], [1 x i64] }"> -// CHECK: llvm.insertvalue %{{.*}}[3, 0] : !llvm<"{ double*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue %{{.*}}[3, 0] : !llvm<"{ double*, double*, i64, [1 x i64], [1 x i64] }"> +// CHECK: llvm.insertvalue %{{.*}}[4, 0] : !llvm<"{ double*, double*, i64, [1 x i64], [1 x i64] }"> func @copy(%arg0: memref, %arg1: memref) { linalg.copy(%arg0, %arg1) : memref, memref return } // CHECK-LABEL: func @copy -// CHECK: llvm.call @linalg_copy_viewsxsxsxf32_viewsxsxsxf32(%{{.*}}, %{{.*}}) : (!llvm<"{ float*, i64, [3 x i64], [3 x i64] }*">, !llvm<"{ float*, i64, [3 x i64], [3 x i64] }*">) -> () +// CHECK: llvm.call @linalg_copy_viewsxsxsxf32_viewsxsxsxf32(%{{.*}}, %{{.*}}) : (!llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }*">, !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }*">) -> () func @transpose(%arg0: memref) { %0 = linalg.transpose %arg0 (i, j, k) -> (k, i, j) : memref return } // CHECK-LABEL: func @transpose -// CHECK: llvm.mlir.undef : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.mlir.undef : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> func @copy_transpose(%arg0: memref, %arg1: memref) { linalg.copy(%arg0, %arg1) {inputPermutation = (i, j, k) -> (i, k, j), @@ -137,26 +138,28 @@ func @copy_transpose(%arg0: memref, %a } // CHECK-LABEL: func @copy // Tranpose input -// CHECK: llvm.insertvalue {{.*}}[0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> // Transpose output -// CHECK: llvm.insertvalue {{.*}}[0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 1] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.extractvalue {{.*}}[2, 2] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> -// CHECK: llvm.insertvalue {{.*}}[2, 0] : !llvm<"{ float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 1] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.extractvalue {{.*}}[3, 2] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> +// CHECK: llvm.insertvalue {{.*}}[3, 0] : !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> // Call external copy after promoting input and output structs to pointers // CHECK-COUNT-2: llvm.mlir.constant(1 : index){{.*[[:space:]].*}}llvm.alloca{{.*[[:space:]].*}}llvm.store -// CHECK: llvm.call @linalg_copy_viewsxsxsxf32_viewsxsxsxf32(%{{.*}}, %{{.*}}) : (!llvm<"{ float*, i64, [3 x i64], [3 x i64] }*">, !llvm<"{ float*, i64, [3 x i64], [3 x i64] }*">) -> () +// CHECK: llvm.call @linalg_copy_viewsxsxsxf32_viewsxsxsxf32(%{{.*}}, %{{.*}}) : (!llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }*">, !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }*">) -> () #matmul_accesses = [ (m, n, k) -> (m, k), @@ -188,7 +191,7 @@ func @matmul_vec_impl(%A: !matrix_type_A, %B: !matrix_type_B, %C: !matrix_type_C return } // CHECK-LABEL: func @matmul_vec_impl( -// CHECK: llvm.call @some_external_function_name_for_vector_outerproduct_matmul(%{{.*}}) : (!llvm<"{ <4 x float>*, i64, [2 x i64], [2 x i64] }*">, !llvm<"{ <4 x float>*, i64, [2 x i64], [2 x i64] }*">, !llvm<"{ [4 x <4 x float>]*, i64, [2 x i64], [2 x i64] }*">) -> () +// CHECK: llvm.call @some_external_function_name_for_vector_outerproduct_matmul(%{{.*}}) : (!llvm<"{ <4 x float>*, <4 x float>*, i64, [2 x i64], [2 x i64] }*">, !llvm<"{ <4 x float>*, <4 x float>*, i64, [2 x i64], [2 x i64] }*">, !llvm<"{ [4 x <4 x float>]*, [4 x <4 x float>]*, i64, [2 x i64], [2 x i64] }*">) -> () // LLVM-LOOPS-LABEL: func @matmul_vec_impl( // LLVM-LOOPS: llvm.shufflevector {{.*}} [0 : i32, 0 : i32, 0 : i32, 0 : i32] : !llvm<"<4 x float>">, !llvm<"<4 x float>"> diff --git a/mlir/test/mlir-cpu-runner/include/mlir_runner_utils.h b/mlir/test/mlir-cpu-runner/include/mlir_runner_utils.h index 3265c0f..262b12c 100644 --- a/mlir/test/mlir-cpu-runner/include/mlir_runner_utils.h +++ b/mlir/test/mlir-cpu-runner/include/mlir_runner_utils.h @@ -35,6 +35,7 @@ /// StridedMemRef descriptor type with static rank. template struct StridedMemRefType { + T *basePtr; T *data; int64_t offset; int64_t sizes[N]; @@ -43,6 +44,7 @@ template struct StridedMemRefType { /// StridedMemRef descriptor type specialized for rank 0. template struct StridedMemRefType { + T *basePtr; T *data; int64_t offset; }; diff --git a/mlir/tools/mlir-cuda-runner/cuda-runtime-wrappers.cpp b/mlir/tools/mlir-cuda-runner/cuda-runtime-wrappers.cpp index 9e035f8..31b6f6f 100644 --- a/mlir/tools/mlir-cuda-runner/cuda-runtime-wrappers.cpp +++ b/mlir/tools/mlir-cuda-runner/cuda-runtime-wrappers.cpp @@ -82,6 +82,7 @@ extern "C" int32_t mcuStreamSynchronize(void *stream) { // A struct that corresponds to how MLIR represents memrefs. template struct MemRefType { + T *basePtr; T *data; int64_t offset; int64_t sizes[N];