1// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
2
3// Is FP_CONTRACT honored in a simple case?
4float fp_contract_1(float a, float b, float c) {
5// CHECK: _Z13fp_contract_1fff
6// CHECK: tail call float @llvm.fmuladd
7  #pragma STDC FP_CONTRACT ON
8  return a * b + c;
9}
10
11// Is FP_CONTRACT state cleared on exiting compound statements?
12float fp_contract_2(float a, float b, float c) {
13// CHECK: _Z13fp_contract_2fff
14// CHECK: %[[M:.+]] = fmul float %a, %b
15// CHECK-NEXT: fadd float %[[M]], %c
16  {
17    #pragma STDC FP_CONTRACT ON
18  }
19  return a * b + c;
20}
21
22// Does FP_CONTRACT survive template instantiation?
23class Foo {};
24Foo operator+(Foo, Foo);
25
26template <typename T>
27T template_muladd(T a, T b, T c) {
28  #pragma STDC FP_CONTRACT ON
29  return a * b + c;
30}
31
32float fp_contract_3(float a, float b, float c) {
33// CHECK: _Z13fp_contract_3fff
34// CHECK: tail call float @llvm.fmuladd
35  return template_muladd<float>(a, b, c);
36}
37
38template<typename T> class fp_contract_4 {
39  float method(float a, float b, float c) {
40    #pragma STDC FP_CONTRACT ON
41    return a * b + c;
42  }
43};
44
45template class fp_contract_4<int>;
46// CHECK: _ZN13fp_contract_4IiE6methodEfff
47// CHECK: tail call float @llvm.fmuladd
48
49// Check file-scoped FP_CONTRACT
50#pragma STDC FP_CONTRACT ON
51float fp_contract_5(float a, float b, float c) {
52// CHECK: _Z13fp_contract_5fff
53// CHECK: tail call float @llvm.fmuladd
54  return a * b + c;
55}
56
57#pragma STDC FP_CONTRACT OFF
58float fp_contract_6(float a, float b, float c) {
59// CHECK: _Z13fp_contract_6fff
60// CHECK: %[[M:.+]] = fmul float %a, %b
61// CHECK-NEXT: fadd float %[[M]], %c
62  return a * b + c;
63}
64
65// If the multiply has multiple uses, don't produce fmuladd.
66// This used to assert (PR25719):
67// https://llvm.org/bugs/show_bug.cgi?id=25719
68
69float fp_contract_7(float a, float b, float c) {
70// CHECK: _Z13fp_contract_7fff
71// CHECK:  %[[M:.+]] = fmul float %b, 2.000000e+00
72// CHECK-NEXT: fsub float %[[M]], %c
73  #pragma STDC FP_CONTRACT ON
74  return (a = 2 * b) - c;
75}
76
77