From b6cdce86b8e62968a82943db776cd06ef68cff80 Mon Sep 17 00:00:00 2001 From: ergawy Date: Wed, 11 Jun 2025 06:38:14 -0500 Subject: [PATCH 1/2] [flang] Erase `fir.local` ops before lowering `fir` to `llvm` `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). --- flang/lib/Optimizer/CodeGen/CodeGen.cpp | 41 +++++++++++++++++++------ flang/test/Fir/local.fir | 10 ++++++ 2 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 flang/test/Fir/local.fir diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 82d960a6fc61e..ecce5c6f9d159 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -3294,6 +3294,29 @@ struct LoadOpConversion : public fir::FIROpConversion { } }; +struct LocalitySpecifierOpConversion + : public fir::FIROpConversion { + using FIROpConversion::FIROpConversion; + llvm::LogicalResult + matchAndRewrite(fir::LocalitySpecifierOp localizer, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + auto uses = mlir::SymbolTable::getSymbolUses( + localizer, localizer->getParentOfType()); + + // `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). + if (!uses || !uses->empty()) + return mlir::failure(); + + 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 +4272,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. diff --git a/flang/test/Fir/local.fir b/flang/test/Fir/local.fir new file mode 100644 index 0000000000000..006f5ca944670 --- /dev/null +++ b/flang/test/Fir/local.fir @@ -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 From 1709ab1360758bbe813e5e7eea4b455def8ecbe4 Mon Sep 17 00:00:00 2001 From: ergawy Date: Wed, 11 Jun 2025 07:52:18 -0500 Subject: [PATCH 2/2] use expensive_checks --- flang/lib/Optimizer/CodeGen/CodeGen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index ecce5c6f9d159..a3de3ae9d116a 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -3300,6 +3300,7 @@ struct LocalitySpecifierOpConversion llvm::LogicalResult matchAndRewrite(fir::LocalitySpecifierOp localizer, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override { +#ifdef EXPENSIVE_CHECKS auto uses = mlir::SymbolTable::getSymbolUses( localizer, localizer->getParentOfType()); @@ -3309,8 +3310,8 @@ struct LocalitySpecifierOpConversion // `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). - if (!uses || !uses->empty()) - return mlir::failure(); + assert(uses && uses->empty()); +#endif rewriter.eraseOp(localizer); return mlir::success();