zahiraam updated this revision to Diff 418210.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D122155/new/
https://reviews.llvm.org/D122155
Files:
clang/include/clang/Basic/DiagnosticFrontendKinds.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Sema/SemaAttr.cpp
clang/test/Sema/eval-method-with-unsafe-math.c
Index: clang/test/Sema/eval-method-with-unsafe-math.c
===================================================================
--- /dev/null
+++ clang/test/Sema/eval-method-with-unsafe-math.c
@@ -0,0 +1,82 @@
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=WARN-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=WARN-RECPR,WARN-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -mreassociate \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=WARN-REC,WARN-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -fapprox-func \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=WARN-FUNC,WARN-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -verify \
+// RUN: %s 2>&1 | FileCheck %s --check-prefixes=WARN-REC,WARN-RECPR,WARN-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -fapprox-func \
+// RUN: -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=WARN-FUNC,WARN-REC,WARN-RECPR,WARN-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -fapprox-func -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-FUNC
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -mreassociate -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-ASSOC
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-RECPR
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate \
+// RUN: -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -fapprox-func \
+// RUN: -ffp-eval-method=source -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR,CHECK-FUNC
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=WARN-FUNC-OPT,WARN-PRGM
+
+// CHECK-FUNC: (frontend): 'fapprox-func' produces inaccurate arithmetic results. It is illegal when 'ffp-eval-method' is set.
+// CHECK-ASSOC: (frontend): 'mreassociate' produces inaccurate arithmetic results. It is illegal when 'ffp-eval-method' is set.
+// CHECK-RECPR: (frontend): 'freciprocal' produces inaccurate arithmetic results. It is illegal when 'ffp-eval-method' is set.
+
+// expected-no-diagnostics
+
+float f1(float a, float b, float c) {
+ a = b + c;
+ return a * b + c;
+}
+
+float f2(float a, float b, float c) {
+ // WARN-FUNC-OPT: eval method setting via 'option ffp-eval-method' cannot be used with 'pragma_clang_fp_eval_reassociate'
+#pragma clang fp reassociate (on)
+ return (a + b) + c;
+}
+
+float f3(float a, float b, float c) {
+#pragma clang fp reassociate (off)
+ return (a - b) - c;
+}
+
+float f4(float a, float b, float c) {
+#pragma clang fp eval_method (double)
+ // WARN-FUNC: '#pragma clang fp eval_method' cannot be used with 'fapprox_func'
+ // WARN-REC: '#pragma clang fp eval_method' cannot be used with 'mreassociate'
+ // WARN-RECPR: '#pragma clang fp eval_method' cannot be used with 'freciprocal'
+ // WARN-PRGM: eval method setting via '#pragma clang fp eval_method' cannot be used with 'pragma_clang_fp_eval_reassociate'
+#pragma clang fp reassociate (on)
+ return (a * c) - (b * c);
+}
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -486,6 +486,15 @@
NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended);
break;
}
+ if (getLangOpts().ApproxFunc)
+ Diag(Loc, diag::warn_pragma_clang_fp_eval_method_used_with_fapprox_func)
+ << "#pragma clang fp eval_method";
+ if (getLangOpts().AllowFPReassoc)
+ Diag(Loc, diag::warn_pragma_clang_fp_eval_method_used_with_mreassociate)
+ << "#pragma clang fp eval_method";
+ if (getLangOpts().AllowRecip)
+ Diag(Loc, diag::warn_pragma_clang_fp_eval_method_used_with_freciprocal)
+ << "#pragma clang fp eval_method";
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
PP.setCurrentFPEvalMethod(Loc, Value);
@@ -1136,6 +1145,19 @@
}
void Sema::ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled) {
+ if (IsEnabled) {
+ StringRef Reason = "";
+ if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine)
+ Reason = "option ffp-eval-method";
+ // Here we could have both an option and a pragma that set the eval method.
+ // The pragma overrides the option in the command line.
+ if (PP.getLastFPEvalPragmaLocation().isValid())
+ Reason = "#pragma clang fp eval_method";
+ if (Reason != "")
+ Diag(Loc,
+ diag::warn_pragma_clang_fp_reassociate_used_with_eval_method_setting)
+ << Reason;
+ }
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
NewFPFeatures.setAllowFPReassociateOverride(IsEnabled);
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -503,6 +503,25 @@
Diags.Report(diag::warn_ignored_hip_only_option)
<< Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);
+ // When these options are used, the compiler is allowed to apply
+ // optimizations that may affect the final result. For example
+ // (x+y)+z is transformed to x+(y+z) but may not give the same
+ // final result; it's not value safe.
+ // Another example can be to simplify x/x to 1.0 but x could be 0.0, INF
+ // or NaN. Final result may then differ. An error is issued when the eval
+ // method is set with one of these options.
+ if (Args.hasArg(OPT_ffp_eval_method_EQ)) {
+ if (LangOpts.ApproxFunc)
+ Diags.Report(
+ diag::err_incompatible_fp_eval_method_option_with_fapprox_func);
+ if (LangOpts.AllowFPReassoc)
+ Diags.Report(
+ diag::err_incompatible_fp_eval_method_option_with_mreassociate);
+ if (LangOpts.AllowRecip)
+ Diags.Report(
+ diag::err_incompatible_fp_eval_method_option_with_freciprocal);
+ }
+
// -cl-strict-aliasing needs to emit diagnostic in the case where CL > 1.0.
// This option should be deprecated for CL > 1.0 because
// this option was added for compatibility with OpenCL 1.0.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6475,6 +6475,19 @@
"comparing floating point with == or != is unsafe">,
InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
+def warn_pragma_clang_fp_reassociate_used_with_eval_method_setting : Warning<
+ "eval method setting via '%0' cannot be used with "
+ "'pragma_clang_fp_eval_reassociate'">, InGroup<Pragmas>;
+def warn_pragma_clang_fp_eval_method_used_with_fapprox_func : Warning<
+ "'#pragma clang fp eval_method' cannot be used with 'fapprox_func'">,
+ InGroup<Pragmas>;
+def warn_pragma_clang_fp_eval_method_used_with_mreassociate : Warning<
+ "'#pragma clang fp eval_method' cannot be used with 'mreassociate'">,
+ InGroup<Pragmas>;
+def warn_pragma_clang_fp_eval_method_used_with_freciprocal : Warning<
+ "'#pragma clang fp eval_method' cannot be used with 'freciprocal'">,
+ InGroup<Pragmas>;
+
def warn_remainder_division_by_zero : Warning<
"%select{remainder|division}0 by zero is undefined">,
InGroup<DivZero>;
Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -48,6 +48,16 @@
"overriding currently unsupported use of floating point exceptions "
"on this target">, InGroup<UnsupportedFPOpt>;
+def err_incompatible_fp_eval_method_option_with_fapprox_func : Error<
+ "'fapprox-func' produces inaccurate arithmetic results. It is illegal when"
+ " 'ffp-eval-method' is set.">;
+def err_incompatible_fp_eval_method_option_with_mreassociate : Error<
+ "'mreassociate' produces inaccurate arithmetic results. It is illegal when"
+ " 'ffp-eval-method' is set.">;
+def err_incompatible_fp_eval_method_option_with_freciprocal : Error<
+ "'freciprocal' produces inaccurate arithmetic results. It is illegal when"
+ " 'ffp-eval-method' is set.">;
+
def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
InGroup<BackendOptimizationRemark>;
def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits