Clang Project

clang_source_code/test/CodeGen/fp-contract-on-pragma.cpp
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 clang 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 clang 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 clang 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>
39class fp_contract_4 {
40  float method(float a, float b, float c) {
41#pragma clang fp contract(on)
42    return a * b + c;
43  }
44};
45
46template class fp_contract_4<int>;
47// CHECK: _ZN13fp_contract_4IiE6methodEfff
48// CHECK: tail call float @llvm.fmuladd
49
50// Check file-scoped FP_CONTRACT
51#pragma clang fp contract(on)
52float fp_contract_5(float a, float b, float c) {
53  // CHECK: _Z13fp_contract_5fff
54  // CHECK: tail call float @llvm.fmuladd
55  return a * b + c;
56}
57
58#pragma clang fp contract(off)
59float fp_contract_6(float a, float b, float c) {
60  // CHECK: _Z13fp_contract_6fff
61  // CHECK: %[[M:.+]] = fmul float %a, %b
62  // CHECK-NEXT: fadd float %[[M]], %c
63  return a * b + c;
64}
65
66// If the multiply has multiple uses, don't produce fmuladd.
67// This used to assert (PR25719):
68// https://llvm.org/bugs/show_bug.cgi?id=25719
69
70float fp_contract_7(float a, float b, float c) {
71// CHECK: _Z13fp_contract_7fff
72// CHECK:  %[[M:.+]] = fmul float %b, 2.000000e+00
73// CHECK-NEXT: fsub float %[[M]], %c
74#pragma clang fp contract(on)
75  return (a = 2 * b) - c;
76}
77