Skip to content

Commit d3a02bc

Browse files
committed
[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.
1 parent f43ad88 commit d3a02bc

File tree

7 files changed

+75
-7
lines changed

7 files changed

+75
-7
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3440,7 +3440,8 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
34403440
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
34413441
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
34423442
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
3443-
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
3443+
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>,
3444+
Visibility<[ClangOption, FlangOption]>;
34443445
def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group<f_Group>;
34453446
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
34463447
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
@@ -3456,7 +3457,8 @@ def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>,
34563457
Visibility<[ClangOption, CC1Option]>,
34573458
MarshallingInfoNegativeFlag<CodeGenOpts<"AsmVerbose">>;
34583459
def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
3459-
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
3460+
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
3461+
Visibility<[ClangOption, FlangOption]>;
34603462
def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>,
34613463
Visibility<[ClangOption, CC1Option]>,
34623464
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
@@ -3952,7 +3954,8 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
39523954
"Enable optimizations based on the strict rules for"
39533955
" overwriting polymorphic C++ objects">,
39543956
NegFlag<SetFalse>>;
3955-
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
3957+
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>,
3958+
Visibility<[ClangOption, FlangOption]>;
39563959
def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group<f_Group>;
39573960
def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
39583961
Visibility<[ClangOption, CLOption, DXCOption]>,
@@ -4221,7 +4224,7 @@ defm virtual_function_elimination : BoolFOption<"virtual-function-elimination",
42214224
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
42224225

42234226
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
4224-
Visibility<[ClangOption, CC1Option]>,
4227+
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
42254228
HelpText<"Treat signed integer overflow as two's complement">;
42264229
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
42274230
Visibility<[ClangOption, CC1Option]>,

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,17 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
872872
}
873873
}
874874

875+
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
876+
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
877+
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
878+
if (A->getOption().matches(options::OPT_fwrapv))
879+
CmdArgs.push_back("-fwrapv");
880+
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
881+
options::OPT_fno_strict_overflow)) {
882+
if (A->getOption().matches(options::OPT_fno_strict_overflow))
883+
CmdArgs.push_back("-fwrapv");
884+
}
885+
875886
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
876887
if (Output.isFilename()) {
877888
CmdArgs.push_back("-o");

flang/include/flang/Frontend/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/Frontend/LangOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ namespace Fortran::frontend {
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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ ENUM_LOWERINGOPT(NoPPCNativeVecElemOrder, unsigned, 1, 0)
3434
/// On by default.
3535
ENUM_LOWERINGOPT(Underscoring, unsigned, 1, 1)
3636

37+
/// If true, assume the behavior of integer overflow is defined
38+
/// (i.e. wraps around as two's complement). Off by default.
39+
ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 0)
40+
3741
/// If true, add nsw flags to loop variable increments.
3842
/// Off by default.
3943
ENUM_LOWERINGOPT(NSWOnLoopVarInc, unsigned, 1, 0)

flang/lib/Frontend/CompilerInvocation.cpp

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

1103+
/// Parses signed integer overflow options and populates the
1104+
/// CompilerInvocation accordingly.
1105+
/// Returns false if new errors are generated.
1106+
///
1107+
/// \param [out] invoc Stores the processed arguments
1108+
/// \param [in] args The compiler invocation arguments to parse
1109+
/// \param [out] diags DiagnosticsEngine to report erros with
1110+
static bool parseIntegerOverflowArgs(CompilerInvocation &invoc,
1111+
llvm::opt::ArgList &args,
1112+
clang::DiagnosticsEngine &diags) {
1113+
LangOptions &opts = invoc.getLangOpts();
1114+
1115+
if (args.getLastArg(clang::driver::options::OPT_fwrapv))
1116+
opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
1117+
1118+
return true;
1119+
}
1120+
11031121
/// Parses all floating point related arguments and populates the
11041122
/// CompilerInvocation accordingly.
11051123
/// Returns false if new errors are generated.
@@ -1240,6 +1258,18 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
12401258
return true;
12411259
}
12421260

1261+
static bool parseLangOptionsArgs(CompilerInvocation &invoc,
1262+
llvm::opt::ArgList &args,
1263+
clang::DiagnosticsEngine &diags) {
1264+
bool success = true;
1265+
1266+
success &= parseIntegerOverflowArgs(invoc, args, diags);
1267+
success &= parseFloatingPointArgs(invoc, args, diags);
1268+
success &= parseVScaleArgs(invoc, args, diags);
1269+
1270+
return success;
1271+
}
1272+
12431273
bool CompilerInvocation::createFromArgs(
12441274
CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs,
12451275
clang::DiagnosticsEngine &diags, const char *argv0) {
@@ -1348,9 +1378,7 @@ bool CompilerInvocation::createFromArgs(
13481378
invoc.frontendOpts.mlirArgs =
13491379
args.getAllArgValues(clang::driver::options::OPT_mmlir);
13501380

1351-
success &= parseFloatingPointArgs(invoc, args, diags);
1352-
1353-
success &= parseVScaleArgs(invoc, args, diags);
1381+
success &= parseLangOptionsArgs(invoc, args, diags);
13541382

13551383
success &= parseLinkerOptionsArgs(invoc, args, diags);
13561384

@@ -1557,6 +1585,8 @@ void CompilerInvocation::setLoweringOptions() {
15571585
loweringOpts.setUnderscoring(codegenOpts.Underscoring);
15581586

15591587
const LangOptions &langOptions = getLangOpts();
1588+
loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() ==
1589+
LangOptions::SOB_Defined);
15601590
Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions();
15611591
// TODO: when LangOptions are finalized, we can represent
15621592
// the math related options using Fortran::commmon::MathOptionsBase,
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-prefixes CHECK,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)