Skip to content

[Flang][Driver] Add a flag to control zero initialization of global v… #122144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 15, 2025
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3505,6 +3505,11 @@ def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>,
Visibility<[ClangOption, FlangOption]>;
defm init_global_zero : BoolOptionWithoutMarshalling<"f", "init-global-zero",
PosFlag<SetTrue, [], [FlangOption, FC1Option],
"Zero initialize globals without default initialization (default)">,
NegFlag<SetFalse, [], [FlangOption, FC1Option],
"Do not zero initialize globals without default initialization">>;
def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group<f_Group>;
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ void Flang::addCodegenOptions(const ArgList &Args,
options::OPT_flang_deprecated_no_hlfir,
options::OPT_fno_ppc_native_vec_elem_order,
options::OPT_fppc_native_vec_elem_order,
options::OPT_ftime_report, options::OPT_ftime_report_EQ});
options::OPT_finit_global_zero,
options::OPT_fno_init_global_zero, options::OPT_ftime_report,
options::OPT_ftime_report_EQ});
}

void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
Expand Down
3 changes: 3 additions & 0 deletions flang/include/flang/Lower/LoweringOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,8 @@ ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 0)
/// If false, assume that the shapes/types/allocation-status match.
ENUM_LOWERINGOPT(ReallocateLHS, unsigned, 1, 1)

/// If true, initialize globals without initialization to zero.
/// On by default.
ENUM_LOWERINGOPT(InitGlobalZero, unsigned, 1, 1)
#undef LOWERINGOPT
#undef ENUM_LOWERINGOPT
8 changes: 8 additions & 0 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,14 @@ bool CompilerInvocation::createFromArgs(
invoc.loweringOpts.setNoPPCNativeVecElemOrder(true);
}

// -f[no-]init-global-zero
if (args.hasFlag(clang::driver::options::OPT_finit_global_zero,
clang::driver::options::OPT_fno_init_global_zero,
/*default=*/true))
invoc.loweringOpts.setInitGlobalZero(true);
else
invoc.loweringOpts.setInitGlobalZero(false);

// Preserve all the remark options requested, i.e. -Rpass, -Rpass-missed or
// -Rpass-analysis. This will be used later when processing and outputting the
// remarks generated by LLVM in ExecuteCompilerInvocation.cpp.
Expand Down
6 changes: 5 additions & 1 deletion flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,11 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
global.setLinkName(builder.createCommonLinkage());
Fortran::lower::createGlobalInitialization(
builder, global, [&](fir::FirOpBuilder &builder) {
mlir::Value initValue = builder.create<fir::ZeroOp>(loc, symTy);
mlir::Value initValue;
if (converter.getLoweringOptions().getInitGlobalZero())
initValue = builder.create<fir::ZeroOp>(loc, symTy);
else
initValue = builder.create<fir::UndefOp>(loc, symTy);
builder.create<fir::HasValueOp>(loc, initValue);
});
}
Expand Down
9 changes: 9 additions & 0 deletions flang/test/Driver/fno-zero-init.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
! Check that the driver passes through -f[no-]init-global-zero:
! RUN: %flang -### -S -finit-global-zero %s -o - 2>&1 | FileCheck --check-prefix=CHECK-POS %s
! RUN: %flang -### -S -fno-init-global-zero %s -o - 2>&1 | FileCheck --check-prefix=CHECK-NEG %s
! Check that the compiler accepts -f[no-]init-global-zero:
! RUN: %flang_fc1 -emit-hlfir -finit-global-zero %s -o -
! RUN: %flang_fc1 -emit-hlfir -fno-init-global-zero %s -o -

! CHECK-POS: "-fc1"{{.*}}"-finit-global-zero"
! CHECK-NEG: "-fc1"{{.*}}"-fno-init-global-zero"
17 changes: 17 additions & 0 deletions flang/test/Lower/zero_init.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck --check-prefix=CHECK-DEFAULT %s
! RUN: %flang_fc1 -finit-global-zero -emit-hlfir -o - %s | FileCheck --check-prefix=CHECK-DEFAULT %s
! RUN: %flang_fc1 -fno-init-global-zero -emit-hlfir -o - %s | FileCheck --check-prefix=CHECK-NO-ZERO-INIT %s

module m1
real :: x
end module m1

!CHECK-DEFAULT: fir.global @_QMm1Ex : f32 {
!CHECK-DEFAULT: %[[UNDEF:.*]] = fir.zero_bits f32
!CHECK-DEFAULT: fir.has_value %[[UNDEF]] : f32
!CHECK-DEFAULT: }

!CHECK-NO-ZERO-INIT: fir.global @_QMm1Ex : f32 {
!CHECK-NO-ZERO-INIT: %[[UNDEF:.*]] = fir.undefined f32
!CHECK-NO-ZERO-INIT: fir.has_value %[[UNDEF]] : f32
!CHECK-NO-ZERO-INIT: }
19 changes: 19 additions & 0 deletions flang/test/Lower/zero_init_default_init.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
! RUN: %flang_fc1 -finit-global-zero -emit-hlfir -o - %s | FileCheck %s
! RUN: %flang_fc1 -fno-init-global-zero -emit-hlfir -o - %s | FileCheck %s

! Test that the flag does not affect globals with default init

module m2
type val
integer :: my_val = 1
end type val
type(val) :: v1
end module m2

!CHECK: fir.global @_QMm2Ev1 : !fir.type<_QMm2Tval{my_val:i32}> {
!CHECK: %[[V1:.*]] = fir.undefined !fir.type<_QMm2Tval{my_val:i32}>
!CHECK: %[[ONE:.*]] = arith.constant 1 : i32
!CHECK: %[[V1_INIT:.*]] = fir.insert_value %[[V1]], %[[ONE]], ["my_val", !fir.type<_QMm2Tval{my_val:i32}>] : (!fir.type<_QMm2Tval{my_val:i32}>, i32) -> !fir.type<_QMm2Tval{my_val:i32}>
!CHECK: fir.has_value %[[V1_INIT]] : !fir.type<_QMm2Tval{my_val:i32}>
!CHECK: }
Loading