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) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits