https://github.com/yus3710-fj updated https://github.com/llvm/llvm-project/pull/110061
>From 6215099ca7da009e98eca138590f78a5e524a1e9 Mon Sep 17 00:00:00 2001 From: Yusuke MINATO <minato.yus...@fujitsu.com> Date: Wed, 18 Sep 2024 21:12:43 +0900 Subject: [PATCH] [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/Clang.cpp | 13 ++----- clang/lib/Driver/ToolChains/CommonArgs.cpp | 14 ++++++++ clang/lib/Driver/ToolChains/CommonArgs.h | 3 ++ clang/lib/Driver/ToolChains/Flang.cpp | 2 ++ 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 ++++++ 11 files changed, 86 insertions(+), 20 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 379e75b197cf96..c15b1fdfbbd3e2 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3454,7 +3454,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< @@ -3470,7 +3471,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">; @@ -3966,7 +3968,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]>, @@ -4235,7 +4238,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/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3fc39296f44281..905b9b4983c1df 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6914,16 +6914,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. + renderCommonIntegerOverflowOptions(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 e662c3f0d2fa8f..91605a67a37fc0 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -3048,3 +3048,17 @@ bool tools::shouldRecordCommandLine(const ToolChain &TC, return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine; } + +void tools::renderCommonIntegerOverflowOptions(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 9cafac2538862a..b6ddd99b872798 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -262,6 +262,9 @@ bool shouldRecordCommandLine(const ToolChain &TC, bool &FRecordCommandLine, bool &GRecordCommandLine); +void renderCommonIntegerOverflowOptions(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 e2f8f6e0cca1c6..a9d2b7a4dc48f9 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -869,6 +869,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, } } + renderCommonIntegerOverflowOptions(Args, CmdArgs); + 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 4607a33ffda6cc..94d3d115417877 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1115,6 +1115,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. @@ -1255,6 +1273,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) { @@ -1363,9 +1393,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); @@ -1577,6 +1605,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 0a56a1e3710d9d..ff2d6609521464 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..023f39fa5413ff --- /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-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 + +! CHECK-NOT: "-fno-wrapv" +! INDUCED: "-fwrapv" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits