[flang]Zero Initialize simple types

Instead of filling uninitialized global variables with "undef",
initialize them with 0. Only for Integer, Float or Logical type
variables. Complex, user defined data structures, arrays, etc
are not supported at this point.

This patch fixes the main problem of
https://github.com/llvm/llvm-project/issues/62432

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D149877
This commit is contained in:
Mats Petersson
2023-05-04 18:45:44 +01:00
parent 6e7840dd42
commit 43cf32a1c0
4 changed files with 12 additions and 5 deletions

View File

@@ -99,6 +99,7 @@ end
* `<>` as synonym for `.NE.` and `/=`
* `$` and `@` as legal characters in names
* Initialization in type declaration statements using `/values/`
* Saved integer, logical and real scalars are zero initialized.
* Kind specification with `*`, e.g. `REAL*4`
* `DOUBLE COMPLEX` as a synonym for `COMPLEX(KIND(0.D0))` --
but not when spelled `TYPE(DOUBLECOMPLEX)`.

View File

@@ -495,7 +495,9 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
} else {
TODO(loc, "global"); // Procedure pointer or something else
}
// Creates undefined initializer for globals without initializers
// Creates zero or undefined initializer for globals without initializers
// Zero initializer is used for "simple types" (integer, real and logical),
// undefined is used for types aside from those types.
if (!globalIsInitialized(global)) {
// TODO: Is it really required to add the undef init if the Public
// visibility is set ? We need to make sure the global is not optimized out
@@ -507,8 +509,12 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
TODO(loc, "BIND(C) module variable linkage");
Fortran::lower::createGlobalInitialization(
builder, global, [&](fir::FirOpBuilder &builder) {
builder.create<fir::HasValueOp>(
loc, builder.create<fir::UndefOp>(loc, symTy));
mlir::Value initValue;
if (symTy.isa<mlir::IntegerType, mlir::FloatType, fir::LogicalType>())
initValue = builder.create<fir::ZeroOp>(loc, symTy);
else
initValue = builder.create<fir::UndefOp>(loc, symTy);
builder.create<fir::HasValueOp>(loc, initValue);
});
}
// Set public visibility to prevent global definition to be optimized out

View File

@@ -3283,7 +3283,7 @@ struct ZeroOpConversion : public FIROpConversion<fir::ZeroOp> {
rewriter.replaceOpWithNewOp<mlir::LLVM::NullOp>(zero, ty);
} else if (ty.isa<mlir::IntegerType>()) {
rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(
zero, ty, mlir::IntegerAttr::get(zero.getType(), 0));
zero, ty, mlir::IntegerAttr::get(ty, 0));
} else if (mlir::LLVM::isCompatibleFloatingPointType(ty)) {
rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(
zero, ty, mlir::FloatAttr::get(zero.getType(), 0.0));

View File

@@ -2,7 +2,7 @@
! Test TARGET attributes on a definition of a global symbol.
! CHECK: fir.global @_QMtarget_modEx target : f32 {
! CHECK: %[[init:.*]] = fir.undefined f32
! CHECK: %[[init:.*]] = fir.zero_bits f32
! CHECK: fir.has_value %[[init]] : f32
! CHECK: }