Skip to content

Commit 964dc36

Browse files
committed
[AsyncToLLVM] aligned_alloc requires the size to be a multiple of aignment, so round up
Fixes a crash with debug malloc.
1 parent 5fb39f0 commit 964dc36

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,20 +333,29 @@ class CoroBeginOpConversion : public OpConversionPattern<CoroBeginOp> {
333333
auto loc = op->getLoc();
334334

335335
// Get coroutine frame size: @llvm.coro.size.i64.
336-
auto coroSize =
336+
Value coroSize =
337337
rewriter.create<LLVM::CoroSizeOp>(loc, rewriter.getI64Type());
338338
// The coroutine lowering doesn't properly account for alignment of the
339339
// frame, so align everything to 64 bytes which ought to be enough for
340340
// everyone. https://llvm.org/PR53148
341-
auto coroAlign = rewriter.create<LLVM::ConstantOp>(
342-
op->getLoc(), rewriter.getI64Type(), rewriter.getI64IntegerAttr(64));
341+
constexpr int64_t coroAlign = 64;
342+
auto makeConstant = [&](uint64_t c) {
343+
return rewriter.create<LLVM::ConstantOp>(
344+
op->getLoc(), rewriter.getI64Type(), rewriter.getI64IntegerAttr(c));
345+
};
346+
// Round up the size to the alignment. This is a requirement of
347+
// aligned_alloc.
348+
coroSize = rewriter.create<LLVM::AddOp>(op->getLoc(), coroSize,
349+
makeConstant(coroAlign - 1));
350+
coroSize = rewriter.create<LLVM::AndOp>(op->getLoc(), coroSize,
351+
makeConstant(-coroAlign));
343352

344353
// Allocate memory for the coroutine frame.
345354
auto allocFuncOp = LLVM::lookupOrCreateAlignedAllocFn(
346355
op->getParentOfType<ModuleOp>(), rewriter.getI64Type());
347356
auto coroAlloc = rewriter.create<LLVM::CallOp>(
348357
loc, i8Ptr, SymbolRefAttr::get(allocFuncOp),
349-
ValueRange{coroAlign, coroSize.getResult()});
358+
ValueRange{makeConstant(coroAlign), coroSize});
350359

351360
// Begin a coroutine: @llvm.coro.begin.
352361
auto coroId = CoroBeginOpAdaptor(adaptor.getOperands()).id();

mlir/test/Conversion/AsyncToLLVM/convert-coro-to-llvm.mlir

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ func @coro_begin() {
1414
// CHECK: %[[ID:.*]] = llvm.intr.coro.id
1515
%0 = async.coro.id
1616
// CHECK: %[[SIZE:.*]] = llvm.intr.coro.size : i64
17+
// CHECK: %[[C63:.*]] = llvm.mlir.constant(63 : i64) : i64
18+
// CHECK: %[[SIZE2:.*]] = llvm.add %[[SIZE]], %[[C63]] : i64
19+
// CHECK: %[[CN64:.*]] = llvm.mlir.constant(-64 : i64) : i64
20+
// CHECK: %[[SIZE3:.*]] = llvm.and %[[SIZE2]], %[[CN64]] : i64
1721
// CHECK: %[[ALIGN:.*]] = llvm.mlir.constant(64 : i64) : i64
18-
// CHECK: %[[ALLOC:.*]] = llvm.call @aligned_alloc(%[[ALIGN]], %[[SIZE]])
22+
// CHECK: %[[ALLOC:.*]] = llvm.call @aligned_alloc(%[[ALIGN]], %[[SIZE3]])
1923
// CHECK: %[[HDL:.*]] = llvm.intr.coro.begin %[[ID]], %[[ALLOC]]
2024
%1 = async.coro.begin %0
2125
return

0 commit comments

Comments
 (0)