diff options
author | Mats Petersson <mats.petersson@arm.com> | 2023-05-04 18:45:44 +0100 |
---|---|---|
committer | Mats Petersson <mats.petersson@arm.com> | 2023-05-05 17:37:41 +0100 |
commit | 43cf32a1c021ab095426320a2e3c4abb5544e0ad (patch) | |
tree | 0abe3e5dc70e1c133c80c5aec9f154ec01993ba3 /flang | |
parent | 6e7840dd42d1c0a23f69bcfcda457f086ed35743 (diff) | |
download | llvm-43cf32a1c021ab095426320a2e3c4abb5544e0ad.tar.gz |
[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
Diffstat (limited to 'flang')
-rw-r--r-- | flang/docs/Extensions.md | 1 | ||||
-rw-r--r-- | flang/lib/Lower/ConvertVariable.cpp | 12 | ||||
-rw-r--r-- | flang/lib/Optimizer/CodeGen/CodeGen.cpp | 2 | ||||
-rw-r--r-- | flang/test/Lower/target_definition.f90 | 2 |
4 files changed, 12 insertions, 5 deletions
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index fbeada77d644..cf6b65c0a6f5 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -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)`. diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 65ae694d23f6..c0343356a84a 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -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 diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 72f02cb42529..c96ce573e9c4 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -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)); diff --git a/flang/test/Lower/target_definition.f90 b/flang/test/Lower/target_definition.f90 index 2bde8b31c4a1..88b31e4598d4 100644 --- a/flang/test/Lower/target_definition.f90 +++ b/flang/test/Lower/target_definition.f90 @@ -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: } |