mibintc created this revision.
mibintc added reviewers: kpn, sepavloff, andrew.w.kaylor, rjmccall.
Herald added subscribers: dexonsmith, dang.
mibintc requested review of this revision.
Herald added a project: clang.
The Intel compiler supports the option -fp-model={source|double|extended} which
causes the compiler to use a wider type for intermediate floating point
calculations. Also supported is a way to embed this effect in the source
program with #pragma float_control(source|double|extended). This patch
proposes to extend pragma float_control syntax, and also to support a new
floating point option via -ffp-eval-method={source|double|extended}
Note that the C floating point working group has proposed nearly identical
pragma semantics in http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1974.pdf
like this
#pragma STDC FENV_FLT_EVAL_METHOD width
I would like to add support for this also, but it's not in this patch.
I'm going to add an inline question about how to redefine __FLT_EVAL_METHOD__
macro
The ICL option with description of semantics is at this url,
https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/floating-point-options/fp-model-fp.html
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D93769
Files:
clang/docs/LanguageExtensions.rst
clang/docs/UsersManual.rst
clang/include/clang/Basic/FPOptions.def
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Basic/PragmaKinds.h
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/CodeGen/fp-floatcontrol-pragma.cpp
Index: clang/test/CodeGen/fp-floatcontrol-pragma.cpp
===
--- clang/test/CodeGen/fp-floatcontrol-pragma.cpp
+++ clang/test/CodeGen/fp-floatcontrol-pragma.cpp
@@ -2,6 +2,9 @@
// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -fexperimental-strict-floating-point -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-FENV %s
// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple %itanium_abi_triple -O3 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-O3 %s
+// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple x86_64-linux-gnu -emit-llvm -o - %s -ffp-eval-method=source | FileCheck %s -check-prefix=CHECK-SOURCE
+// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple x86_64-linux-gnu -emit-llvm -o - %s -ffp-eval-method=double | FileCheck %s -check-prefix=CHECK-DOUBLE
+// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple x86_64-linux-gnu -emit-llvm -o - %s -ffp-eval-method=extended | FileCheck %s -check-prefix=CHECK-EXTENDED
// Verify float_control(precise, off) enables fast math flags on fp operations.
float fp_precise_1(float a, float b, float c) {
@@ -229,3 +232,45 @@
result = x + t;
return result;
}
+
+float mySub(float x, float y) {
+// CHECK: define float {{.*}}mySub{{.*}}
+// CHECK-NS: fsub float
+// CHECK-SOURCE: fsub float
+// CHECK-DOUBLE: fpext float
+// CHECK-DOUBLE: fpext float
+// CHECK-DOUBLE: fsub double
+// CHECK-DOUBLE: fptrunc double {{.*}} to float
+// CHECK-EXTENDED: fpext float
+// CHECK-EXTENDED: fpext float
+// CHECK-EXTENDED: fsub double
+// CHECK-EXTENDED: fptrunc double {{.*}} to float
+ return x - y;
+}
+
+float mySubSource( float x, float y ) {
+// CHECK: define float {{.*}}mySubSource{{.*}}
+#pragma float_control(source)
+ return x - y;
+// CHECK: fsub float
+}
+
+float mySubExtended( float x, float y ) {
+// CHECK: define float {{.*}}mySubExtended{{.*}}
+#pragma float_control(extended)
+ return x - y;
+// CHECK: fpext float
+// CHECK: fpext float
+// CHECK: fsub x86_fp80
+// CHECK: fptrunc x86_fp80 {{.*}} to float
+}
+
+float mySubDouble( float x, float y ) {
+// CHECK: define float {{.*}}mySubDouble{{.*}}
+#pragma float_control(double)
+ return x - y;
+// CHECK: fpext float
+// CHECK: fpext float
+// CHECK: fsub double
+// CHECK: fptrunc double {{.*}} to float
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -773,6 +773,32 @@
QualType Ty = E->getType();
assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
+ auto EvalMethod = CurFPFeatures.getFPEvalMethod();
+ if (EvalMethod != LangOptions::FEM_Source &&
+ Ty->isFloatingType()) {
+switch (EvalMethod) {
+default:
+ llvm_unreachable("Unrecognized float evaluation method");
+ break;
+case LangOptions::FEM_Double:
+ if (Context.getFloatingTypeOrder(Context.DoubleTy, Ty) >0)
+