Skip to content

Commit aea2cfa

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 b91a25e commit aea2cfa

File tree

8 files changed

+75
-10
lines changed

8 files changed

+75
-10
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3451,7 +3451,8 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
34513451
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
34523452
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
34533453
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
3454-
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
3454+
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>,
3455+
Visibility<[ClangOption, FlangOption]>;
34553456
def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group<f_Group>;
34563457
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
34573458
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
@@ -3467,7 +3468,8 @@ def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>,
34673468
Visibility<[ClangOption, CC1Option]>,
34683469
MarshallingInfoNegativeFlag<CodeGenOpts<"AsmVerbose">>;
34693470
def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
3470-
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
3471+
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
3472+
Visibility<[ClangOption, FlangOption]>;
34713473
def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>,
34723474
Visibility<[ClangOption, CC1Option]>,
34733475
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
@@ -3963,7 +3965,8 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
39633965
"Enable optimizations based on the strict rules for"
39643966
" overwriting polymorphic C++ objects">,
39653967
NegFlag<SetFalse>>;
3966-
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
3968+
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>,
3969+
Visibility<[ClangOption, FlangOption]>;
39673970
def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group<f_Group>;
39683971
def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
39693972
Visibility<[ClangOption, CLOption, DXCOption]>,
@@ -4232,7 +4235,7 @@ defm virtual_function_elimination : BoolFOption<"virtual-function-elimination",
42324235
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
42334236

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

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,17 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
866866
}
867867
}
868868

869+
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
870+
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
871+
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
872+
if (A->getOption().matches(options::OPT_fwrapv))
873+
CmdArgs.push_back("-fwrapv");
874+
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
875+
options::OPT_fno_strict_overflow)) {
876+
if (A->getOption().matches(options::OPT_fno_strict_overflow))
877+
CmdArgs.push_back("-fwrapv");
878+
}
879+
869880
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
870881
if (Output.isFilename()) {
871882
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
@@ -1109,6 +1109,24 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
11091109
return diags.getNumErrors() == numErrorsBefore;
11101110
}
11111111

1112+
/// Parses signed integer overflow options and populates the
1113+
/// CompilerInvocation accordingly.
1114+
/// Returns false if new errors are generated.
1115+
///
1116+
/// \param [out] invoc Stores the processed arguments
1117+
/// \param [in] args The compiler invocation arguments to parse
1118+
/// \param [out] diags DiagnosticsEngine to report erros with
1119+
static bool parseIntegerOverflowArgs(CompilerInvocation &invoc,
1120+
llvm::opt::ArgList &args,
1121+
clang::DiagnosticsEngine &diags) {
1122+
Fortran::common::LangOptions &opts = invoc.getLangOpts();
1123+
1124+
if (args.getLastArg(clang::driver::options::OPT_fwrapv))
1125+
opts.setSignedOverflowBehavior(Fortran::common::LangOptions::SOB_Defined);
1126+
1127+
return true;
1128+
}
1129+
11121130
/// Parses all floating point related arguments and populates the
11131131
/// CompilerInvocation accordingly.
11141132
/// Returns false if new errors are generated.
@@ -1249,6 +1267,18 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
12491267
return true;
12501268
}
12511269

1270+
static bool parseLangOptionsArgs(CompilerInvocation &invoc,
1271+
llvm::opt::ArgList &args,
1272+
clang::DiagnosticsEngine &diags) {
1273+
bool success = true;
1274+
1275+
success &= parseIntegerOverflowArgs(invoc, args, diags);
1276+
success &= parseFloatingPointArgs(invoc, args, diags);
1277+
success &= parseVScaleArgs(invoc, args, diags);
1278+
1279+
return success;
1280+
}
1281+
12521282
bool CompilerInvocation::createFromArgs(
12531283
CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs,
12541284
clang::DiagnosticsEngine &diags, const char *argv0) {
@@ -1357,9 +1387,7 @@ bool CompilerInvocation::createFromArgs(
13571387
invoc.frontendOpts.mlirArgs =
13581388
args.getAllArgValues(clang::driver::options::OPT_mmlir);
13591389

1360-
success &= parseFloatingPointArgs(invoc, args, diags);
1361-
1362-
success &= parseVScaleArgs(invoc, args, diags);
1390+
success &= parseLangOptionsArgs(invoc, args, diags);
13631391

13641392
success &= parseLinkerOptionsArgs(invoc, args, diags);
13651393

@@ -1571,6 +1599,8 @@ void CompilerInvocation::setLoweringOptions() {
15711599
loweringOpts.setUnderscoring(codegenOpts.Underscoring);
15721600

15731601
const Fortran::common::LangOptions &langOptions = getLangOpts();
1602+
loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() ==
1603+
Fortran::common::LangOptions::SOB_Defined);
15741604
Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions();
15751605
// TODO: when LangOptions are finalized, we can represent
15761606
// 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-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)