mirror of
https://github.com/intel/llvm.git
synced 2026-01-25 10:55:58 +08:00
[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:
@@ -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)`.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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: }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user