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