This is an archive of the discontinued LLVM Phabricator instance.

[flang] Allow and use fir.rebox in fir.global
ClosedPublic

Authored by jeanPerier on Jan 6 2023, 7:13 AM.

Details

Summary

The current lowering of initial target in fir.global is relying
on how fir.box are created: instead of using a fir.rebox to add
the POINTER attribute to the created descriptor, it is looking
for a fir.embox defining operation and creating a copy of
it with a different result types.

The rational for doing so was that fir.rebox codegen was not possible
inside fir.global because it expects to manipulate the input fir.box
in memory, while objects cannot be manipulated in memory inside
a fir.global region that must be constant foldable.

But this approach has two problems:

  • it won't work with hlfir where fir.box may be created by more operations than fir.embox (e.g. hlfir.delcare or hlfir.designate). In general, looking for a precise defining op for a value is fragile.
  • manually copying and modifying an operation is risky: it is easy to forget copying some default operands (that could be added later).

This patch modifies the helpers to get descriptor fields so that they
can both operate on fir.box lowered in memory or in an llvm.struct
value. This enables the usage of fir.rebox in fir.global op.

The fallout in FIR tests is caused by the usage of constant index
when creating GEP (because extractOp requires constant indices).
MLIR builder uses i32 bit constant indices when non mlir::Value
indices are passed to the MLIR GEP op builder. Previously,
an 64 nist mlir constant value was created and passed to the GEP
builder. In this case, the builder respect the value type when
later generating the GEP.
Given this changes impact the "dimension" index that can, per
Fortran requirement, not be greated than 15, using a 32 bit index
is just fine and actually simplify the MLIR LLVM IR generation.

The fallout in lowering tests is caused by the introduction
of the fir.rebox everytime an initial target is created.

Diff Detail

Event Timeline

jeanPerier created this revision.Jan 6 2023, 7:13 AM
jeanPerier requested review of this revision.Jan 6 2023, 7:13 AM
PeteSteinfeld requested changes to this revision.Jan 6 2023, 8:26 AM

I get build errors with this patch. I'm building with GCC 9.3.0. Here's the relevant excerpt from my build log:

[6211/7172] Building CXX object tools/flang/lib/Optimizer/CodeGen/CMakeFiles/obj.FIRCodeGen.dir/CodeGen.cpp.o
FAILED: tools/flang/lib/Optimizer/CodeGen/CMakeFiles/obj.FIRCodeGen.dir/CodeGen.cpp.o 
/home/sw/thirdparty/gcc/gcc-9.3.0/linux86-64/bin/g++ -DFLANG_INCLUDE_TESTS=1 -DFLANG_LITTLE_ENDIAN=1 -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/local/home/psteinfeld/main/allow/build/tools/flang/lib/Optimizer/CodeGen -I/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen -I/local/home/psteinfeld/main/allow/flang/include -I/local/home/psteinfeld/main/allow/build/tools/flang/include -I/local/home/psteinfeld/main/allow/build/include -I/local/home/psteinfeld/main/allow/llvm/include -isystem /local/home/psteinfeld/main/allow/llvm/../mlir/include -isystem /local/home/psteinfeld/main/allow/build/tools/mlir/include -isystem /local/home/psteinfeld/main/allow/build/tools/clang/include -isystem /local/home/psteinfeld/main/allow/llvm/../clang/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -fdiagnostics-color -ffunction-sections -fdata-sections -Werror -Wno-deprecated-copy -Wno-ctad-maybe-unsupported -fno-strict-aliasing -fno-semantic-interposition -O3 -DNDEBUG  -fno-exceptions -fno-rtti -UNDEBUG -std=c++17 -MD -MT tools/flang/lib/Optimizer/CodeGen/CMakeFiles/obj.FIRCodeGen.dir/CodeGen.cpp.o -MF tools/flang/lib/Optimizer/CodeGen/CMakeFiles/obj.FIRCodeGen.dir/CodeGen.cpp.o.d -o tools/flang/lib/Optimizer/CodeGen/CMakeFiles/obj.FIRCodeGen.dir/CodeGen.cpp.o -c /local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp: In instantiation of ‘mlir::LLVM::GEPOp {anonymous}::FIROpConversion<FromOp>::genGEP(mlir::Location, mlir::Type, mlir::ConversionPatternRewriter&, mlir::Value, ARGS ...) const [with ARGS = {int, unsigned int, mlir::Value, int}; FromOp = fir::BoxDimsOp]’:
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:208:23:   required from ‘mlir::Value {anonymous}::FIROpConversion<FromOp>::loadDimFieldFromBox(mlir::Location, mlir::Value, mlir::Value, int, mlir::Type, mlir::ConversionPatternRewriter&) const [with FromOp = fir::BoxDimsOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:184:22:   required from ‘llvm::SmallVector<mlir::Value, 3> {anonymous}::FIROpConversion<FromOp>::getDimsFromBox(mlir::Location, llvm::ArrayRef<mlir::Type>, mlir::Value, mlir::Value, mlir::ConversionPatternRewriter&) const [with FromOp = fir::BoxDimsOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:548:58:   required from here
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#1’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
  305 |     llvm::SmallVector<mlir::LLVM::GEPArg> cv = {args...};
      |                                                 ^~~~
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp: In instantiation of ‘mlir::LLVM::GEPOp {anonymous}::FIROpConversion<FromOp>::genGEP(mlir::Location, mlir::Type, mlir::ConversionPatternRewriter&, mlir::Value, ARGS ...) const [with ARGS = {int, unsigned int, unsigned int, int}; FromOp = fir::cg::XReboxOp]’:
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:219:25:   required from ‘mlir::Value {anonymous}::FIROpConversion<FromOp>::getDimFieldFromBox(mlir::Location, mlir::Value, unsigned int, int, mlir::Type, mlir::ConversionPatternRewriter&) const [with FromOp = fir::cg::XReboxOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:194:22:   required from ‘llvm::SmallVector<mlir::Value, 3> {anonymous}::FIROpConversion<FromOp>::getDimsFromBox(mlir::Location, llvm::ArrayRef<mlir::Type>, mlir::Value, unsigned int, mlir::ConversionPatternRewriter&) const [with FromOp = fir::cg::XReboxOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:2014:79:   required from here
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#1’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#2’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp: In instantiation of ‘mlir::LLVM::GEPOp {anonymous}::FIROpConversion<FromOp>::genGEP(mlir::Location, mlir::Type, mlir::ConversionPatternRewriter&, mlir::Value, ARGS ...) const [with ARGS = {int, unsigned int, unsigned int, int}; FromOp = fir::cg::XArrayCoorOp]’:
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:219:25:   required from ‘mlir::Value {anonymous}::FIROpConversion<FromOp>::getDimFieldFromBox(mlir::Location, mlir::Value, unsigned int, int, mlir::Type, mlir::ConversionPatternRewriter&) const [with FromOp = fir::cg::XArrayCoorOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:231:12:   required from ‘mlir::Value {anonymous}::FIROpConversion<FromOp>::getStrideFromBox(mlir::Location, mlir::Value, unsigned int, mlir::ConversionPatternRewriter&) const [with FromOp = fir::cg::XArrayCoorOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:2428:76:   required from here
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#1’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#2’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp: In instantiation of ‘mlir::LLVM::GEPOp {anonymous}::FIROpConversion<FromOp>::genGEP(mlir::Location, mlir::Type, mlir::ConversionPatternRewriter&, mlir::Value, ARGS ...) const [with ARGS = {int, unsigned int, unsigned int, int}; FromOp = fir::CoordinateOp]’:
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:219:25:   required from ‘mlir::Value {anonymous}::FIROpConversion<FromOp>::getDimFieldFromBox(mlir::Location, mlir::Value, unsigned int, int, mlir::Type, mlir::ConversionPatternRewriter&) const [with FromOp = fir::CoordinateOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:231:12:   required from ‘mlir::Value {anonymous}::FIROpConversion<FromOp>::getStrideFromBox(mlir::Location, mlir::Value, unsigned int, mlir::ConversionPatternRewriter&) const [with FromOp = fir::CoordinateOp]’
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:2678:69:   required from here
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#1’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
/local/home/psteinfeld/main/allow/flang/lib/Optimizer/CodeGen/CodeGen.cpp:305:49: error: narrowing conversion of ‘args#2’ from ‘unsigned int’ to ‘int32_t’ {aka ‘int’} [-Werror=narrowing]
cc1plus: error: unrecognized command line option ‘-Wno-ctad-maybe-unsupported’ [-Werror]
cc1plus: all warnings being treated as errors
This revision now requires changes to proceed.Jan 6 2023, 8:26 AM
vzakhari added inline comments.Jan 6 2023, 8:39 AM
flang/lib/Optimizer/CodeGen/CodeGen.cpp
1993

Jean, can you please explain how the mlir::UnrealizedConversionCastOp is actually removed? I see that here we "ignore" it and use its operand instead of the result, but the operation should be still there. Is it removed somewhere just because it does not have any uses?

jeanPerier updated this revision to Diff 487330.Jan 9 2023, 1:32 AM

Fix signed/unsigned narrowing warning.

Looks like a part of your revision disappeared with your last update.

I get build errors with this patch. I'm building with GCC 9.3.0. Here's the relevant excerpt from my build log:

Thanks @PeteSteinfeld, I was able to reproduce and this should be fixed now.

flang/lib/Optimizer/CodeGen/CodeGen.cpp
1993

I thought this was trivially some DCE at play before you asked, but it is a bit more subtle. My understanding is the following:

  • mlir::UnrealizedConversionCastOp are added automatically by the dialect translation pass framework to satisfy type MLIR constraints while doing a dialect translation (at [1]).
  • At the end of the conversion pass, the framework tries to get rid of the inserted casts, it succeeds at [2] in this case because the FIR to LLVM IR translation registers a handler (at [3]) that just uses the builtin.unrealized_conversion_cast operand as what the builtin.unrealized_conversion_cast should be rewritten to (which allows supporting unused builtin.unrealized_conversion_cast, since it is they can be rewritten to any existing value in the IR with no effect).

There is also a "reconcile-unrealized-casts" mlir pass to get rid of builtin.unrealized_conversion_cast in some cases [4], but it is not used in FIR pipeline.

[1]: https://github.com/llvm/llvm-project/blob/0de16fafa57153a70168d69ca8591dbe8489905f/mlir/lib/Transforms/Utils/DialectConversion.cpp#L428
[2]: https://github.com/llvm/llvm-project/blob/0de16fafa57153a70168d69ca8591dbe8489905f/mlir/lib/Transforms/Utils/DialectConversion.cpp#L2785
[3]: https://github.com/llvm/llvm-project/blob/0de16fafa57153a70168d69ca8591dbe8489905f/flang/lib/Optimizer/CodeGen/TypeConverter.h#L148

[4]: https://github.com/llvm/llvm-project/blob/67d0d7ac0acb0665d6a09f61278fbcf51f0114c2/mlir/lib/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.cpp

jeanPerier updated this revision to Diff 487367.Jan 9 2023, 3:15 AM

Apply previous fix correctly.

Looks like a part of your revision disappeared with your last update.

Thanks, forgot to squash.

PeteSteinfeld accepted this revision.Jan 9 2023, 7:05 AM

All builds and tests correctly and looks good.

This revision is now accepted and ready to land.Jan 9 2023, 7:05 AM
vzakhari accepted this revision.Jan 9 2023, 10:39 AM
vzakhari added inline comments.
flang/lib/Optimizer/CodeGen/CodeGen.cpp
1993

Thank you for the detailed explanation, Jean! This looks brittle. I think it might be worth adding a comment around [3] to mention this box case, so that there is more context when the FIXME notes are being worked on.

Update comment about addTargetMaterialization as suggested and fix
conflict with https://reviews.llvm.org/D141274 after rebase.

This revision was landed with ongoing or failed builds.Jan 10 2023, 12:27 AM
This revision was automatically updated to reflect the committed changes.
vzakhari added inline comments.Jan 10 2023, 10:18 AM
flang/lib/Optimizer/CodeGen/TypeConverter.h
157

Thank you for the comment, Jean!

nit typo: discrepencies -> discrepancies