mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 10:46:07 +00:00

This adds the new pragma and the first variant, contract(on/off/fast). The pragma has the same block scope rules as STDC FP_CONTRACT, i.e. it can be placed at the beginning of a compound statement or at file scope. Similarly to STDC FP_CONTRACT there is no need to use attributes. First an annotate token is inserted with the parsed details of the pragma. Then the annotate token is parsed in the proper contexts and the Sema is updated with the corresponding FPOptions using the shared ActOn function with STDC FP_CONTRACT. After this the FPOptions from the Sema is propagated into the AST expression nodes. There is no change here. I was going to add a 'default' option besides 'on/off/fast' similar to STDC FP_CONTRACT but then decided against it. I think that we'd have to make option uppercase then to avoid using 'default' the keyword. Also because of the scoped activation of pragma I am not sure there is really a need a for this. Differential Revision: https://reviews.llvm.org/D31276 llvm-svn: 299470
70 lines
1.9 KiB
C++
70 lines
1.9 KiB
C++
// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
|
|
|
|
// Is FP_CONTRACT honored in a simple case?
|
|
float fp_contract_1(float a, float b, float c) {
|
|
// CHECK: _Z13fp_contract_1fff
|
|
// CHECK: %[[M:.+]] = fmul contract float %a, %b
|
|
// CHECK-NEXT: fadd contract float %[[M]], %c
|
|
#pragma clang fp contract(fast)
|
|
return a * b + c;
|
|
}
|
|
|
|
// Is FP_CONTRACT state cleared on exiting compound statements?
|
|
float fp_contract_2(float a, float b, float c) {
|
|
// CHECK: _Z13fp_contract_2fff
|
|
// CHECK: %[[M:.+]] = fmul float %a, %b
|
|
// CHECK-NEXT: fadd float %[[M]], %c
|
|
{
|
|
#pragma clang fp contract(fast)
|
|
}
|
|
return a * b + c;
|
|
}
|
|
|
|
// Does FP_CONTRACT survive template instantiation?
|
|
class Foo {};
|
|
Foo operator+(Foo, Foo);
|
|
|
|
template <typename T>
|
|
T template_muladd(T a, T b, T c) {
|
|
#pragma clang fp contract(fast)
|
|
return a * b + c;
|
|
}
|
|
|
|
float fp_contract_3(float a, float b, float c) {
|
|
// CHECK: _Z13fp_contract_3fff
|
|
// CHECK: %[[M:.+]] = fmul contract float %a, %b
|
|
// CHECK-NEXT: fadd contract float %[[M]], %c
|
|
return template_muladd<float>(a, b, c);
|
|
}
|
|
|
|
template <typename T>
|
|
class fp_contract_4 {
|
|
float method(float a, float b, float c) {
|
|
#pragma clang fp contract(fast)
|
|
return a * b + c;
|
|
}
|
|
};
|
|
|
|
template class fp_contract_4<int>;
|
|
// CHECK: _ZN13fp_contract_4IiE6methodEfff
|
|
// CHECK: %[[M:.+]] = fmul contract float %a, %b
|
|
// CHECK-NEXT: fadd contract float %[[M]], %c
|
|
|
|
// Check file-scoped FP_CONTRACT
|
|
#pragma clang fp contract(fast)
|
|
float fp_contract_5(float a, float b, float c) {
|
|
// CHECK: _Z13fp_contract_5fff
|
|
// CHECK: %[[M:.+]] = fmul contract float %a, %b
|
|
// CHECK-NEXT: fadd contract float %[[M]], %c
|
|
return a * b + c;
|
|
}
|
|
|
|
// Verify that we can handle multiple flags on the same pragma
|
|
#pragma clang fp contract(fast) contract(off)
|
|
float fp_contract_6(float a, float b, float c) {
|
|
// CHECK: _Z13fp_contract_6fff
|
|
// CHECK: %[[M:.+]] = fmul float %a, %b
|
|
// CHECK-NEXT: fadd float %[[M]], %c
|
|
return a * b + c;
|
|
}
|