xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/fp-contract-pragma.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -O3 -emit-llvm -o - %s | FileCheck %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc // Is FP_CONTRACT is honored in a simple case?
4*f4a2713aSLionel Sambuc float fp_contract_1(float a, float b, float c) {
5*f4a2713aSLionel Sambuc // CHECK: _Z13fp_contract_1fff
6*f4a2713aSLionel Sambuc // CHECK: tail call float @llvm.fmuladd
7*f4a2713aSLionel Sambuc   #pragma STDC FP_CONTRACT ON
8*f4a2713aSLionel Sambuc   return a * b + c;
9*f4a2713aSLionel Sambuc }
10*f4a2713aSLionel Sambuc 
11*f4a2713aSLionel Sambuc // Is FP_CONTRACT state cleared on exiting compound statements?
12*f4a2713aSLionel Sambuc float fp_contract_2(float a, float b, float c) {
13*f4a2713aSLionel Sambuc // CHECK: _Z13fp_contract_2fff
14*f4a2713aSLionel Sambuc // CHECK: %[[M:.+]] = fmul float %a, %b
15*f4a2713aSLionel Sambuc // CHECK-NEXT: fadd float %[[M]], %c
16*f4a2713aSLionel Sambuc   {
17*f4a2713aSLionel Sambuc     #pragma STDC FP_CONTRACT ON
18*f4a2713aSLionel Sambuc   }
19*f4a2713aSLionel Sambuc   return a * b + c;
20*f4a2713aSLionel Sambuc }
21*f4a2713aSLionel Sambuc 
22*f4a2713aSLionel Sambuc // Does FP_CONTRACT survive template instatiation?
23*f4a2713aSLionel Sambuc class Foo {};
24*f4a2713aSLionel Sambuc Foo operator+(Foo, Foo);
25*f4a2713aSLionel Sambuc 
26*f4a2713aSLionel Sambuc template <typename T>
27*f4a2713aSLionel Sambuc T template_muladd(T a, T b, T c) {
28*f4a2713aSLionel Sambuc   #pragma STDC FP_CONTRACT ON
29*f4a2713aSLionel Sambuc   return a * b + c;
30*f4a2713aSLionel Sambuc }
31*f4a2713aSLionel Sambuc 
32*f4a2713aSLionel Sambuc float fp_contract_3(float a, float b, float c) {
33*f4a2713aSLionel Sambuc // CHECK: _Z13fp_contract_3fff
34*f4a2713aSLionel Sambuc // CHECK: tail call float @llvm.fmuladd
35*f4a2713aSLionel Sambuc   return template_muladd<float>(a, b, c);
36*f4a2713aSLionel Sambuc }
37*f4a2713aSLionel Sambuc 
38*f4a2713aSLionel Sambuc template<typename T> class fp_contract_4 {
39*f4a2713aSLionel Sambuc   float method(float a, float b, float c) {
40*f4a2713aSLionel Sambuc     #pragma STDC FP_CONTRACT ON
41*f4a2713aSLionel Sambuc     return a * b + c;
42*f4a2713aSLionel Sambuc   }
43*f4a2713aSLionel Sambuc };
44*f4a2713aSLionel Sambuc 
45*f4a2713aSLionel Sambuc template class fp_contract_4<int>;
46*f4a2713aSLionel Sambuc // CHECK: _ZN13fp_contract_4IiE6methodEfff
47*f4a2713aSLionel Sambuc // CHECK: tail call float @llvm.fmuladd
48*f4a2713aSLionel Sambuc 
49*f4a2713aSLionel Sambuc // Check file-scoped FP_CONTRACT
50*f4a2713aSLionel Sambuc #pragma STDC FP_CONTRACT ON
51*f4a2713aSLionel Sambuc float fp_contract_5(float a, float b, float c) {
52*f4a2713aSLionel Sambuc // CHECK: _Z13fp_contract_5fff
53*f4a2713aSLionel Sambuc // CHECK: tail call float @llvm.fmuladd
54*f4a2713aSLionel Sambuc   return a * b + c;
55*f4a2713aSLionel Sambuc }
56*f4a2713aSLionel Sambuc 
57*f4a2713aSLionel Sambuc #pragma STDC FP_CONTRACT OFF
58*f4a2713aSLionel Sambuc float fp_contract_6(float a, float b, float c) {
59*f4a2713aSLionel Sambuc // CHECK: _Z13fp_contract_6fff
60*f4a2713aSLionel Sambuc // CHECK: %[[M:.+]] = fmul float %a, %b
61*f4a2713aSLionel Sambuc // CHECK-NEXT: fadd float %[[M]], %c
62*f4a2713aSLionel Sambuc   return a * b + c;
63*f4a2713aSLionel Sambuc }
64*f4a2713aSLionel Sambuc 
65