Skip to content

Commit 9698e57

Browse files
authored
[flang][Driver] Add support for -f[no-]wrapv and -f[no]-strict-overflow in the frontend (llvm#110061)
This patch introduces the options for integer overflow flags into Flang. The behavior is similar to that of Clang.
1 parent e6a4346 commit 9698e57

File tree

11 files changed

+86
-20
lines changed

11 files changed

+86
-20
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3454,7 +3454,8 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
34543454
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
34553455
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
34563456
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
3457-
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
3457+
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>,
3458+
Visibility<[ClangOption, FlangOption]>;
34583459
def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group<f_Group>;
34593460
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
34603461
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
@@ -3470,7 +3471,8 @@ def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>,
34703471
Visibility<[ClangOption, CC1Option]>,
34713472
MarshallingInfoNegativeFlag<CodeGenOpts<"AsmVerbose">>;
34723473
def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
3473-
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
3474+
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
3475+
Visibility<[ClangOption, FlangOption]>;
34743476
def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>,
34753477
Visibility<[ClangOption, CC1Option]>,
34763478
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
@@ -3966,7 +3968,8 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
39663968
"Enable optimizations based on the strict rules for"
39673969
" overwriting polymorphic C++ objects">,
39683970
NegFlag<SetFalse>>;
3969-
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
3971+
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>,
3972+
Visibility<[ClangOption, FlangOption]>;
39703973
def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group<f_Group>;
39713974
def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
39723975
Visibility<[ClangOption, CLOption, DXCOption]>,
@@ -4235,7 +4238,7 @@ defm virtual_function_elimination : BoolFOption<"virtual-function-elimination",
42354238
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
42364239

42374240
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
4238-
Visibility<[ClangOption, CC1Option]>,
4241+
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
42394242
HelpText<"Treat signed integer overflow as two's complement">;
42404243
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
42414244
Visibility<[ClangOption, CC1Option]>,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6924,16 +6924,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
69246924

69256925
Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
69266926

6927-
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
6928-
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
6929-
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
6930-
if (A->getOption().matches(options::OPT_fwrapv))
6931-
CmdArgs.push_back("-fwrapv");
6932-
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
6933-
options::OPT_fno_strict_overflow)) {
6934-
if (A->getOption().matches(options::OPT_fno_strict_overflow))
6935-
CmdArgs.push_back("-fwrapv");
6936-
}
6927+
// Handle -f[no-]wrapv and -f[no-]strict-overflow, which are used by both
6928+
// clang and flang.
6929+
renderCommonIntegerOverflowOptions(Args, CmdArgs);
69376930

69386931
Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
69396932
options::OPT_fno_finite_loops);

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,3 +3048,17 @@ bool tools::shouldRecordCommandLine(const ToolChain &TC,
30483048

30493049
return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine;
30503050
}
3051+
3052+
void tools::renderCommonIntegerOverflowOptions(const ArgList &Args,
3053+
ArgStringList &CmdArgs) {
3054+
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
3055+
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
3056+
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
3057+
if (A->getOption().matches(options::OPT_fwrapv))
3058+
CmdArgs.push_back("-fwrapv");
3059+
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
3060+
options::OPT_fno_strict_overflow)) {
3061+
if (A->getOption().matches(options::OPT_fno_strict_overflow))
3062+
CmdArgs.push_back("-fwrapv");
3063+
}
3064+
}

clang/lib/Driver/ToolChains/CommonArgs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ bool shouldRecordCommandLine(const ToolChain &TC,
262262
bool &FRecordCommandLine,
263263
bool &GRecordCommandLine);
264264

265+
void renderCommonIntegerOverflowOptions(const llvm::opt::ArgList &Args,
266+
llvm::opt::ArgStringList &CmdArgs);
267+
265268
} // end namespace tools
266269
} // end namespace driver
267270
} // end namespace clang

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
869869
}
870870
}
871871

872+
renderCommonIntegerOverflowOptions(Args, CmdArgs);
873+
872874
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
873875
if (Output.isFilename()) {
874876
CmdArgs.push_back("-o");

flang/include/flang/Common/LangOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ LANGOPT(Name, Bits, Default)
2020
#endif
2121

2222
ENUM_LANGOPT(FPContractMode, FPModeKind, 2, FPM_Fast) ///< FP Contract Mode (off/fast)
23+
/// signed integer overflow handling
24+
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 1, SOB_Undefined)
2325

2426
/// Indicate a build without the standard GPU libraries.
2527
LANGOPT(NoGPULib , 1, false)

flang/include/flang/Common/LangOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ namespace Fortran::common {
2727
class LangOptionsBase {
2828

2929
public:
30+
enum SignedOverflowBehaviorTy {
31+
// -fno-wrapv (default behavior in Flang)
32+
SOB_Undefined,
33+
34+
// -fwrapv
35+
SOB_Defined,
36+
};
37+
3038
enum FPModeKind {
3139
// Do not fuse FP ops
3240
FPM_Off,

flang/include/flang/Lower/LoweringOptions.def

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ ENUM_LOWERINGOPT(NoPPCNativeVecElemOrder, unsigned, 1, 0)
3535
ENUM_LOWERINGOPT(Underscoring, unsigned, 1, 1)
3636

3737
/// If true, assume the behavior of integer overflow is defined
38-
/// (i.e. wraps around as two's complement). On by default.
39-
/// TODO: make the default off
40-
ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 1)
38+
/// (i.e. wraps around as two's complement). Off by default.
39+
ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 0)
4140

4241
/// If true, add nsw flags to loop variable increments.
4342
/// Off by default.

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,24 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
11151115
return diags.getNumErrors() == numErrorsBefore;
11161116
}
11171117

1118+
/// Parses signed integer overflow options and populates the
1119+
/// CompilerInvocation accordingly.
1120+
/// Returns false if new errors are generated.
1121+
///
1122+
/// \param [out] invoc Stores the processed arguments
1123+
/// \param [in] args The compiler invocation arguments to parse
1124+
/// \param [out] diags DiagnosticsEngine to report erros with
1125+
static bool parseIntegerOverflowArgs(CompilerInvocation &invoc,
1126+
llvm::opt::ArgList &args,
1127+
clang::DiagnosticsEngine &diags) {
1128+
Fortran::common::LangOptions &opts = invoc.getLangOpts();
1129+
1130+
if (args.getLastArg(clang::driver::options::OPT_fwrapv))
1131+
opts.setSignedOverflowBehavior(Fortran::common::LangOptions::SOB_Defined);
1132+
1133+
return true;
1134+
}
1135+
11181136
/// Parses all floating point related arguments and populates the
11191137
/// CompilerInvocation accordingly.
11201138
/// Returns false if new errors are generated.
@@ -1255,6 +1273,18 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
12551273
return true;
12561274
}
12571275

1276+
static bool parseLangOptionsArgs(CompilerInvocation &invoc,
1277+
llvm::opt::ArgList &args,
1278+
clang::DiagnosticsEngine &diags) {
1279+
bool success = true;
1280+
1281+
success &= parseIntegerOverflowArgs(invoc, args, diags);
1282+
success &= parseFloatingPointArgs(invoc, args, diags);
1283+
success &= parseVScaleArgs(invoc, args, diags);
1284+
1285+
return success;
1286+
}
1287+
12581288
bool CompilerInvocation::createFromArgs(
12591289
CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs,
12601290
clang::DiagnosticsEngine &diags, const char *argv0) {
@@ -1363,9 +1393,7 @@ bool CompilerInvocation::createFromArgs(
13631393
invoc.frontendOpts.mlirArgs =
13641394
args.getAllArgValues(clang::driver::options::OPT_mmlir);
13651395

1366-
success &= parseFloatingPointArgs(invoc, args, diags);
1367-
1368-
success &= parseVScaleArgs(invoc, args, diags);
1396+
success &= parseLangOptionsArgs(invoc, args, diags);
13691397

13701398
success &= parseLinkerOptionsArgs(invoc, args, diags);
13711399

@@ -1577,6 +1605,8 @@ void CompilerInvocation::setLoweringOptions() {
15771605
loweringOpts.setUnderscoring(codegenOpts.Underscoring);
15781606

15791607
const Fortran::common::LangOptions &langOptions = getLangOpts();
1608+
loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() ==
1609+
Fortran::common::LangOptions::SOB_Defined);
15801610
Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions();
15811611
// TODO: when LangOptions are finalized, we can represent
15821612
// the math related options using Fortran::commmon::MathOptionsBase,

flang/test/Driver/frontend-forwarding.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
! RUN: -fno-signed-zeros \
1515
! RUN: -fassociative-math \
1616
! RUN: -freciprocal-math \
17+
! RUN: -fno-strict-overflow \
1718
! RUN: -fomit-frame-pointer \
1819
! RUN: -fpass-plugin=Bye%pluginext \
1920
! RUN: -fversion-loops-for-stride \
@@ -63,4 +64,5 @@
6364
! CHECK: "-Rpass=inline"
6465
! CHECK: "-mframe-pointer=none"
6566
! CHECK: "-mllvm" "-print-before-all"
67+
! CHECK: "-fwrapv"
6668
! CHECK: "-save-temps=obj"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! Test for correct forwarding of integer overflow flags from the compiler driver
2+
! to the frontend driver
3+
4+
! RUN: %flang -### -fno-strict-overflow %s 2>&1 | FileCheck %s --check-prefix=INDUCED
5+
! RUN: %flang -### -fstrict-overflow %s 2>&1 | FileCheck %s
6+
! RUN: %flang -### -fno-wrapv %s 2>&1 | FileCheck %s
7+
! RUN: %flang -### -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck %s
8+
9+
! CHECK-NOT: "-fno-wrapv"
10+
! INDUCED: "-fwrapv"

0 commit comments

Comments
 (0)