1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s 2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s 3 // RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s 4 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s 5 6 #define FUN(n) \ 7 (float z) { return n * z + n; } 8 9 float fun_default FUN(1) 10 //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}} 11 #if DEFAULT 12 //CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}} 13 #endif 14 #if EBSTRICT 15 // Note that backend wants constrained intrinsics used 16 // throughout the function if they are needed anywhere in the function. 17 // In that case, operations are built with constrained intrinsics operator 18 // but using default settings for exception behavior and rounding mode. 19 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict 20 #endif 21 #if FAST 22 //CHECK-FAST: fmul fast float 23 //CHECK-FAST: fadd fast float 24 #endif 25 26 #pragma float_control(push) 27 #ifndef FAST 28 // Rule: precise must be enabled 29 #pragma float_control(except, on) 30 #endif 31 float exc_on FUN(2) 32 //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}} 33 #if DEFAULT 34 //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}} 35 #endif 36 #if EBSTRICT 37 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict 38 #endif 39 #if NOHONOR 40 //CHECK-NOHONOR: nnan ninf contract float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict 41 #endif 42 #if FAST 43 //Not possible to enable float_control(except) in FAST mode. 44 //CHECK-FAST: fmul fast float 45 //CHECK-FAST: fadd fast float 46 #endif 47 48 #pragma float_control(pop) 49 float exc_pop FUN(5) 50 //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}} 51 #if DEFAULT 52 //CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}} 53 #endif 54 #if EBSTRICT 55 //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict 56 #endif 57 #if NOHONOR 58 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} 59 #endif 60 #if FAST 61 //CHECK-FAST: fmul fast float 62 //CHECK-FAST: fadd fast float 63 #endif 64 65 #pragma float_control(except, off) 66 float exc_off FUN(5) 67 //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}} 68 #if DEFAULT 69 //CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}} 70 #endif 71 #if EBSTRICT 72 //CHECK-DEBSTRICT: call contract float @llvm.fmuladd{{.*}} 73 #endif 74 #if NOHONOR 75 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} 76 #endif 77 #if FAST 78 //CHECK-FAST: fmul fast float 79 //CHECK-FAST: fadd fast float 80 #endif 81 82 #pragma float_control(precise, on, push) 83 float precise_on FUN(3) 84 //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}} 85 #if DEFAULT 86 //CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}} 87 #endif 88 #if EBSTRICT 89 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} 90 #endif 91 #if NOHONOR 92 // If precise is pushed then all fast-math should be off! 93 //CHECK-NOHONOR: call contract float {{.*}}llvm.fmuladd{{.*}} 94 #endif 95 #if FAST 96 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} 97 #endif 98 99 #pragma float_control(pop) 100 float precise_pop FUN(3) 101 //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}} 102 #if DEFAULT 103 //CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}} 104 #endif 105 #if EBSTRICT 106 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} 107 #endif 108 #if NOHONOR 109 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} 110 #endif 111 #if FAST 112 //CHECK-FAST: fmul fast float 113 //CHECK-FAST: fadd fast float 114 #endif 115 #pragma float_control(precise, off) 116 float precise_off FUN(4) 117 //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}} 118 #if DEFAULT 119 // Note: precise_off enables fp_contract=fast and the instructions 120 // generated do not include the contract flag, although it was enabled 121 // in IRBuilder. 122 //CHECK-DDEFAULT: fmul fast float 123 //CHECK-DDEFAULT: fadd fast float 124 #endif 125 #if EBSTRICT 126 //CHECK-DEBSTRICT: fmul fast float 127 //CHECK-DEBSTRICT: fadd fast float 128 #endif 129 #if NOHONOR 130 // fast math should be enabled, and contract should be fast 131 //CHECK-NOHONOR: fmul fast float 132 //CHECK-NOHONOR: fadd fast float 133 #endif 134 #if FAST 135 //CHECK-FAST: fmul fast float 136 //CHECK-FAST: fadd fast float 137 #endif 138 139 #pragma float_control(precise, on) 140 float precise_on2 FUN(3) 141 //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}} 142 #if DEFAULT 143 //CHECK-DDEFAULT: llvm.fmuladd{{.*}} 144 #endif 145 #if EBSTRICT 146 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} 147 #endif 148 #if NOHONOR 149 // fast math should be off, and contract should be on 150 //CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}} 151 #endif 152 #if FAST 153 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} 154 #endif 155 156 #pragma float_control(push) 157 float precise_push FUN(3) 158 //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}} 159 #if DEFAULT 160 //CHECK-DDEFAULT: llvm.fmuladd{{.*}} 161 #endif 162 #if EBSTRICT 163 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} 164 #endif 165 #if NOHONOR 166 //CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}} 167 #endif 168 #if FAST 169 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} 170 #endif 171 172 #pragma float_control(precise, off) 173 float precise_off2 FUN(4) 174 //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}} 175 #if DEFAULT 176 //CHECK-DDEFAULT: fmul fast float 177 //CHECK-DDEFAULT: fadd fast float 178 #endif 179 #if EBSTRICT 180 //CHECK-DEBSTRICT: fmul fast float 181 //CHECK-DEBSTRICT: fadd fast float 182 #endif 183 #if NOHONOR 184 // fast math settings since precise is off 185 //CHECK-NOHONOR: fmul fast float 186 //CHECK-NOHONOR: fadd fast float 187 #endif 188 #if FAST 189 //CHECK-FAST: fmul fast float 190 //CHECK-FAST: fadd fast float 191 #endif 192 193 #pragma float_control(pop) 194 float precise_pop2 FUN(3) 195 //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}} 196 #if DEFAULT 197 //CHECK-DDEFAULT: llvm.fmuladd{{.*}} 198 #endif 199 #if EBSTRICT 200 //CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} 201 #endif 202 #if NOHONOR 203 //CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}} 204 #endif 205 #if FAST 206 //CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} 207 #endif 208 209 #ifndef FAST 210 // Rule: precise must be enabled 211 #pragma float_control(except, on) 212 #endif 213 float y(); 214 class ON { 215 // Settings for top level class initializer revert to command line 216 // source pragma's do not pertain. 217 float z = 2 + y() * 7; 218 //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} 219 #if DEFAULT 220 //CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd 221 #endif 222 #if EBSTRICT 223 //Currently, same as default [command line options not considered] 224 //CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd 225 #endif 226 #if NOHONOR 227 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} 228 #endif 229 #if FAST 230 //CHECK-FAST: fmul fast float 231 //CHECK-FAST: fadd fast float 232 #endif 233 }; 234 ON on; 235 #pragma float_control(except, off) 236 class OFF { 237 float w = 2 + y() * 7; 238 //CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} 239 #if DEFAULT 240 //CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd 241 #endif 242 #if EBSTRICT 243 //CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd 244 #endif 245 #if NOHONOR 246 //CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} 247 #endif 248 #if FAST 249 //CHECK-FAST: fmul fast float 250 //CHECK-FAST: fadd fast float 251 #endif 252 }; 253 OFF off; 254