[clang] 7b8e306 - [clang] Fix bug in #pragma float_control(push/pop)

Melanie Blower via cfe-commits cfe-commits at lists.llvm.org
Thu May 14 05:58:27 PDT 2020


Author: Melanie Blower
Date: 2020-05-14T05:58:11-07:00
New Revision: 7b8e3065606cb555e7528e3b59d5e164ecf008fa

URL: https://github.com/llvm/llvm-project/commit/7b8e3065606cb555e7528e3b59d5e164ecf008fa
DIFF: https://github.com/llvm/llvm-project/commit/7b8e3065606cb555e7528e3b59d5e164ecf008fa.diff

LOG: [clang] Fix bug in #pragma float_control(push/pop)

Summary: #pragma float_control(pop) was failing to restore the expected
floating point settings because the settings were not correctly preserved
at #pragma float_control(push).

Added: 
    

Modified: 
    clang/lib/Sema/SemaAttr.cpp
    clang/test/CodeGen/fp-floatcontrol-pragma.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 222aaf3049ae..977e92475182 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -457,8 +457,12 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
     FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
     break;
   case PFC_Push:
-    Action = Sema::PSK_Push_Set;
-    FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt());
+    if (FpPragmaStack.Stack.empty()) {
+      FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(),
+                        CurFPFeatures.getAsOpaqueInt());
+    }
+    FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(),
+                      NewFPFeatures.getAsOpaqueInt());
     break;
   case PFC_Pop:
     if (FpPragmaStack.Stack.empty()) {

diff  --git a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
index a80a4d377660..ca3a3a46aab2 100644
--- a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
+++ b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
@@ -1,6 +1,68 @@
 // RUN: %clang_cc1 -DEXCEPT=1 -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NS %s
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -verify -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -O3 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-O3 %s
+
+// Verify float_control(precise, off) enables fast math flags on fp operations.
+float fp_precise_1(float a, float b, float c) {
+// CHECK-O3: _Z12fp_precise_1fff
+// CHECK-O3: %[[M:.+]] = fmul fast float{{.*}}
+// CHECK-O3: fadd fast float %[[M]], %c
+#pragma float_control(precise, off)
+  return a * b + c;
+}
+
+// Is float_control state cleared on exiting compound statements?
+float fp_precise_2(float a, float b, float c) {
+  // CHECK-O3: _Z12fp_precise_2fff
+  // CHECK-O3: %[[M:.+]] = fmul float{{.*}}
+  // CHECK-O3: fadd float %[[M]], %c
+  {
+#pragma float_control(precise, off)
+  }
+  return a * b + c;
+}
+
+// Does float_control survive template instantiation?
+class Foo {};
+Foo operator+(Foo, Foo);
+
+template <typename T>
+T template_muladd(T a, T b, T c) {
+#pragma float_control(precise, off)
+  return a * b + c;
+}
+
+float fp_precise_3(float a, float b, float c) {
+  // CHECK-O3: _Z12fp_precise_3fff
+  // CHECK-O3: %[[M:.+]] = fmul fast float{{.*}}
+  // CHECK-O3: fadd fast float %[[M]], %c
+  return template_muladd<float>(a, b, c);
+}
+
+template <typename T>
+class fp_precise_4 {
+  float method(float a, float b, float c) {
+#pragma float_control(precise, off)
+    return a * b + c;
+  }
+};
+
+template class fp_precise_4<int>;
+// CHECK-O3: _ZN12fp_precise_4IiE6methodEfff
+// CHECK-O3: %[[M:.+]] = fmul fast float{{.*}}
+// CHECK-O3: fadd fast float %[[M]], %c
+
+// Check file-scoped float_control
+#pragma float_control(push)
+#pragma float_control(precise, off)
+float fp_precise_5(float a, float b, float c) {
+  // CHECK-O3: _Z12fp_precise_5fff
+  // CHECK-O3: %[[M:.+]] = fmul fast float{{.*}}
+  // CHECK-O3: fadd fast float %[[M]], %c
+  return a * b + c;
+}
+#pragma float_control(pop)
 
 float fff(float x, float y) {
 // CHECK-LABEL: define float @_Z3fffff{{.*}}
@@ -41,6 +103,14 @@ float check_precise(float x, float y) {
   return z;
 }
 
+float fma_test2(float a, float b, float c) {
+// CHECK-LABEL define float @_Z9fma_test2fff{{.*}}
+#pragma float_control(precise, off)
+  float x = a * b + c;
+  //CHECK: fmuladd
+  return x;
+}
+
 float fma_test1(float a, float b, float c) {
 // CHECK-LABEL define float @_Z9fma_test1fff{{.*}}
 #pragma float_control(precise, on)


        


More information about the cfe-commits mailing list