diff --git a/flang/include/flang/Common/MathOptionsBase.def b/flang/include/flang/Common/MathOptionsBase.def --- a/flang/include/flang/Common/MathOptionsBase.def +++ b/flang/include/flang/Common/MathOptionsBase.def @@ -22,4 +22,20 @@ /// Permit floating point optimizations without regard to infinities. ENUM_MATHOPT(NoHonorInfs, unsigned, 1, 0) +/// Permit floating point optimization without regard to NaN +ENUM_MATHOPT(NoHonorNaNs, unsigned, 1, 0) + +/// Allow math functions to be replaced with an approximately equivalent +/// calculation +ENUM_MATHOPT(ApproxFunc, unsigned, 1, 0) + +/// Allow optimizations that ignore the sign of floating point zeros +ENUM_MATHOPT(NoSignedZeros, unsigned, 1, 0) + +/// Allow reassociation transformations for floating-point instructions +ENUM_MATHOPT(AssociativeMath, unsigned, 1, 0) + +/// Allow division operations to be reassociated +ENUM_MATHOPT(ReciprocalMath, unsigned, 1, 0) + #undef ENUM_MATHOPT diff --git a/flang/include/flang/Frontend/LangOptions.def b/flang/include/flang/Frontend/LangOptions.def --- a/flang/include/flang/Frontend/LangOptions.def +++ b/flang/include/flang/Frontend/LangOptions.def @@ -25,7 +25,8 @@ LANGOPT(NoHonorInfs, 1, false) /// Permit floating point optimization without regard to NaN LANGOPT(NoHonorNaNs, 1, false) -/// Allow math functions to be replaced with an approximately equivalent calculation +/// Allow math functions to be replaced with an approximately equivalent +/// calculation LANGOPT(ApproxFunc, 1, false) /// Allow optimizations that ignore the sign of floating point zeros LANGOPT(NoSignedZeros, 1, false) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -957,5 +957,10 @@ mathOpts .setFPContractEnabled(langOptions.getFPContractMode() == LangOptions::FPM_Fast) - .setNoHonorInfs(langOptions.NoHonorInfs); + .setNoHonorInfs(langOptions.NoHonorInfs) + .setNoHonorNaNs(langOptions.NoHonorNaNs) + .setApproxFunc(langOptions.ApproxFunc) + .setNoSignedZeros(langOptions.NoSignedZeros) + .setAssociativeMath(langOptions.AssociativeMath) + .setReciprocalMath(langOptions.ReciprocalMath); } diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -592,6 +592,21 @@ if (options.getNoHonorInfs()) { arithFMF = arithFMF | mlir::arith::FastMathFlags::ninf; } + if (options.getNoHonorNaNs()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::nnan; + } + if (options.getApproxFunc()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::afn; + } + if (options.getNoSignedZeros()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::nsz; + } + if (options.getAssociativeMath()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::reassoc; + } + if (options.getReciprocalMath()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::arcp; + } setFastMathFlags(arithFMF); } diff --git a/flang/test/Lower/fast-math-arithmetic.f90 b/flang/test/Lower/fast-math-arithmetic.f90 --- a/flang/test/Lower/fast-math-arithmetic.f90 +++ b/flang/test/Lower/fast-math-arithmetic.f90 @@ -1,11 +1,23 @@ ! RUN: %flang_fc1 -emit-fir -ffp-contract=fast %s -o - 2>&1 | FileCheck --check-prefixes=CONTRACT,ALL %s ! RUN: %flang_fc1 -emit-fir -menable-no-infs %s -o - 2>&1 | FileCheck --check-prefixes=NINF,ALL %s +! RUN: %flang_fc1 -emit-fir -menable-no-nans %s -o - 2>&1 | FileCheck --check-prefixes=NNAN,ALL %s +! RUN: %flang_fc1 -emit-fir -fapprox-func %s -o - 2>&1 | FileCheck --check-prefixes=AFN,ALL %s +! RUN: %flang_fc1 -emit-fir -fno-signed-zeros %s -o - 2>&1 | FileCheck --check-prefixes=NSZ,ALL %s +! RUN: %flang_fc1 -emit-fir -mreassociate %s -o - 2>&1 | FileCheck --check-prefixes=REASSOC,ALL %s +! RUN: %flang_fc1 -emit-fir -freciprocal-math %s -o - 2>&1 | FileCheck --check-prefixes=ARCP,ALL %s +! RUN: %flang_fc1 -emit-fir -ffp-contract=fast -menable-no-infs -menable-no-nans -fapprox-func -fno-signed-zeros -mreassociate -freciprocal-math %s -o - 2>&1 | FileCheck --check-prefixes=FAST,ALL %s ! ALL-LABEL: func.func @_QPtest subroutine test(x) real x ! CONTRACT: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:contract]]> : f32 ! NINF: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:ninf]]> : f32 +! NNAN: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:nnan]]> : f32 +! AFN: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:afn]]> : f32 +! NSZ: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:nsz]]> : f32 +! REASSOC: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:reassoc]]> : f32 +! ARCP: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:arcp]]> : f32 +! FAST: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:fast]]> : f32 ! ALL: arith.divf{{.*}}, {{.*}} fastmath<[[ATTRS]]> : f32 ! ALL: arith.addf{{.*}}, {{.*}} fastmath<[[ATTRS]]> : f32 ! ALL: arith.subf{{.*}}, {{.*}} fastmath<[[ATTRS]]> : f32