https://github.com/yus3710-fj created https://github.com/llvm/llvm-project/pull/110061
This patch introduces the options for integer overflow flags into Flang. The behavior is similar to that of Clang. >From d3a02bcea0cda96694b79c8b22812c29150c00b1 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/Flang.cpp | 11 ++++++ flang/include/flang/Frontend/LangOptions.def | 2 ++ flang/include/flang/Frontend/LangOptions.h | 8 +++++ flang/include/flang/Lower/LoweringOptions.def | 4 +++ flang/lib/Frontend/CompilerInvocation.cpp | 36 +++++++++++++++++-- flang/test/Driver/integer-overflow.f90 | 10 ++++++ 7 files changed, 75 insertions(+), 7 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 23bd686a85f526..8dfac9088ac7e1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3440,7 +3440,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< @@ -3456,7 +3457,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">; @@ -3952,7 +3954,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]>, @@ -4221,7 +4224,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 6ce79d27e98c48..0205749407b3df 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -872,6 +872,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/Frontend/LangOptions.def b/flang/include/flang/Frontend/LangOptions.def index d3e1e972d1519f..1bfdba9cc2c1c7 100644 --- a/flang/include/flang/Frontend/LangOptions.def +++ b/flang/include/flang/Frontend/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/Frontend/LangOptions.h b/flang/include/flang/Frontend/LangOptions.h index 57d86d46df5ab1..b9cfd387131235 100644 --- a/flang/include/flang/Frontend/LangOptions.h +++ b/flang/include/flang/Frontend/LangOptions.h @@ -27,6 +27,14 @@ namespace Fortran::frontend { 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 7594a57a262914..c8a28566446b9c 100644 --- a/flang/include/flang/Lower/LoweringOptions.def +++ b/flang/include/flang/Lower/LoweringOptions.def @@ -34,6 +34,10 @@ ENUM_LOWERINGOPT(NoPPCNativeVecElemOrder, unsigned, 1, 0) /// On by default. ENUM_LOWERINGOPT(Underscoring, unsigned, 1, 1) +/// If true, assume the behavior of integer overflow is defined +/// (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. ENUM_LOWERINGOPT(NSWOnLoopVarInc, unsigned, 1, 0) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 90c327546198b5..f2bb77958a4ebd 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1100,6 +1100,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) { + LangOptions &opts = invoc.getLangOpts(); + + if (args.getLastArg(clang::driver::options::OPT_fwrapv)) + opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); + + return true; +} + /// Parses all floating point related arguments and populates the /// CompilerInvocation accordingly. /// Returns false if new errors are generated. @@ -1240,6 +1258,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) { @@ -1348,9 +1378,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); @@ -1557,6 +1585,8 @@ void CompilerInvocation::setLoweringOptions() { loweringOpts.setUnderscoring(codegenOpts.Underscoring); const LangOptions &langOptions = getLangOpts(); + loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() == + 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/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" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits