[flang] Erase fir.local ops before lowering fir to llvm (#143687)

`fir.local` ops are not supposed to have any uses at this point (i.e.
during lowering to LLVM). In case of serialization, the
`fir.do_concurrent` users are expected to have been lowered to
`fir.do_loop` nests. In case of parallelization, the `fir.do_concurrent`
users are expected to have been lowered to the target parallel model
(e.g. OpenMP).

This hopefully resolved a build issue introduced by
https://github.com/llvm/llvm-project/pull/142567 (see for example:
https://lab.llvm.org/buildbot/#/builders/199/builds/4009).
This commit is contained in:
Kareem Ergawy
2025-06-12 05:58:55 +02:00
committed by GitHub
parent f09050fdc8
commit 282e471018
2 changed files with 43 additions and 9 deletions

View File

@@ -3294,6 +3294,30 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
}
};
struct LocalitySpecifierOpConversion
: public fir::FIROpConversion<fir::LocalitySpecifierOp> {
using FIROpConversion::FIROpConversion;
llvm::LogicalResult
matchAndRewrite(fir::LocalitySpecifierOp localizer, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
#ifdef EXPENSIVE_CHECKS
auto uses = mlir::SymbolTable::getSymbolUses(
localizer, localizer->getParentOfType<mlir::ModuleOp>());
// `fir.local` ops are not supposed to have any uses at this point (i.e.
// during lowering to LLVM). In case of serialization, the
// `fir.do_concurrent` users are expected to have been lowered to
// `fir.do_loop` nests. In case of parallelization, the `fir.do_concurrent`
// users are expected to have been lowered to the target parallel model
// (e.g. OpenMP).
assert(uses && uses->empty());
#endif
rewriter.eraseOp(localizer);
return mlir::success();
}
};
/// Lower `fir.no_reassoc` to LLVM IR dialect.
/// TODO: how do we want to enforce this in LLVM-IR? Can we manipulate the fast
/// math flags?
@@ -4249,15 +4273,15 @@ void fir::populateFIRToLLVMConversionPatterns(
FieldIndexOpConversion, FirEndOpConversion, FreeMemOpConversion,
GlobalLenOpConversion, GlobalOpConversion, InsertOnRangeOpConversion,
IsPresentOpConversion, LenParamIndexOpConversion, LoadOpConversion,
MulcOpConversion, NegcOpConversion, NoReassocOpConversion,
SelectCaseOpConversion, SelectOpConversion, SelectRankOpConversion,
SelectTypeOpConversion, ShapeOpConversion, ShapeShiftOpConversion,
ShiftOpConversion, SliceOpConversion, StoreOpConversion,
StringLitOpConversion, SubcOpConversion, TypeDescOpConversion,
TypeInfoOpConversion, UnboxCharOpConversion, UnboxProcOpConversion,
UndefOpConversion, UnreachableOpConversion, XArrayCoorOpConversion,
XEmboxOpConversion, XReboxOpConversion, ZeroOpConversion>(converter,
options);
LocalitySpecifierOpConversion, MulcOpConversion, NegcOpConversion,
NoReassocOpConversion, SelectCaseOpConversion, SelectOpConversion,
SelectRankOpConversion, SelectTypeOpConversion, ShapeOpConversion,
ShapeShiftOpConversion, ShiftOpConversion, SliceOpConversion,
StoreOpConversion, StringLitOpConversion, SubcOpConversion,
TypeDescOpConversion, TypeInfoOpConversion, UnboxCharOpConversion,
UnboxProcOpConversion, UndefOpConversion, UnreachableOpConversion,
XArrayCoorOpConversion, XEmboxOpConversion, XReboxOpConversion,
ZeroOpConversion>(converter, options);
// Patterns that are populated without a type converter do not trigger
// target materializations for the operands of the root op.

10
flang/test/Fir/local.fir Normal file
View File

@@ -0,0 +1,10 @@
// RUN: fir-opt --fir-to-llvm-ir %s | FileCheck %s
// Tests that `fir.local` ops are dropped from the module before LLVM lowering.
fir.local {type = local} @local_privatizer : i32
func.func @foo() {
return
}
// CHECK-NOT: fir.local