1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
2be9af1288881110e406b87914162eaa59f1e5918Lang Hames
3be9af1288881110e406b87914162eaa59f1e5918Lang Hames// Is FP_CONTRACT is honored in a simple case?
4be9af1288881110e406b87914162eaa59f1e5918Lang Hamesfloat fp_contract_1(float a, float b, float c) {
5be9af1288881110e406b87914162eaa59f1e5918Lang Hames// CHECK: _Z13fp_contract_1fff
6438daee6eea16a17b5e309c4f31e2f2fef3fd452NAKAMURA Takumi// CHECK: tail call float @llvm.fmuladd
7be9af1288881110e406b87914162eaa59f1e5918Lang Hames  #pragma STDC FP_CONTRACT ON
8be9af1288881110e406b87914162eaa59f1e5918Lang Hames  return a * b + c;
9be9af1288881110e406b87914162eaa59f1e5918Lang Hames}
10be9af1288881110e406b87914162eaa59f1e5918Lang Hames
11be9af1288881110e406b87914162eaa59f1e5918Lang Hames// Is FP_CONTRACT state cleared on exiting compound statements?
12be9af1288881110e406b87914162eaa59f1e5918Lang Hamesfloat fp_contract_2(float a, float b, float c) {
13be9af1288881110e406b87914162eaa59f1e5918Lang Hames// CHECK: _Z13fp_contract_2fff
14438daee6eea16a17b5e309c4f31e2f2fef3fd452NAKAMURA Takumi// CHECK: %[[M:.+]] = fmul float %a, %b
15438daee6eea16a17b5e309c4f31e2f2fef3fd452NAKAMURA Takumi// CHECK-NEXT: fadd float %[[M]], %c
16be9af1288881110e406b87914162eaa59f1e5918Lang Hames  {
17be9af1288881110e406b87914162eaa59f1e5918Lang Hames    #pragma STDC FP_CONTRACT ON
18be9af1288881110e406b87914162eaa59f1e5918Lang Hames  }
19be9af1288881110e406b87914162eaa59f1e5918Lang Hames  return a * b + c;
20be9af1288881110e406b87914162eaa59f1e5918Lang Hames}
21be9af1288881110e406b87914162eaa59f1e5918Lang Hames
22be9af1288881110e406b87914162eaa59f1e5918Lang Hames// Does FP_CONTRACT survive template instatiation?
23be9af1288881110e406b87914162eaa59f1e5918Lang Hamesclass Foo {};
24be9af1288881110e406b87914162eaa59f1e5918Lang HamesFoo operator+(Foo, Foo);
25be9af1288881110e406b87914162eaa59f1e5918Lang Hames
26be9af1288881110e406b87914162eaa59f1e5918Lang Hamestemplate <typename T>
27be9af1288881110e406b87914162eaa59f1e5918Lang HamesT template_muladd(T a, T b, T c) {
28be9af1288881110e406b87914162eaa59f1e5918Lang Hames  #pragma STDC FP_CONTRACT ON
29be9af1288881110e406b87914162eaa59f1e5918Lang Hames  return a * b + c;
30be9af1288881110e406b87914162eaa59f1e5918Lang Hames}
31be9af1288881110e406b87914162eaa59f1e5918Lang Hames
32be9af1288881110e406b87914162eaa59f1e5918Lang Hamesfloat fp_contract_3(float a, float b, float c) {
33be9af1288881110e406b87914162eaa59f1e5918Lang Hames// CHECK: _Z13fp_contract_3fff
34438daee6eea16a17b5e309c4f31e2f2fef3fd452NAKAMURA Takumi// CHECK: tail call float @llvm.fmuladd
35be9af1288881110e406b87914162eaa59f1e5918Lang Hames  return template_muladd<float>(a, b, c);
36be9af1288881110e406b87914162eaa59f1e5918Lang Hames}
379595c7e2533c836537dc300e75d059c29feb7094Eli Friedman
389595c7e2533c836537dc300e75d059c29feb7094Eli Friedmantemplate<typename T> class fp_contract_4 {
399595c7e2533c836537dc300e75d059c29feb7094Eli Friedman  float method(float a, float b, float c) {
409595c7e2533c836537dc300e75d059c29feb7094Eli Friedman    #pragma STDC FP_CONTRACT ON
419595c7e2533c836537dc300e75d059c29feb7094Eli Friedman    return a * b + c;
429595c7e2533c836537dc300e75d059c29feb7094Eli Friedman  }
439595c7e2533c836537dc300e75d059c29feb7094Eli Friedman};
449595c7e2533c836537dc300e75d059c29feb7094Eli Friedman
459595c7e2533c836537dc300e75d059c29feb7094Eli Friedmantemplate class fp_contract_4<int>;
469595c7e2533c836537dc300e75d059c29feb7094Eli Friedman// CHECK: _ZN13fp_contract_4IiE6methodEfff
479595c7e2533c836537dc300e75d059c29feb7094Eli Friedman// CHECK: tail call float @llvm.fmuladd
48eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames
49eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames// Check file-scoped FP_CONTRACT
50eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames#pragma STDC FP_CONTRACT ON
51eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hamesfloat fp_contract_5(float a, float b, float c) {
52eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames// CHECK: _Z13fp_contract_5fff
53eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames// CHECK: tail call float @llvm.fmuladd
54eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames  return a * b + c;
55eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames}
56eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames
57eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames#pragma STDC FP_CONTRACT OFF
58eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hamesfloat fp_contract_6(float a, float b, float c) {
59eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames// CHECK: _Z13fp_contract_6fff
60eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames// CHECK: %[[M:.+]] = fmul float %a, %b
61eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames// CHECK-NEXT: fadd float %[[M]], %c
62eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames  return a * b + c;
63eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames}
64eddb00a704ed39ea781693cf8fcf7cc69a175b95Lang Hames
65