[flang-commits] [clang] [flang] [flang][Driver] Add support for -f[no-]wrapv and -f[no]-strict-overflow in the frontend (PR #110061)
Yusuke MINATO via flang-commits
flang-commits at lists.llvm.org
Fri Oct 4 00:09:02 PDT 2024
https://github.com/yus3710-fj updated https://github.com/llvm/llvm-project/pull/110061
>From aea2cfa4b1d812dc84cb1609f93cc2ec2bcd33b4 Mon Sep 17 00:00:00 2001
From: Yusuke MINATO <minato.yusuke at fujitsu.com>
Date: Wed, 18 Sep 2024 21:12:43 +0900
Subject: [PATCH 1/2] [flang][Driver] Add support for -f[no-]wrapv and
-f[no]-strict-overflow in the frontend
This patch introduces the options for integer overflow flags into Flang.
---
clang/include/clang/Driver/Options.td | 11 +++---
clang/lib/Driver/ToolChains/Flang.cpp | 11 ++++++
flang/include/flang/Common/LangOptions.def | 2 ++
flang/include/flang/Common/LangOptions.h | 8 +++++
flang/include/flang/Lower/LoweringOptions.def | 5 ++-
flang/lib/Frontend/CompilerInvocation.cpp | 36 +++++++++++++++++--
flang/test/Driver/frontend-forwarding.f90 | 2 ++
flang/test/Driver/integer-overflow.f90 | 10 ++++++
8 files changed, 75 insertions(+), 10 deletions(-)
create mode 100644 flang/test/Driver/integer-overflow.f90
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9d183ff2d69b3c..4610cd917f685d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3451,7 +3451,8 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
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>;
+def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
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<
@@ -3467,7 +3468,8 @@ def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoNegativeFlag<CodeGenOpts<"AsmVerbose">>;
def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
-def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
+def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
@@ -3963,7 +3965,8 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
"Enable optimizations based on the strict rules for"
" overwriting polymorphic C++ objects">,
NegFlag<SetFalse>>;
-def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
+def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group<f_Group>;
def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption]>,
@@ -4232,7 +4235,7 @@ defm virtual_function_elimination : BoolFOption<"virtual-function-elimination",
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
- Visibility<[ClangOption, CC1Option]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 98350690f8d20e..1865fd57a2d893 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -866,6 +866,17 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
+ // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
+ if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
+ if (A->getOption().matches(options::OPT_fwrapv))
+ CmdArgs.push_back("-fwrapv");
+ } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
+ options::OPT_fno_strict_overflow)) {
+ if (A->getOption().matches(options::OPT_fno_strict_overflow))
+ CmdArgs.push_back("-fwrapv");
+ }
+
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
if (Output.isFilename()) {
CmdArgs.push_back("-o");
diff --git a/flang/include/flang/Common/LangOptions.def b/flang/include/flang/Common/LangOptions.def
index d3e1e972d1519f..1bfdba9cc2c1c7 100644
--- a/flang/include/flang/Common/LangOptions.def
+++ b/flang/include/flang/Common/LangOptions.def
@@ -20,6 +20,8 @@ LANGOPT(Name, Bits, Default)
#endif
ENUM_LANGOPT(FPContractMode, FPModeKind, 2, FPM_Fast) ///< FP Contract Mode (off/fast)
+/// signed integer overflow handling
+ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 1, SOB_Undefined)
/// Indicate a build without the standard GPU libraries.
LANGOPT(NoGPULib , 1, false)
diff --git a/flang/include/flang/Common/LangOptions.h b/flang/include/flang/Common/LangOptions.h
index 52a45047deb0e2..83f25cfbe26142 100644
--- a/flang/include/flang/Common/LangOptions.h
+++ b/flang/include/flang/Common/LangOptions.h
@@ -27,6 +27,14 @@ namespace Fortran::common {
class LangOptionsBase {
public:
+ enum SignedOverflowBehaviorTy {
+ // -fno-wrapv (default behavior in Flang)
+ SOB_Undefined,
+
+ // -fwrapv
+ SOB_Defined,
+ };
+
enum FPModeKind {
// Do not fuse FP ops
FPM_Off,
diff --git a/flang/include/flang/Lower/LoweringOptions.def b/flang/include/flang/Lower/LoweringOptions.def
index d3f17c3f939c16..231de533fbd30a 100644
--- a/flang/include/flang/Lower/LoweringOptions.def
+++ b/flang/include/flang/Lower/LoweringOptions.def
@@ -35,9 +35,8 @@ ENUM_LOWERINGOPT(NoPPCNativeVecElemOrder, unsigned, 1, 0)
ENUM_LOWERINGOPT(Underscoring, unsigned, 1, 1)
/// If true, assume the behavior of integer overflow is defined
-/// (i.e. wraps around as two's complement). On by default.
-/// TODO: make the default off
-ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 1)
+/// (i.e. wraps around as two's complement). Off by default.
+ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 0)
/// If true, add nsw flags to loop variable increments.
/// Off by default.
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 2154b9ab2fbf47..c8160a4236b466 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1109,6 +1109,24 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
return diags.getNumErrors() == numErrorsBefore;
}
+/// Parses signed integer overflow options and populates the
+/// CompilerInvocation accordingly.
+/// Returns false if new errors are generated.
+///
+/// \param [out] invoc Stores the processed arguments
+/// \param [in] args The compiler invocation arguments to parse
+/// \param [out] diags DiagnosticsEngine to report erros with
+static bool parseIntegerOverflowArgs(CompilerInvocation &invoc,
+ llvm::opt::ArgList &args,
+ clang::DiagnosticsEngine &diags) {
+ Fortran::common::LangOptions &opts = invoc.getLangOpts();
+
+ if (args.getLastArg(clang::driver::options::OPT_fwrapv))
+ opts.setSignedOverflowBehavior(Fortran::common::LangOptions::SOB_Defined);
+
+ return true;
+}
+
/// Parses all floating point related arguments and populates the
/// CompilerInvocation accordingly.
/// Returns false if new errors are generated.
@@ -1249,6 +1267,18 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
return true;
}
+static bool parseLangOptionsArgs(CompilerInvocation &invoc,
+ llvm::opt::ArgList &args,
+ clang::DiagnosticsEngine &diags) {
+ bool success = true;
+
+ success &= parseIntegerOverflowArgs(invoc, args, diags);
+ success &= parseFloatingPointArgs(invoc, args, diags);
+ success &= parseVScaleArgs(invoc, args, diags);
+
+ return success;
+}
+
bool CompilerInvocation::createFromArgs(
CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs,
clang::DiagnosticsEngine &diags, const char *argv0) {
@@ -1357,9 +1387,7 @@ bool CompilerInvocation::createFromArgs(
invoc.frontendOpts.mlirArgs =
args.getAllArgValues(clang::driver::options::OPT_mmlir);
- success &= parseFloatingPointArgs(invoc, args, diags);
-
- success &= parseVScaleArgs(invoc, args, diags);
+ success &= parseLangOptionsArgs(invoc, args, diags);
success &= parseLinkerOptionsArgs(invoc, args, diags);
@@ -1571,6 +1599,8 @@ void CompilerInvocation::setLoweringOptions() {
loweringOpts.setUnderscoring(codegenOpts.Underscoring);
const Fortran::common::LangOptions &langOptions = getLangOpts();
+ loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() ==
+ Fortran::common::LangOptions::SOB_Defined);
Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions();
// TODO: when LangOptions are finalized, we can represent
// the math related options using Fortran::commmon::MathOptionsBase,
diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90
index 35adb47b56861e..382c1aa5d350b7 100644
--- a/flang/test/Driver/frontend-forwarding.f90
+++ b/flang/test/Driver/frontend-forwarding.f90
@@ -14,6 +14,7 @@
! RUN: -fno-signed-zeros \
! RUN: -fassociative-math \
! RUN: -freciprocal-math \
+! RUN: -fno-strict-overflow \
! RUN: -fomit-frame-pointer \
! RUN: -fpass-plugin=Bye%pluginext \
! RUN: -fversion-loops-for-stride \
@@ -63,4 +64,5 @@
! CHECK: "-Rpass=inline"
! CHECK: "-mframe-pointer=none"
! CHECK: "-mllvm" "-print-before-all"
+! CHECK: "-fwrapv"
! CHECK: "-save-temps=obj"
diff --git a/flang/test/Driver/integer-overflow.f90 b/flang/test/Driver/integer-overflow.f90
new file mode 100644
index 00000000000000..2cfb36527a30ad
--- /dev/null
+++ b/flang/test/Driver/integer-overflow.f90
@@ -0,0 +1,10 @@
+! Test for correct forwarding of integer overflow flags from the compiler driver
+! to the frontend driver
+
+! RUN: %flang -### -fno-strict-overflow %s 2>&1 | FileCheck %s --check-prefixes CHECK,INDUCED
+! RUN: %flang -### -fstrict-overflow %s 2>&1 | FileCheck %s
+! RUN: %flang -### -fno-wrapv %s 2>&1 | FileCheck %s
+! RUN: %flang -### -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck %s
+
+! CHECK-NOT: "-fno-wrapv"
+! INDUCED: "-fwrapv"
>From c32d6c32e6339840eeddb28f22836b648d0b81f3 Mon Sep 17 00:00:00 2001
From: Yusuke MINATO <minato.yusuke at fujitsu.com>
Date: Fri, 4 Oct 2024 16:04:51 +0900
Subject: [PATCH 2/2] fixup! [flang][Driver] Add support for -f[no-]wrapv and
-f[no]-strict-overflow in the frontend
---
clang/lib/Driver/ToolChains/Clang.cpp | 13 +++----------
clang/lib/Driver/ToolChains/CommonArgs.cpp | 14 ++++++++++++++
clang/lib/Driver/ToolChains/CommonArgs.h | 3 +++
clang/lib/Driver/ToolChains/Flang.cpp | 11 +----------
flang/test/Driver/integer-overflow.f90 | 2 +-
5 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..b04c061f4d9326 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6921,16 +6921,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
- // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
- // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
- if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
- if (A->getOption().matches(options::OPT_fwrapv))
- CmdArgs.push_back("-fwrapv");
- } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
- options::OPT_fno_strict_overflow)) {
- if (A->getOption().matches(options::OPT_fno_strict_overflow))
- CmdArgs.push_back("-fwrapv");
- }
+ // handle -f[no-]wrapv and -f[no-]strict-overflow, which are used by both
+ // clang and flang
+ renderIntegerOverflowOptions(Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
options::OPT_fno_finite_loops);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 0c6a585c3acffd..3baafde387621d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2979,3 +2979,17 @@ void tools::handleColorDiagnosticsArgs(const Driver &D, const ArgList &Args,
if (D.getDiags().getDiagnosticOptions().ShowColors)
CmdArgs.push_back("-fcolor-diagnostics");
}
+
+void tools::renderIntegerOverflowOptions(const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
+ // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
+ if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
+ if (A->getOption().matches(options::OPT_fwrapv))
+ CmdArgs.push_back("-fwrapv");
+ } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
+ options::OPT_fno_strict_overflow)) {
+ if (A->getOption().matches(options::OPT_fno_strict_overflow))
+ CmdArgs.push_back("-fwrapv");
+ }
+}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index eff21b210b4244..08d9d47d189158 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -237,6 +237,9 @@ void addMCModel(const Driver &D, const llvm::opt::ArgList &Args,
void handleColorDiagnosticsArgs(const Driver &D, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
+void renderIntegerOverflowOptions(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs);
+
} // end namespace tools
} // end namespace driver
} // end namespace clang
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 1865fd57a2d893..994e0c0de407de 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -866,16 +866,7 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
- // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
- // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
- if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
- if (A->getOption().matches(options::OPT_fwrapv))
- CmdArgs.push_back("-fwrapv");
- } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
- options::OPT_fno_strict_overflow)) {
- if (A->getOption().matches(options::OPT_fno_strict_overflow))
- CmdArgs.push_back("-fwrapv");
- }
+ renderIntegerOverflowOptions(Args, CmdArgs);
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
if (Output.isFilename()) {
diff --git a/flang/test/Driver/integer-overflow.f90 b/flang/test/Driver/integer-overflow.f90
index 2cfb36527a30ad..023f39fa5413ff 100644
--- a/flang/test/Driver/integer-overflow.f90
+++ b/flang/test/Driver/integer-overflow.f90
@@ -1,7 +1,7 @@
! Test for correct forwarding of integer overflow flags from the compiler driver
! to the frontend driver
-! RUN: %flang -### -fno-strict-overflow %s 2>&1 | FileCheck %s --check-prefixes CHECK,INDUCED
+! RUN: %flang -### -fno-strict-overflow %s 2>&1 | FileCheck %s --check-prefix=INDUCED
! RUN: %flang -### -fstrict-overflow %s 2>&1 | FileCheck %s
! RUN: %flang -### -fno-wrapv %s 2>&1 | FileCheck %s
! RUN: %flang -### -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck %s
More information about the flang-commits
mailing list