Skip to content

Commit 8ed0841

Browse files
committed
[Flang] Add -ffast-real-mod back for further control of MOD optimizations
1 parent 92e2404 commit 8ed0841

File tree

8 files changed

+65
-57
lines changed

8 files changed

+65
-57
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,6 +2778,9 @@ def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">
27782778
Group<f_Group>;
27792779
def fassociative_math : Flag<["-"], "fassociative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>;
27802780
def fno_associative_math : Flag<["-"], "fno-associative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>;
2781+
def ffast_real_mod : Flag<["-"], "ffast-real-mod">,
2782+
Group<f_Group>, Visibility<[FlangOption, FC1Option]>,
2783+
HelpText<"Enable optimization of MOD for REAL types">;
27812784
def fno_fast_real_mod : Flag<["-"], "fno-fast-real-mod">,
27822785
Group<f_Group>, Visibility<[FlangOption, FC1Option]>,
27832786
HelpText<"Disable optimization of MOD for REAL types in presence of -ffast-math">;

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,8 @@ static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
822822
complexRangeKindToStr(Range)));
823823
}
824824

825+
if (Args.hasArg(options::OPT_ffast_real_mod))
826+
CmdArgs.push_back("-ffast-real-mod");
825827
if (Args.hasArg(options::OPT_fno_fast_real_mod))
826828
CmdArgs.push_back("-fno-fast-real-mod");
827829

flang/include/flang/Support/LangOptions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ LANGOPT(OpenMPNoNestedParallelism, 1, 0)
6161
/// Use SIMD only OpenMP support.
6262
LANGOPT(OpenMPSimd, 1, false)
6363
/// Enable fast MOD operations for REAL
64-
LANGOPT(NoFastRealMod, 1, false)
64+
LANGOPT(FastRealMod, 1, false)
6565
LANGOPT(VScaleMin, 32, 0) ///< Minimum vscale range value
6666
LANGOPT(VScaleMax, 32, 0) ///< Maximum vscale range value
6767

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,11 +1428,14 @@ static bool parseFloatingPointArgs(CompilerInvocation &invoc,
14281428
opts.ReciprocalMath = true;
14291429
opts.ApproxFunc = true;
14301430
opts.NoSignedZeros = true;
1431+
opts.FastRealMod = true;
14311432
opts.setFPContractMode(Fortran::common::LangOptions::FPM_Fast);
14321433
}
14331434

1435+
if (args.hasArg(clang::driver::options::OPT_ffast_real_mod))
1436+
opts.FastRealMod = true;
14341437
if (args.hasArg(clang::driver::options::OPT_fno_fast_real_mod))
1435-
opts.NoFastRealMod = true;
1438+
opts.FastRealMod = false;
14361439

14371440
return true;
14381441
}

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ bool CodeGenAction::beginSourceFileAction() {
277277
ci.getInvocation().getLangOpts().OpenMPVersion);
278278
}
279279

280-
if (ci.getInvocation().getLangOpts().NoFastRealMod) {
280+
if (ci.getInvocation().getLangOpts().FastRealMod) {
281281
mlir::ModuleOp mod = lb.getModule();
282282
mod.getOperation()->setAttr(
283283
mlir::StringAttr::get(mod.getContext(),
284-
llvm::Twine{"fir.no_fast_real_mod"}),
284+
llvm::Twine{"fir.fast_real_mod"}),
285285
mlir::BoolAttr::get(mod.getContext(), true));
286286
}
287287

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6509,11 +6509,9 @@ static mlir::Value genFastMod(fir::FirOpBuilder &builder, mlir::Location loc,
65096509
mlir::Value IntrinsicLibrary::genMod(mlir::Type resultType,
65106510
llvm::ArrayRef<mlir::Value> args) {
65116511
auto mod = builder.getModule();
6512-
bool dontUseFastRealMod = false;
6513-
bool canUseApprox = mlir::arith::bitEnumContainsAny(
6514-
builder.getFastMathFlags(), mlir::arith::FastMathFlags::afn);
6515-
if (auto attr = mod->getAttrOfType<mlir::BoolAttr>("fir.no_fast_real_mod"))
6516-
dontUseFastRealMod = attr.getValue();
6512+
bool useFastRealMod = false;
6513+
if (auto attr = mod->getAttrOfType<mlir::BoolAttr>("fir.fast_real_mod"))
6514+
useFastRealMod = attr.getValue();
65176515

65186516
assert(args.size() == 2);
65196517
if (resultType.isUnsignedInteger()) {
@@ -6526,7 +6524,7 @@ mlir::Value IntrinsicLibrary::genMod(mlir::Type resultType,
65266524
if (mlir::isa<mlir::IntegerType>(resultType))
65276525
return mlir::arith::RemSIOp::create(builder, loc, args[0], args[1]);
65286526

6529-
if (resultType.isFloat() && canUseApprox && !dontUseFastRealMod) {
6527+
if (resultType.isFloat() && useFastRealMod) {
65306528
// Treat MOD as an approximate function and code-gen inline code
65316529
// instead of calling into the Fortran runtime library.
65326530
return builder.createConvert(loc, resultType,

flang/test/Driver/fast-real-mod.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
! RUN: %flang -ffast-real-mod -### -c %s 2>&1 | FileCheck %s -check-prefix CHECK-FAST-REAL-MOD
12
! RUN: %flang -fno-fast-real-mod -### -c %s 2>&1 | FileCheck %s -check-prefix CHECK-NO-FAST-REAL-MOD
23

4+
! CHECK-FAST-REAL-MOD: "-ffast-real-mod"
35
! CHECK-NO-FAST-REAL-MOD: "-fno-fast-real-mod"
46

57
program test
Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
! RUN: %flang_fc1 -ffast-math -emit-mlir -o - %s | FileCheck %s --check-prefixes=CHECK%if target=x86_64{{.*}} %{,CHECK-KIND10%}%if flang-supports-f128-math %{,CHECK-KIND16%}
1+
! RUN: %flang_fc1 -ffast-real-mod -emit-mlir -o - %s | FileCheck %s --check-prefixes=CHECK-FRM%if target=x86_64{{.*}} %{,CHECK-FRM-KIND10%}%if flang-supports-f128-math %{,CHECK-FRM-KIND16%}
2+
! RUN: %flang_fc1 -ffast-math -emit-mlir -o - %s | FileCheck %s --check-prefixes=CHECK-FRM%if target=x86_64{{.*}} %{,CHECK-FRM-KIND10%}%if flang-supports-f128-math %{,CHECK-FRM-KIND16%}
23
! RUN: %flang_fc1 -ffast-math -fno-fast-real-mod -emit-mlir -o - %s | FileCheck %s --check-prefixes=CHECK-NFRM%if target=x86_64{{.*}} %{,CHECK-NFRM-KIND10%}%if flang-supports-f128-math %{,CHECK-NFRM-KIND16%}
34

4-
! TODO: check line that fir.fast_real_mod is not there
5-
! CHECK-NFRM: module attributes {{{.*}}fir.no_fast_real_mod = true{{.*}}}
5+
! CHECK,CHECK-FRM: module attributes {{{.*}}fir.fast_real_mod = true{{.*}}}
66

77
! CHECK-LABEL: @_QPmod_real4
88
subroutine mod_real4(r, a, p)
99
implicit none
1010
real(kind=4) :: r, a, p
11-
! CHECK: %[[A:.*]] = fir.declare{{.*}}a"
12-
! CHECK: %[[P:.*]] = fir.declare{{.*}}p"
13-
! CHECK: %[[R:.*]] = fir.declare{{.*}}r"
14-
! CHECK: %[[A_LOAD:.*]] = fir.load %[[A]]
15-
! CHECK: %[[P_LOAD:.*]] = fir.load %[[P]]
16-
! CHECK: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<fast> : f32
17-
! CHECK: %[[CV1:.*]] = fir.convert %[[DIV]] : (f32) -> si32
18-
! CHECK: %[[CV2:.*]] = fir.convert %[[CV1]] : (si32) -> f32
19-
! CHECK: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<fast> : f32
20-
! CHECK: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<fast> : f32
21-
! CHECK: fir.store %[[SUB]] to %[[R]] : !fir.ref<f32>
11+
! CHECK-FRM: %[[A:.*]] = fir.declare{{.*}}a"
12+
! CHECK-FRM: %[[P:.*]] = fir.declare{{.*}}p"
13+
! CHECK-FRM: %[[R:.*]] = fir.declare{{.*}}r"
14+
! CHECK-FRM: %[[A_LOAD:.*]] = fir.load %[[A]]
15+
! CHECK-FRM: %[[P_LOAD:.*]] = fir.load %[[P]]
16+
! CHECK-FRM: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<{{.*}}> : f32
17+
! CHECK-FRM: %[[CV1:.*]] = fir.convert %[[DIV]] : (f32) -> si32
18+
! CHECK-FRM: %[[CV2:.*]] = fir.convert %[[CV1]] : (si32) -> f32
19+
! CHECK-FRM: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<{{.*}}> : f32
20+
! CHECK-FRM: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<{{.*}}> : f32
21+
! CHECK-FRM: fir.store %[[SUB]] to %[[R]] : !fir.ref<f32>
2222
! CHECK-NFRM: fir.call @_FortranAModReal4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (f32, f32, !fir.ref<i8>, i32) -> f32
2323
r = mod(a, p)
2424
end subroutine mod_real4
@@ -27,17 +27,17 @@ end subroutine mod_real4
2727
subroutine mod_real8(r, a, p)
2828
implicit none
2929
real(kind=8) :: r, a, p
30-
! CHECK: %[[A:.*]] = fir.declare{{.*}}a"
31-
! CHECK: %[[P:.*]] = fir.declare{{.*}}p"
32-
! CHECK: %[[R:.*]] = fir.declare{{.*}}r"
33-
! CHECK: %[[A_LOAD:.*]] = fir.load %[[A]]
34-
! CHECK: %[[P_LOAD:.*]] = fir.load %[[P]]
35-
! CHECK: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<fast> : f64
36-
! CHECK: %[[CV1:.*]] = fir.convert %[[DIV]] : (f64) -> si64
37-
! CHECK: %[[CV2:.*]] = fir.convert %[[CV1]] : (si64) -> f64
38-
! CHECK: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<fast> : f64
39-
! CHECK: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<fast> : f64
40-
! CHECK: fir.store %[[SUB]] to %[[R]] : !fir.ref<f64>
30+
! CHECK-FRM: %[[A:.*]] = fir.declare{{.*}}a"
31+
! CHECK-FRM: %[[P:.*]] = fir.declare{{.*}}p"
32+
! CHECK-FRM: %[[R:.*]] = fir.declare{{.*}}r"
33+
! CHECK-FRM: %[[A_LOAD:.*]] = fir.load %[[A]]
34+
! CHECK-FRM: %[[P_LOAD:.*]] = fir.load %[[P]]
35+
! CHECK-FRM: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<{{.*}}> : f64
36+
! CHECK-FRM: %[[CV1:.*]] = fir.convert %[[DIV]] : (f64) -> si64
37+
! CHECK-FRM: %[[CV2:.*]] = fir.convert %[[CV1]] : (si64) -> f64
38+
! CHECK-FRM: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<{{.*}}> : f64
39+
! CHECK-FRM: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<{{.*}}> : f64
40+
! CHECK-FRM: fir.store %[[SUB]] to %[[R]] : !fir.ref<f64>
4141
! CHECK-NFRM: fir.call @_FortranAModReal8(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (f64, f64, !fir.ref<i8>, i32) -> f64
4242
r = mod(a, p)
4343
end subroutine mod_real8
@@ -47,17 +47,17 @@ subroutine mod_real10(r, a, p)
4747
implicit none
4848
integer, parameter :: kind10 = merge(10, 4, selected_real_kind(p=18).eq.10)
4949
real(kind=kind10) :: r, a, p
50-
! CHECK-KIND10: %[[A:.*]] = fir.declare{{.*}}a"
51-
! CHECK-KIND10: %[[P:.*]] = fir.declare{{.*}}p"
52-
! CHECK-KIND10: %[[R:.*]] = fir.declare{{.*}}r"
53-
! CHECK-KIND10: %[[A_LOAD:.*]] = fir.load %[[A]]
54-
! CHECK-KIND10: %[[P_LOAD:.*]] = fir.load %[[P]]
55-
! CHECK-KIND10: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<fast> : f80
56-
! CHECK-KIND10: %[[CV1:.*]] = fir.convert %[[DIV]] : (f80) -> si80
57-
! CHECK-KIND10: %[[CV2:.*]] = fir.convert %[[CV1]] : (si80) -> f80
58-
! CHECK-KIND10: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<fast> : f80
59-
! CHECK-KIND10: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<fast> : f80
60-
! CHECK-KIND10: fir.store %[[SUB]] to %[[R]] : !fir.ref<f80>
50+
! CHECK-FRM-KIND10: %[[A:.*]] = fir.declare{{.*}}a"
51+
! CHECK-FRM-KIND10: %[[P:.*]] = fir.declare{{.*}}p"
52+
! CHECK-FRM-KIND10: %[[R:.*]] = fir.declare{{.*}}r"
53+
! CHECK-FRM-KIND10: %[[A_LOAD:.*]] = fir.load %[[A]]
54+
! CHECK-FRM-KIND10: %[[P_LOAD:.*]] = fir.load %[[P]]
55+
! CHECK-FRM-KIND10: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<{{.*}}> : f80
56+
! CHECK-FRM-KIND10: %[[CV1:.*]] = fir.convert %[[DIV]] : (f80) -> si80
57+
! CHECK-FRM-KIND10: %[[CV2:.*]] = fir.convert %[[CV1]] : (si80) -> f80
58+
! CHECK-FRM-KIND10: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<{{.*}}> : f80
59+
! CHECK-FRM-KIND10: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<{{.*}}> : f80
60+
! CHECK-FRM-KIND10: fir.store %[[SUB]] to %[[R]] : !fir.ref<f80>
6161
! CHECK-NFRM-KIND10: fir.call @_FortranAModReal10(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (f80, f80, !fir.ref<i8>, i32) -> f80
6262
r = mod(a, p)
6363
end subroutine mod_real10
@@ -67,17 +67,17 @@ subroutine mod_real16(r, a, p)
6767
implicit none
6868
integer, parameter :: kind16 = merge(16, 4, selected_real_kind(p=33).eq.16)
6969
real(kind=kind16) :: r, a, p
70-
! CHECK-KIND16: %[[A:.*]] = fir.declare{{.*}}a"
71-
! CHECK-KIND16: %[[P:.*]] = fir.declare{{.*}}p"
72-
! CHECK-KIND16: %[[R:.*]] = fir.declare{{.*}}r"
73-
! CHECK-KIND16: %[[A_LOAD:.*]] = fir.load %[[A]]
74-
! CHECK-KIND16: %[[P_LOAD:.*]] = fir.load %[[P]]
75-
! CHECK-KIND16: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<fast> : f128
76-
! CHECK-KIND16: %[[CV1:.*]] = fir.convert %[[DIV]] : (f128) -> si128
77-
! CHECK-KIND16: %[[CV2:.*]] = fir.convert %[[CV1]] : (si128) -> f128
78-
! CHECK-KIND16: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<fast> : f128
79-
! CHECK-KIND16: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<fast> : f128
80-
! CHECK-KIND16: fir.store %[[SUB]] to %[[R]] : !fir.ref<f128>
70+
! CHECK-FRM-KIND16: %[[A:.*]] = fir.declare{{.*}}a"
71+
! CHECK-FRM-KIND16: %[[P:.*]] = fir.declare{{.*}}p"
72+
! CHECK-FRM-KIND16: %[[R:.*]] = fir.declare{{.*}}r"
73+
! CHECK-FRM-KIND16: %[[A_LOAD:.*]] = fir.load %[[A]]
74+
! CHECK-FRM-KIND16: %[[P_LOAD:.*]] = fir.load %[[P]]
75+
! CHECK-FRM-KIND16: %[[DIV:.*]] = arith.divf %[[A_LOAD]], %[[P_LOAD]] fastmath<{{.*}}> : f128
76+
! CHECK-FRM-KIND16: %[[CV1:.*]] = fir.convert %[[DIV]] : (f128) -> si128
77+
! CHECK-FRM-KIND16: %[[CV2:.*]] = fir.convert %[[CV1]] : (si128) -> f128
78+
! CHECK-FRM-KIND16: %[[MUL:.*]] = arith.mulf %[[CV2]], %[[P_LOAD]] fastmath<{{.*}}> : f128
79+
! CHECK-FRM-KIND16: %[[SUB:.*]] = arith.subf %[[A_LOAD]], %[[MUL]] fastmath<{{.*}}> : f128
80+
! CHECK-FRM-KIND16: fir.store %[[SUB]] to %[[R]] : !fir.ref<f128>
8181
! CHECK-NFRM-KIND16: fir.call @_FortranAModReal16(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (f128, f128, !fir.ref<i8>, i32) -> f128
8282
r = mod(a, p)
8383
end subroutine mod_real16

0 commit comments

Comments
 (0)