Skip to content

Commit f3fdc96

Browse files
authored
[flang] Fix the incorrect insertion point for alloca (#65999)
While creating a temporary alloca for a box in OpenMp region, the insertion point should be the OpenMP region block instead of the function entry block.
1 parent 5a48a82 commit f3fdc96

File tree

2 files changed

+54
-13
lines changed

2 files changed

+54
-13
lines changed

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,25 +333,28 @@ class FIROpConversion : public mlir::ConvertOpToLLVMPattern<FromOp> {
333333
return rewriter.create<mlir::LLVM::GEPOp>(loc, ty, base, cv);
334334
}
335335

336-
// Find the LLVMFuncOp in whose entry block the alloca should be inserted.
337-
// The order to find the LLVMFuncOp is as follows:
338-
// 1. The parent operation of the current block if it is a LLVMFuncOp.
339-
// 2. The first ancestor that is a LLVMFuncOp.
340-
mlir::LLVM::LLVMFuncOp
341-
getFuncForAllocaInsert(mlir::ConversionPatternRewriter &rewriter) const {
342-
mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp();
343-
return mlir::isa<mlir::LLVM::LLVMFuncOp>(parentOp)
344-
? mlir::cast<mlir::LLVM::LLVMFuncOp>(parentOp)
345-
: parentOp->getParentOfType<mlir::LLVM::LLVMFuncOp>();
336+
// Find the Block in which the alloca should be inserted.
337+
// The order to recursively find the proper block:
338+
// 1. An OpenMP Op that will be outlined.
339+
// 2. A LLVMFuncOp
340+
// 3. The first ancestor that is an OpenMP Op or a LLVMFuncOp
341+
static mlir::Block *getBlockForAllocaInsert(mlir::Operation *op) {
342+
if (auto iface =
343+
mlir::dyn_cast<mlir::omp::OutlineableOpenMPOpInterface>(op))
344+
return iface.getAllocaBlock();
345+
if (auto llvmFuncOp = mlir::dyn_cast<mlir::LLVM::LLVMFuncOp>(op))
346+
return &llvmFuncOp.front();
347+
return getBlockForAllocaInsert(op->getParentOp());
346348
}
347349

348350
// Generate an alloca of size 1 and type \p toTy.
349351
mlir::LLVM::AllocaOp
350352
genAllocaWithType(mlir::Location loc, mlir::Type toTy, unsigned alignment,
351353
mlir::ConversionPatternRewriter &rewriter) const {
352354
auto thisPt = rewriter.saveInsertionPoint();
353-
mlir::LLVM::LLVMFuncOp func = getFuncForAllocaInsert(rewriter);
354-
rewriter.setInsertionPointToStart(&func.front());
355+
mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp();
356+
mlir::Block *insertBlock = getBlockForAllocaInsert(parentOp);
357+
rewriter.setInsertionPointToStart(insertBlock);
355358
auto size = genI32Constant(loc, rewriter, 1);
356359
auto al = rewriter.create<mlir::LLVM::AllocaOp>(loc, toTy, size, alignment);
357360
rewriter.restoreInsertionPoint(thisPt);

flang/test/Fir/convert-to-llvm-openmp-and-fir.fir

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,4 +654,42 @@ func.func @_QPs(%arg0: !fir.ref<!fir.complex<4>> {fir.bindc_name = "x"}) {
654654
%0 = fir.alloca !fir.complex<4> {bindc_name = "v", uniq_name = "_QFsEv"}
655655
omp.atomic.read %0 = %arg0 : !fir.ref<!fir.complex<4>>, !fir.complex<4>
656656
return
657-
}
657+
}
658+
659+
// -----
660+
// Test if llvm.alloca is properly inserted in the omp section
661+
662+
//CHECK: %[[CONST:.*]] = llvm.mlir.constant(1 : i64) : i64
663+
//CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[CONST]] x !llvm.struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)> {bindc_name = "iattr", in_type = !fir.box<!fir.ptr<i32>>, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFEiattr"} : (i64) -> !llvm.ptr<struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)>>
664+
//CHECK: omp.parallel {
665+
//CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
666+
//CHECK: %[[ALLOCA_1:.*]] = llvm.alloca %[[CONST_1:.*]] x !llvm.struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)>>
667+
//CHECK: %[[LOAD:.*]] = llvm.load %[[ALLOCA]] : !llvm.ptr<struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)>>
668+
//CHECK: llvm.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.ptr<struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)>>
669+
//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA_1]][0, 0] : (!llvm.ptr<struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)>>) -> !llvm.ptr<ptr<i32>>
670+
//CHECK: %[[LOAD_2:.*]] = llvm.load %[[GEP]] : !llvm.ptr<ptr<i32>>
671+
//CHECK: omp.terminator
672+
//CHECK: }
673+
674+
func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
675+
%0 = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "iattr", uniq_name = "_QFEiattr"}
676+
%1 = fir.zero_bits !fir.ptr<i32>
677+
%2 = fir.embox %1 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
678+
fir.store %2 to %0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
679+
%3 = fir.address_of(@_QFEx) : !fir.ref<i32>
680+
%4 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
681+
%5 = fir.embox %3 : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>>
682+
fir.store %5 to %0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
683+
omp.parallel {
684+
%6 = fir.load %4 : !fir.ref<i32>
685+
%7 = fir.load %0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
686+
%8 = fir.box_addr %7 : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
687+
fir.store %6 to %8 : !fir.ptr<i32>
688+
omp.terminator
689+
}
690+
return
691+
}
692+
fir.global internal @_QFEx target : i32 {
693+
%0 = fir.zero_bits i32
694+
fir.has_value %0 : i32
695+
}

0 commit comments

Comments
 (0)