forked from OSchip/llvm-project
[mlir] Simplify std.alloc lowering to LLVM.
std.alloc only supports memrefs with identity layout, which means we can simplify the lowering to LLVM and compute strides only from (static and dynamic) sizes. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D91549
This commit is contained in:
parent
6ef6beaa57
commit
bedaad4495
|
@ -520,11 +520,27 @@ protected:
|
|||
/// Returns the type of a pointer to an element of the memref.
|
||||
Type getElementPtrType(MemRefType type) const;
|
||||
|
||||
/// Determines sizes to be used in the memref descriptor.
|
||||
/// Computes sizes, strides and buffer size in bytes of `memRefType` with
|
||||
/// identity layout. Emits constant ops for the static sizes of `memRefType`,
|
||||
/// and uses `dynamicSizes` for the others. Emits instructions to compute
|
||||
/// strides and buffer size from these sizes.
|
||||
///
|
||||
/// For example, memref<4x?xf32> emits:
|
||||
/// `sizes[0]` = llvm.mlir.constant(4 : index) : !llvm.i64
|
||||
/// `sizes[1]` = `dynamicSizes[0]`
|
||||
/// `strides[1]` = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
/// `strides[0]` = `sizes[0]`
|
||||
/// %size = llvm.mul `sizes[0]`, `sizes[1]` : !llvm.i64
|
||||
/// %nullptr = llvm.mlir.null : !llvm.ptr<float>
|
||||
/// %gep = llvm.getelementptr %nullptr[%size]
|
||||
/// : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
/// `sizeBytes` = llvm.ptrtoint %gep : !llvm.ptr<float> to !llvm.i64
|
||||
void getMemRefDescriptorSizes(Location loc, MemRefType memRefType,
|
||||
ArrayRef<Value> dynSizes,
|
||||
ArrayRef<Value> dynamicSizes,
|
||||
ConversionPatternRewriter &rewriter,
|
||||
SmallVectorImpl<Value> &sizes) const;
|
||||
SmallVectorImpl<Value> &sizes,
|
||||
SmallVectorImpl<Value> &strides,
|
||||
Value &sizeBytes) const;
|
||||
|
||||
/// Computes the size of type in bytes.
|
||||
Value getSizeInBytes(Location loc, Type type,
|
||||
|
@ -534,18 +550,11 @@ protected:
|
|||
Value getNumElements(Location loc, ArrayRef<Value> shape,
|
||||
ConversionPatternRewriter &rewriter) const;
|
||||
|
||||
/// Computes total size in bytes of to store the given shape.
|
||||
Value getCumulativeSizeInBytes(Location loc, Type elementType,
|
||||
ArrayRef<Value> shape,
|
||||
ConversionPatternRewriter &rewriter) const;
|
||||
|
||||
/// Creates and populates the memref descriptor struct given all its fields.
|
||||
/// 'strides' can be either dynamic (kDynamicStrideOrOffset) or static, but
|
||||
/// not a mix of the two.
|
||||
/// Creates and populates a canonical memref descriptor struct.
|
||||
MemRefDescriptor
|
||||
createMemRefDescriptor(Location loc, MemRefType memRefType,
|
||||
Value allocatedPtr, Value alignedPtr, uint64_t offset,
|
||||
ArrayRef<int64_t> strides, ArrayRef<Value> sizes,
|
||||
Value allocatedPtr, Value alignedPtr,
|
||||
ArrayRef<Value> sizes, ArrayRef<Value> strides,
|
||||
ConversionPatternRewriter &rewriter) const;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -211,10 +211,10 @@ class GPULaunchLowering : public ConvertOpToLLVMPattern<gpu::LaunchFuncOp> {
|
|||
// Calculate the size of the memref and get the pointer to the allocated
|
||||
// buffer.
|
||||
SmallVector<Value, 4> sizes;
|
||||
SmallVector<Value, 4> strides;
|
||||
Value sizeBytes;
|
||||
getMemRefDescriptorSizes(loc, memRefType, operand.value(), rewriter,
|
||||
sizes);
|
||||
Value size = getCumulativeSizeInBytes(loc, memRefType.getElementType(),
|
||||
sizes, rewriter);
|
||||
sizes, strides, sizeBytes);
|
||||
MemRefDescriptor descriptor(operand.value());
|
||||
Value src = descriptor.allocatedPtr(rewriter, loc);
|
||||
|
||||
|
@ -244,12 +244,12 @@ class GPULaunchLowering : public ConvertOpToLLVMPattern<gpu::LaunchFuncOp> {
|
|||
// src, dst and size so that we can copy data back after emulating the
|
||||
// kernel call.
|
||||
Value dst = rewriter.create<LLVM::AddressOfOp>(loc, dstGlobal);
|
||||
copy(loc, dst, src, size, rewriter);
|
||||
copy(loc, dst, src, sizeBytes, rewriter);
|
||||
|
||||
CopyInfo info;
|
||||
info.dst = dst;
|
||||
info.src = src;
|
||||
info.size = size;
|
||||
info.size = sizeBytes;
|
||||
copyInfo.push_back(info);
|
||||
}
|
||||
// Create a call to the kernel and copy the data back.
|
||||
|
|
|
@ -1094,14 +1094,51 @@ Type ConvertToLLVMPattern::getElementPtrType(MemRefType type) const {
|
|||
}
|
||||
|
||||
void ConvertToLLVMPattern::getMemRefDescriptorSizes(
|
||||
Location loc, MemRefType memRefType, ArrayRef<Value> dynSizes,
|
||||
ConversionPatternRewriter &rewriter, SmallVectorImpl<Value> &sizes) const {
|
||||
Location loc, MemRefType memRefType, ArrayRef<Value> dynamicSizes,
|
||||
ConversionPatternRewriter &rewriter, SmallVectorImpl<Value> &sizes,
|
||||
SmallVectorImpl<Value> &strides, Value &sizeBytes) const {
|
||||
assert(isSupportedMemRefType(memRefType) &&
|
||||
"layout maps must have been normalized away");
|
||||
|
||||
sizes.reserve(memRefType.getRank());
|
||||
unsigned i = 0;
|
||||
for (int64_t s : memRefType.getShape())
|
||||
sizes.push_back(s == ShapedType::kDynamicSize
|
||||
? dynSizes[i++]
|
||||
: createIndexConstant(rewriter, loc, s));
|
||||
unsigned dynamicIndex = 0;
|
||||
for (int64_t size : memRefType.getShape()) {
|
||||
sizes.push_back(size == ShapedType::kDynamicSize
|
||||
? dynamicSizes[dynamicIndex++]
|
||||
: createIndexConstant(rewriter, loc, size));
|
||||
}
|
||||
|
||||
// Strides: iterate sizes in reverse order and multiply.
|
||||
int64_t stride = 1;
|
||||
Value runningStride = createIndexConstant(rewriter, loc, 1);
|
||||
strides.resize(memRefType.getRank());
|
||||
for (auto i = memRefType.getRank(); i-- > 0;) {
|
||||
strides[i] = runningStride;
|
||||
|
||||
int64_t size = memRefType.getShape()[i];
|
||||
if (size == 0)
|
||||
continue;
|
||||
bool useSizeAsStride = stride == 1;
|
||||
if (size == ShapedType::kDynamicSize)
|
||||
stride = ShapedType::kDynamicSize;
|
||||
if (stride != ShapedType::kDynamicSize)
|
||||
stride *= size;
|
||||
|
||||
if (useSizeAsStride)
|
||||
runningStride = sizes[i];
|
||||
else if (stride == ShapedType::kDynamicSize)
|
||||
runningStride =
|
||||
rewriter.create<LLVM::MulOp>(loc, runningStride, sizes[i]);
|
||||
else
|
||||
runningStride = createIndexConstant(rewriter, loc, stride);
|
||||
}
|
||||
|
||||
// Buffer size in bytes.
|
||||
Type elementPtrType = getElementPtrType(memRefType);
|
||||
Value nullPtr = rewriter.create<LLVM::NullOp>(loc, elementPtrType);
|
||||
Value gepPtr = rewriter.create<LLVM::GEPOp>(
|
||||
loc, elementPtrType, ArrayRef<Value>{nullPtr, runningStride});
|
||||
sizeBytes = rewriter.create<LLVM::PtrToIntOp>(loc, getIndexType(), gepPtr);
|
||||
}
|
||||
|
||||
Value ConvertToLLVMPattern::getSizeInBytes(
|
||||
|
@ -1131,18 +1168,10 @@ Value ConvertToLLVMPattern::getNumElements(
|
|||
return numElements;
|
||||
}
|
||||
|
||||
Value ConvertToLLVMPattern::getCumulativeSizeInBytes(
|
||||
Location loc, Type elementType, ArrayRef<Value> shape,
|
||||
ConversionPatternRewriter &rewriter) const {
|
||||
Value numElements = this->getNumElements(loc, shape, rewriter);
|
||||
Value elementSize = this->getSizeInBytes(loc, elementType, rewriter);
|
||||
return rewriter.create<LLVM::MulOp>(loc, numElements, elementSize);
|
||||
}
|
||||
|
||||
/// Creates and populates the memref descriptor struct given all its fields.
|
||||
MemRefDescriptor ConvertToLLVMPattern::createMemRefDescriptor(
|
||||
Location loc, MemRefType memRefType, Value allocatedPtr, Value alignedPtr,
|
||||
uint64_t offset, ArrayRef<int64_t> strides, ArrayRef<Value> sizes,
|
||||
ArrayRef<Value> sizes, ArrayRef<Value> strides,
|
||||
ConversionPatternRewriter &rewriter) const {
|
||||
auto structType = typeConverter.convertType(memRefType);
|
||||
auto memRefDescriptor = MemRefDescriptor::undef(rewriter, loc, structType);
|
||||
|
@ -1155,37 +1184,16 @@ MemRefDescriptor ConvertToLLVMPattern::createMemRefDescriptor(
|
|||
|
||||
// Field 3: Offset in aligned pointer.
|
||||
memRefDescriptor.setOffset(rewriter, loc,
|
||||
createIndexConstant(rewriter, loc, offset));
|
||||
createIndexConstant(rewriter, loc, 0));
|
||||
|
||||
if (memRefType.getRank() == 0)
|
||||
// No size/stride descriptor in memref, return the descriptor value.
|
||||
return memRefDescriptor;
|
||||
// Fields 4: Sizes.
|
||||
for (auto en : llvm::enumerate(sizes))
|
||||
memRefDescriptor.setSize(rewriter, loc, en.index(), en.value());
|
||||
|
||||
// Field 5: Strides.
|
||||
for (auto en : llvm::enumerate(strides))
|
||||
memRefDescriptor.setStride(rewriter, loc, en.index(), en.value());
|
||||
|
||||
// Fields 4 and 5: sizes and strides of the strided MemRef.
|
||||
// Store all sizes in the descriptor. Only dynamic sizes are passed in as
|
||||
// operands to AllocOp.
|
||||
Value runningStride = nullptr;
|
||||
// Iterate strides in reverse order, compute runningStride and strideValues.
|
||||
auto nStrides = strides.size();
|
||||
SmallVector<Value, 4> strideValues(nStrides, nullptr);
|
||||
for (unsigned i = 0; i < nStrides; ++i) {
|
||||
int64_t index = nStrides - 1 - i;
|
||||
if (strides[index] == MemRefType::getDynamicStrideOrOffset())
|
||||
// Identity layout map is enforced in the match function, so we compute:
|
||||
// `runningStride *= sizes[index + 1]`
|
||||
runningStride = runningStride ? rewriter.create<LLVM::MulOp>(
|
||||
loc, runningStride, sizes[index + 1])
|
||||
: createIndexConstant(rewriter, loc, 1);
|
||||
else
|
||||
runningStride = createIndexConstant(rewriter, loc, strides[index]);
|
||||
strideValues[index] = runningStride;
|
||||
}
|
||||
// Fill size and stride descriptors in memref.
|
||||
for (auto indexedSize : llvm::enumerate(sizes)) {
|
||||
int64_t index = indexedSize.index();
|
||||
memRefDescriptor.setSize(rewriter, loc, index, indexedSize.value());
|
||||
memRefDescriptor.setStride(rewriter, loc, index, strideValues[index]);
|
||||
}
|
||||
return memRefDescriptor;
|
||||
}
|
||||
|
||||
|
@ -1953,15 +1961,11 @@ protected:
|
|||
return rewriter.create<LLVM::BitcastOp>(loc, ptrType, allocatedPtr);
|
||||
}
|
||||
|
||||
/// Returns if buffer allocation needs buffer size to be computed. This size
|
||||
/// feeds into the `bufferSize` argument of `allocateBuffer`.
|
||||
virtual bool needsBufferSize() const { return true; }
|
||||
|
||||
/// Allocates the underlying buffer. Returns the allocated pointer and the
|
||||
/// aligned pointer.
|
||||
virtual std::tuple<Value, Value>
|
||||
allocateBuffer(ConversionPatternRewriter &rewriter, Location loc,
|
||||
Value bufferSize, Operation *op) const = 0;
|
||||
Value sizeBytes, Operation *op) const = 0;
|
||||
|
||||
private:
|
||||
static MemRefType getMemRefResultType(Operation *op) {
|
||||
|
@ -1998,37 +2002,20 @@ private:
|
|||
// values and dynamic sizes are passed to 'alloc' as operands. In case of
|
||||
// zero-dimensional memref, assume a scalar (size 1).
|
||||
SmallVector<Value, 4> sizes;
|
||||
this->getMemRefDescriptorSizes(loc, memRefType, operands, rewriter, sizes);
|
||||
|
||||
Value bufferSize;
|
||||
if (needsBufferSize())
|
||||
bufferSize = this->getCumulativeSizeInBytes(
|
||||
loc, memRefType.getElementType(), sizes, rewriter);
|
||||
SmallVector<Value, 4> strides;
|
||||
Value sizeBytes;
|
||||
this->getMemRefDescriptorSizes(loc, memRefType, operands, rewriter, sizes,
|
||||
strides, sizeBytes);
|
||||
|
||||
// Allocate the underlying buffer.
|
||||
Value allocatedPtr;
|
||||
Value alignedPtr;
|
||||
std::tie(allocatedPtr, alignedPtr) =
|
||||
this->allocateBuffer(rewriter, loc, bufferSize, op);
|
||||
|
||||
int64_t offset;
|
||||
SmallVector<int64_t, 4> strides;
|
||||
auto successStrides = getStridesAndOffset(memRefType, strides, offset);
|
||||
(void)successStrides;
|
||||
assert(succeeded(successStrides) && "unexpected non-strided memref");
|
||||
assert(offset != MemRefType::getDynamicStrideOrOffset() &&
|
||||
"unexpected dynamic offset");
|
||||
|
||||
// 0-D memref corner case: they have size 1.
|
||||
assert(
|
||||
((memRefType.getRank() == 0 && strides.empty() && sizes.size() == 1) ||
|
||||
(strides.size() == sizes.size())) &&
|
||||
"unexpected number of strides");
|
||||
this->allocateBuffer(rewriter, loc, sizeBytes, op);
|
||||
|
||||
// Create the MemRef descriptor.
|
||||
auto memRefDescriptor =
|
||||
this->createMemRefDescriptor(loc, memRefType, allocatedPtr, alignedPtr,
|
||||
offset, strides, sizes, rewriter);
|
||||
auto memRefDescriptor = this->createMemRefDescriptor(
|
||||
loc, memRefType, allocatedPtr, alignedPtr, sizes, strides, rewriter);
|
||||
|
||||
// Return the final value of the descriptor.
|
||||
rewriter.replaceOp(op, {memRefDescriptor});
|
||||
|
@ -2040,7 +2027,7 @@ struct AllocOpLowering : public AllocLikeOpLowering {
|
|||
: AllocLikeOpLowering(AllocOp::getOperationName(), converter) {}
|
||||
|
||||
std::tuple<Value, Value> allocateBuffer(ConversionPatternRewriter &rewriter,
|
||||
Location loc, Value bufferSize,
|
||||
Location loc, Value sizeBytes,
|
||||
Operation *op) const override {
|
||||
// Heap allocations.
|
||||
AllocOp allocOp = cast<AllocOp>(op);
|
||||
|
@ -2059,14 +2046,14 @@ struct AllocOpLowering : public AllocLikeOpLowering {
|
|||
|
||||
if (alignment) {
|
||||
// Adjust the allocation size to consider alignment.
|
||||
bufferSize = rewriter.create<LLVM::AddOp>(loc, bufferSize, alignment);
|
||||
sizeBytes = rewriter.create<LLVM::AddOp>(loc, sizeBytes, alignment);
|
||||
}
|
||||
|
||||
// Allocate the underlying buffer and store a pointer to it in the MemRef
|
||||
// descriptor.
|
||||
Type elementPtrType = this->getElementPtrType(memRefType);
|
||||
Value allocatedPtr =
|
||||
createAllocCall(loc, "malloc", elementPtrType, {bufferSize},
|
||||
createAllocCall(loc, "malloc", elementPtrType, {sizeBytes},
|
||||
allocOp.getParentOfType<ModuleOp>(), rewriter);
|
||||
|
||||
Value alignedPtr = allocatedPtr;
|
||||
|
@ -2133,7 +2120,7 @@ struct AlignedAllocOpLowering : public AllocLikeOpLowering {
|
|||
}
|
||||
|
||||
std::tuple<Value, Value> allocateBuffer(ConversionPatternRewriter &rewriter,
|
||||
Location loc, Value bufferSize,
|
||||
Location loc, Value sizeBytes,
|
||||
Operation *op) const override {
|
||||
// Heap allocations.
|
||||
AllocOp allocOp = cast<AllocOp>(op);
|
||||
|
@ -2144,11 +2131,11 @@ struct AlignedAllocOpLowering : public AllocLikeOpLowering {
|
|||
// aligned_alloc requires size to be a multiple of alignment; we will pad
|
||||
// the size to the next multiple if necessary.
|
||||
if (!isMemRefSizeMultipleOf(memRefType, alignment))
|
||||
bufferSize = createAligned(rewriter, loc, bufferSize, allocAlignment);
|
||||
sizeBytes = createAligned(rewriter, loc, sizeBytes, allocAlignment);
|
||||
|
||||
Type elementPtrType = this->getElementPtrType(memRefType);
|
||||
Value allocatedPtr = createAllocCall(
|
||||
loc, "aligned_alloc", elementPtrType, {allocAlignment, bufferSize},
|
||||
loc, "aligned_alloc", elementPtrType, {allocAlignment, sizeBytes},
|
||||
allocOp.getParentOfType<ModuleOp>(), rewriter);
|
||||
|
||||
return std::make_tuple(allocatedPtr, allocatedPtr);
|
||||
|
@ -2169,7 +2156,7 @@ struct AllocaOpLowering : public AllocLikeOpLowering {
|
|||
/// is set to null for stack allocations. `accessAlignment` is set if
|
||||
/// alignment is needed post allocation (for eg. in conjunction with malloc).
|
||||
std::tuple<Value, Value> allocateBuffer(ConversionPatternRewriter &rewriter,
|
||||
Location loc, Value bufferSize,
|
||||
Location loc, Value sizeBytes,
|
||||
Operation *op) const override {
|
||||
|
||||
// With alloca, one gets a pointer to the element type right away.
|
||||
|
@ -2178,7 +2165,7 @@ struct AllocaOpLowering : public AllocLikeOpLowering {
|
|||
auto elementPtrType = this->getElementPtrType(allocaOp.getType());
|
||||
|
||||
auto allocatedElementPtr = rewriter.create<LLVM::AllocaOp>(
|
||||
loc, elementPtrType, bufferSize,
|
||||
loc, elementPtrType, sizeBytes,
|
||||
allocaOp.alignment() ? *allocaOp.alignment() : 0);
|
||||
|
||||
return std::make_tuple(allocatedElementPtr, allocatedElementPtr);
|
||||
|
@ -2453,14 +2440,10 @@ struct GetGlobalMemrefOpLowering : public AllocLikeOpLowering {
|
|||
GetGlobalMemrefOpLowering(LLVMTypeConverter &converter)
|
||||
: AllocLikeOpLowering(GetGlobalMemrefOp::getOperationName(), converter) {}
|
||||
|
||||
/// Allocation for GetGlobalMemrefOp just returns the GV pointer, so no need
|
||||
/// to compute buffer size.
|
||||
bool needsBufferSize() const override { return false; }
|
||||
|
||||
/// Buffer "allocation" for get_global_memref op is getting the address of
|
||||
/// the global variable referenced.
|
||||
std::tuple<Value, Value> allocateBuffer(ConversionPatternRewriter &rewriter,
|
||||
Location loc, Value bufferSize,
|
||||
Location loc, Value sizeBytes,
|
||||
Operation *op) const override {
|
||||
auto getGlobalOp = cast<GetGlobalMemrefOp>(op);
|
||||
MemRefType type = getGlobalOp.result().getType().cast<MemRefType>();
|
||||
|
|
|
@ -29,13 +29,12 @@ func @check_arguments(%static: memref<10x20xf32>, %dynamic : memref<?x?xf32>, %m
|
|||
// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> {
|
||||
func @mixed_alloc(%arg0: index, %arg1: index) -> memref<?x42x?xf32> {
|
||||
// CHECK: %[[c42:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64
|
||||
// CHECK-NEXT: llvm.mul %[[M]], %[[c42]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[sz:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[sz]], %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[st0:.*]] = llvm.mul %[[N]], %[[c42]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[st0]], %[[M]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
|
@ -43,15 +42,12 @@ func @mixed_alloc(%arg0: index, %arg1: index) -> memref<?x42x?xf32> {
|
|||
// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: %[[st2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[st1:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[c42]] : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[c42]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st2]], %{{.*}}[4, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
%0 = alloc(%arg0, %arg1) : memref<?x42x?xf32>
|
||||
// CHECK-NEXT: llvm.return %{{.*}} : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)>
|
||||
return %0 : memref<?x42x?xf32>
|
||||
|
@ -70,12 +66,11 @@ func @mixed_dealloc(%arg0: memref<?x42x?xf32>) {
|
|||
// CHECK-LABEL: func @dynamic_alloc(
|
||||
// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> {
|
||||
func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> {
|
||||
// CHECK: %[[sz:.*]] = llvm.mul %[[M]], %[[N]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[sz]], %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[sz:.*]] = llvm.mul %[[N]], %[[M]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: llvm.call @malloc(%[[sz_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
|
@ -83,12 +78,10 @@ func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> {
|
|||
// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[one]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
%0 = alloc(%arg0, %arg1) : memref<?x?xf32>
|
||||
// CHECK-NEXT: llvm.return %{{.*}} : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
return %0 : memref<?x?xf32>
|
||||
|
@ -99,23 +92,20 @@ func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> {
|
|||
// CHECK-LABEL: func @dynamic_alloca
|
||||
// CHECK: %[[M:.*]]: !llvm.i64, %[[N:.*]]: !llvm.i64) -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> {
|
||||
func @dynamic_alloca(%arg0: index, %arg1: index) -> memref<?x?xf32> {
|
||||
// CHECK: %[[num_elems:.*]] = llvm.mul %[[M]], %[[N]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %[[N]], %[[M]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sz_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[sz_bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[allocated]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: %[[off:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[off]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[st0:.*]] = llvm.mul %{{.*}}, %[[N]] : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[M]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st0]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[N]], %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[st1]], %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
%0 = alloca(%arg0, %arg1) : memref<?x?xf32>
|
||||
|
||||
|
@ -144,12 +134,11 @@ func @dynamic_dealloc(%arg0: memref<?x?xf32>) {
|
|||
func @stdlib_aligned_alloc(%N : index) -> memref<32x18xf32> {
|
||||
// ALIGNED-ALLOC-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[num_elems:.*]] = llvm.mul %0, %1 : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// ALIGNED-ALLOC-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// ALIGNED-ALLOC-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// ALIGNED-ALLOC-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// ALIGNED-ALLOC-NEXT: %[[bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[alignment:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64
|
||||
// ALIGNED-ALLOC-NEXT: %[[allocated:.*]] = llvm.call @aligned_alloc(%[[alignment]], %[[bytes]]) : (!llvm.i64, !llvm.i64) -> !llvm.ptr<i8>
|
||||
// ALIGNED-ALLOC-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
|
|
|
@ -70,13 +70,11 @@ func @check_static_return_with_offset(%static : memref<32x18xf32, offset:7, stri
|
|||
// CHECK-LABEL: func @zero_d_alloc() -> !llvm.struct<(ptr<float>, ptr<float>, i64)> {
|
||||
// BAREPTR-LABEL: func @zero_d_alloc() -> !llvm.ptr<float> {
|
||||
func @zero_d_alloc() -> memref<f32> {
|
||||
// CHECK-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: llvm.call @malloc(%{{.*}}) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64)>
|
||||
// CHECK-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)>
|
||||
|
@ -84,13 +82,11 @@ func @zero_d_alloc() -> memref<f32> {
|
|||
// CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64)>
|
||||
|
||||
// BAREPTR-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// BAREPTR-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64
|
||||
// BAREPTR-NEXT: llvm.call @malloc(%{{.*}}) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// BAREPTR-NEXT: llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// BAREPTR-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64)>
|
||||
// BAREPTR-NEXT: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)>
|
||||
|
@ -122,14 +118,13 @@ func @zero_d_dealloc(%arg0: memref<f32>) {
|
|||
// CHECK-LABEL: func @aligned_1d_alloc(
|
||||
// BAREPTR-LABEL: func @aligned_1d_alloc(
|
||||
func @aligned_1d_alloc() -> memref<42xf32> {
|
||||
// CHECK: llvm.mlir.constant(42 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[allocsize:.*]] = llvm.add {{.*}}, %[[alignment]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr<float> to !llvm.i64
|
||||
|
@ -145,14 +140,13 @@ func @aligned_1d_alloc() -> memref<42xf32> {
|
|||
// CHECK-NEXT: %[[c0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK-NEXT: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)>
|
||||
|
||||
// BAREPTR-NEXT: llvm.mlir.constant(42 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[st1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// BAREPTR-NEXT: llvm.mul %{{.*}}, %[[sizeof]] : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// BAREPTR-NEXT: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[allocsize:.*]] = llvm.add {{.*}}, %[[alignment]] : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[allocsize]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// BAREPTR-NEXT: %[[ptr:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr<float> to !llvm.i64
|
||||
|
@ -176,26 +170,18 @@ func @aligned_1d_alloc() -> memref<42xf32> {
|
|||
// CHECK-LABEL: func @static_alloc() -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> {
|
||||
// BAREPTR-LABEL: func @static_alloc() -> !llvm.ptr<float> {
|
||||
func @static_alloc() -> memref<32x18xf32> {
|
||||
// CHECK: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %0, %1 : !llvm.i64
|
||||
// CHECK: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// CHECK-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
|
||||
// BAREPTR-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[num_elems:.*]] = llvm.mul %[[sz1]], %[[sz2]] : !llvm.i64
|
||||
// BAREPTR: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// BAREPTR-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64
|
||||
// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// BAREPTR-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// BAREPTR-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// BAREPTR-NEXT: %[[allocated:.*]] = llvm.call @malloc(%[[size_bytes]]) : (!llvm.i64) -> !llvm.ptr<i8>
|
||||
// BAREPTR-NEXT: llvm.bitcast %[[allocated]] : !llvm.ptr<i8> to !llvm.ptr<float>
|
||||
%0 = alloc() : memref<32x18xf32>
|
||||
return %0 : memref<32x18xf32>
|
||||
|
@ -207,13 +193,12 @@ func @static_alloc() -> memref<32x18xf32> {
|
|||
func @static_alloca() -> memref<32x18xf32> {
|
||||
// CHECK-NEXT: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[num_elems:.*]] = llvm.mul %0, %1 : !llvm.i64
|
||||
// CHECK-NEXT: %[[st2:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[null:.*]] = llvm.mlir.null : !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[one:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[sizeof:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[bytes:.*]] = llvm.mul %[[num_elems]], %[[sizeof]] : !llvm.i64
|
||||
// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr<float>, !llvm.i64) -> !llvm.ptr<float>
|
||||
// CHECK-NEXT: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr<float> to !llvm.i64
|
||||
// CHECK-NEXT: %[[allocated:.*]] = llvm.alloca %[[size_bytes]] x !llvm.float : (!llvm.i64) -> !llvm.ptr<float>
|
||||
%0 = alloca() : memref<32x18xf32>
|
||||
|
||||
// Test with explicitly specified alignment. llvm.alloca takes care of the
|
||||
|
|
|
@ -142,6 +142,7 @@ global_memref @gv2 : memref<2x3xf32> = dense<[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]]>
|
|||
func @get_gv0_memref() {
|
||||
%0 = get_global_memref @gv0 : memref<2xf32>
|
||||
// CHECK: %[[DIM:.*]] = llvm.mlir.constant(2 : index) : !llvm.i64
|
||||
// CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @gv0 : !llvm.ptr<array<2 x float>>
|
||||
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ADDR]][%[[ZERO]], %[[ZERO]]] : (!llvm.ptr<array<2 x float>>, !llvm.i64, !llvm.i64) -> !llvm.ptr<float>
|
||||
|
@ -152,7 +153,6 @@ func @get_gv0_memref() {
|
|||
// CHECK: llvm.insertvalue %[[GEP]], {{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)>
|
||||
// CHECK: %[[OFFSET:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK: llvm.insertvalue %[[OFFSET]], {{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)>
|
||||
// CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK: llvm.insertvalue %[[DIM]], {{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)>
|
||||
// CHECK: llvm.insertvalue %[[STRIDE]], {{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)>
|
||||
return
|
||||
|
@ -163,6 +163,7 @@ func @get_gv0_memref() {
|
|||
func @get_gv2_memref() {
|
||||
// CHECK: %[[DIM0:.*]] = llvm.mlir.constant(2 : index) : !llvm.i64
|
||||
// CHECK: %[[DIM1:.*]] = llvm.mlir.constant(3 : index) : !llvm.i64
|
||||
// CHECK: %[[STRIDE1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @gv2 : !llvm.ptr<array<2 x array<3 x float>>>
|
||||
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ADDR]][%[[ZERO]], %[[ZERO]], %[[ZERO]]] : (!llvm.ptr<array<2 x array<3 x float>>>, !llvm.i64, !llvm.i64, !llvm.i64) -> !llvm.ptr<float>
|
||||
|
@ -173,11 +174,9 @@ func @get_gv2_memref() {
|
|||
// CHECK: llvm.insertvalue %[[GEP]], {{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK: %[[OFFSET:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
|
||||
// CHECK: llvm.insertvalue %[[OFFSET]], {{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK: %[[STRIDE1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
|
||||
// CHECK: %[[STRIDE0:.*]] = llvm.mlir.constant(3 : index) : !llvm.i64
|
||||
// CHECK: llvm.insertvalue %[[DIM0]], {{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK: llvm.insertvalue %[[STRIDE0]], {{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK: llvm.insertvalue %[[DIM1]], {{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK: llvm.insertvalue %[[DIM1]], {{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
// CHECK: llvm.insertvalue %[[STRIDE1]], {{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
|
||||
|
||||
%0 = get_global_memref @gv2 : memref<2x3xf32>
|
||||
|
|
Loading…
Reference in New Issue