1 // RUN: %clang_cc1 -DEXCEPT=1 -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NS %s 2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s 3 // RUN: %clang_cc1 -verify -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s 4 5 float fff(float x, float y) { 6 // CHECK-LABEL: define float @_Z3fffff{{.*}} 7 // CHECK: entry 8 #pragma float_control(except, on) 9 float z; 10 z = z * z; 11 //CHECK: llvm.experimental.constrained.fmul{{.*}} 12 { 13 z = x * y; 14 //CHECK: llvm.experimental.constrained.fmul{{.*}} 15 } 16 { 17 // This pragma has no effect since if there are any fp intrin in the 18 // function then all the operations need to be fp intrin 19 #pragma float_control(except, off) 20 z = z + x * y; 21 //CHECK: llvm.experimental.constrained.fmul{{.*}} 22 } 23 z = z * z; 24 //CHECK: llvm.experimental.constrained.fmul{{.*}} 25 return z; 26 } 27 float check_precise(float x, float y) { 28 // CHECK-LABEL: define float @_Z13check_preciseff{{.*}} 29 float z; 30 { 31 #pragma float_control(precise, on) 32 z = x * y + z; 33 //CHECK: llvm.fmuladd{{.*}} 34 } 35 { 36 #pragma float_control(precise, off) 37 z = x * y + z; 38 //CHECK: fmul fast float 39 //CHECK: fadd fast float 40 } 41 return z; 42 } 43 44 float fma_test1(float a, float b, float c) { 45 // CHECK-LABEL define float @_Z9fma_test1fff{{.*}} 46 #pragma float_control(precise, on) 47 float x = a * b + c; 48 //CHECK: fmuladd 49 return x; 50 } 51 52 #if FENV_ON 53 // expected-warning@+1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}} 54 #pragma STDC FENV_ACCESS ON 55 #endif 56 // CHECK-LABEL: define {{.*}}callt{{.*}} 57 58 void callt() { 59 volatile float z; 60 z = z * z; 61 //CHECK: = fmul float 62 } 63 64 #if EXCEPT 65 namespace ns { 66 // Check that pragma float_control can appear in namespace. 67 #pragma float_control(except, on, push) 68 float exc_on(double x, float zero) { 69 // CHECK-NS: define {{.*}}exc_on{{.*}} 70 {} try { 71 x = 1.0 / zero; /* division by zero, the result unused */ 72 //CHECK-NS: llvm.experimental.constrained.fdiv{{.*}} 73 } catch (...) {} 74 return zero; 75 } 76 } 77 78 // Check pragma is still effective after namespace closes 79 float exc_still_on(double x, float zero) { 80 // CHECK-NS: define {{.*}}exc_still_on{{.*}} 81 {} try { 82 x = 1.0 / zero; /* division by zero, the result unused */ 83 //CHECK-NS: llvm.experimental.constrained.fdiv{{.*}} 84 } catch (...) {} 85 return zero; 86 } 87 88 #pragma float_control(pop) 89 float exc_off(double x, float zero) { 90 // CHECK-NS: define {{.*}}exc_off{{.*}} 91 {} try { 92 x = 1.0 / zero; /* division by zero, the result unused */ 93 //CHECK-NS: fdiv contract double 94 } catch (...) {} 95 return zero; 96 } 97 98 namespace fc_template_namespace { 99 #pragma float_control(except, on, push) 100 template <class T> 101 T exc_on(double x, T zero) { 102 // CHECK-NS: define {{.*}}fc_template_namespace{{.*}} 103 {} try { 104 x = 1.0 / zero; /* division by zero, the result unused */ 105 //CHECK-NS: llvm.experimental.constrained.fdiv{{.*}} 106 } catch (...) {} 107 return zero; 108 } 109 } 110 111 #pragma float_control(pop) 112 float xx(double x, float z) { 113 return fc_template_namespace::exc_on<float>(x, z); 114 } 115 #endif // EXCEPT 116