1f5360d4bSMelanie Blower // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s 2f5360d4bSMelanie 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 3f5360d4bSMelanie 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 4f5360d4bSMelanie 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 5f5360d4bSMelanie Blower 6f5360d4bSMelanie Blower #define FUN(n) \ 7f5360d4bSMelanie Blower (float z) { return n * z + n; } 8f5360d4bSMelanie Blower 9*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress 10*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress 11*bc5b5ea0SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone 12*bc5b5ea0SMelanie Blower // CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress 13f5360d4bSMelanie Blower float fun_default FUN(1) 14f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}} 15f5360d4bSMelanie Blower #if DEFAULT 16827be690SMelanie Blower //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} 17f5360d4bSMelanie Blower #endif 18f5360d4bSMelanie Blower #if EBSTRICT 19f5360d4bSMelanie Blower // Note that backend wants constrained intrinsics used 20f5360d4bSMelanie Blower // throughout the function if they are needed anywhere in the function. 21f5360d4bSMelanie Blower // In that case, operations are built with constrained intrinsics operator 22f5360d4bSMelanie Blower // but using default settings for exception behavior and rounding mode. 23f5360d4bSMelanie Blower //CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict 24f5360d4bSMelanie Blower #endif 25f5360d4bSMelanie Blower #if FAST 26f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 27f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 28f5360d4bSMelanie Blower #endif 29f5360d4bSMelanie Blower 30f5360d4bSMelanie Blower #pragma float_control(push) 31f5360d4bSMelanie Blower #ifndef FAST 32f5360d4bSMelanie Blower // Rule: precise must be enabled 33f5360d4bSMelanie Blower #pragma float_control(except, on) 34f5360d4bSMelanie Blower #endif 35*bc5b5ea0SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone 36*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone strictfp mustprogress 37*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress 38*bc5b5ea0SMelanie Blower // CHECK-NOHONOR Function Attrs: noinline nounwind optnone strictfp mustprogress 39f5360d4bSMelanie Blower float exc_on FUN(2) 40f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}} 41f5360d4bSMelanie Blower #if DEFAULT 42f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}} 43f5360d4bSMelanie Blower #endif 44f5360d4bSMelanie Blower #if EBSTRICT 45f5360d4bSMelanie Blower //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict 46f5360d4bSMelanie Blower #endif 47f5360d4bSMelanie Blower #if NOHONOR 48827be690SMelanie Blower //CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict 49f5360d4bSMelanie Blower #endif 50f5360d4bSMelanie Blower #if FAST 51f5360d4bSMelanie Blower //Not possible to enable float_control(except) in FAST mode. 52f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 53f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 54f5360d4bSMelanie Blower #endif 55f5360d4bSMelanie Blower 56f5360d4bSMelanie Blower #pragma float_control(pop) 57*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress 58*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress 59*bc5b5ea0SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone 60*bc5b5ea0SMelanie Blower // CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress 61f5360d4bSMelanie Blower float exc_pop FUN(5) 62f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}} 63f5360d4bSMelanie Blower #if DEFAULT 64827be690SMelanie Blower //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} 65f5360d4bSMelanie Blower #endif 66f5360d4bSMelanie Blower #if EBSTRICT 67f5360d4bSMelanie Blower //CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict 68f5360d4bSMelanie Blower #endif 69f5360d4bSMelanie Blower #if NOHONOR 70827be690SMelanie Blower //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} 71f5360d4bSMelanie Blower #endif 72f5360d4bSMelanie Blower #if FAST 73f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 74f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 75f5360d4bSMelanie Blower #endif 76f5360d4bSMelanie Blower 77f5360d4bSMelanie Blower #pragma float_control(except, off) 78f5360d4bSMelanie Blower float exc_off FUN(5) 79f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}} 80f5360d4bSMelanie Blower #if DEFAULT 81827be690SMelanie Blower //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} 82f5360d4bSMelanie Blower #endif 83f5360d4bSMelanie Blower #if EBSTRICT 84827be690SMelanie Blower //CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}} 85f5360d4bSMelanie Blower #endif 86f5360d4bSMelanie Blower #if NOHONOR 87827be690SMelanie Blower //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} 88f5360d4bSMelanie Blower #endif 89f5360d4bSMelanie Blower #if FAST 90f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 91f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 92f5360d4bSMelanie Blower #endif 93f5360d4bSMelanie Blower 94f5360d4bSMelanie Blower #pragma float_control(precise, on, push) 95f5360d4bSMelanie Blower float precise_on FUN(3) 96f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}} 97f5360d4bSMelanie Blower #if DEFAULT 98827be690SMelanie Blower //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}} 99f5360d4bSMelanie Blower #endif 100f5360d4bSMelanie Blower #if EBSTRICT 101827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} 102f5360d4bSMelanie Blower #endif 103f5360d4bSMelanie Blower #if NOHONOR 104f5360d4bSMelanie Blower // If precise is pushed then all fast-math should be off! 105827be690SMelanie Blower //CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}} 106f5360d4bSMelanie Blower #endif 107f5360d4bSMelanie Blower #if FAST 108827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} 109f5360d4bSMelanie Blower #endif 110f5360d4bSMelanie Blower 111f5360d4bSMelanie Blower #pragma float_control(pop) 112f5360d4bSMelanie Blower float precise_pop FUN(3) 113f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}} 114f5360d4bSMelanie Blower #if DEFAULT 115827be690SMelanie Blower //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}} 116f5360d4bSMelanie Blower #endif 117f5360d4bSMelanie Blower #if EBSTRICT 118827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} 119f5360d4bSMelanie Blower #endif 120f5360d4bSMelanie Blower #if NOHONOR 121827be690SMelanie Blower //CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} 122f5360d4bSMelanie Blower #endif 123f5360d4bSMelanie Blower #if FAST 124f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 125f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 126f5360d4bSMelanie Blower #endif 127f5360d4bSMelanie Blower #pragma float_control(precise, off) 128f5360d4bSMelanie Blower float precise_off FUN(4) 129f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}} 130f5360d4bSMelanie Blower #if DEFAULT 131f5360d4bSMelanie Blower // Note: precise_off enables fp_contract=fast and the instructions 132f5360d4bSMelanie Blower // generated do not include the contract flag, although it was enabled 133f5360d4bSMelanie Blower // in IRBuilder. 134f5360d4bSMelanie Blower //CHECK-DDEFAULT: fmul fast float 135f5360d4bSMelanie Blower //CHECK-DDEFAULT: fadd fast float 136f5360d4bSMelanie Blower #endif 137f5360d4bSMelanie Blower #if EBSTRICT 138f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fmul fast float 139f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fadd fast float 140f5360d4bSMelanie Blower #endif 141f5360d4bSMelanie Blower #if NOHONOR 142f5360d4bSMelanie Blower // fast math should be enabled, and contract should be fast 143f5360d4bSMelanie Blower //CHECK-NOHONOR: fmul fast float 144f5360d4bSMelanie Blower //CHECK-NOHONOR: fadd fast float 145f5360d4bSMelanie Blower #endif 146f5360d4bSMelanie Blower #if FAST 147f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 148f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 149f5360d4bSMelanie Blower #endif 150f5360d4bSMelanie Blower 151f5360d4bSMelanie Blower #pragma float_control(precise, on) 152f5360d4bSMelanie Blower float precise_on2 FUN(3) 153f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}} 154f5360d4bSMelanie Blower #if DEFAULT 155f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.fmuladd{{.*}} 156f5360d4bSMelanie Blower #endif 157f5360d4bSMelanie Blower #if EBSTRICT 158827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} 159f5360d4bSMelanie Blower #endif 160f5360d4bSMelanie Blower #if NOHONOR 161f5360d4bSMelanie Blower // fast math should be off, and contract should be on 162827be690SMelanie Blower //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}} 163f5360d4bSMelanie Blower #endif 164f5360d4bSMelanie Blower #if FAST 165827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} 166f5360d4bSMelanie Blower #endif 167f5360d4bSMelanie Blower 168f5360d4bSMelanie Blower #pragma float_control(push) 169f5360d4bSMelanie Blower float precise_push FUN(3) 170f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}} 171f5360d4bSMelanie Blower #if DEFAULT 172f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.fmuladd{{.*}} 173f5360d4bSMelanie Blower #endif 174f5360d4bSMelanie Blower #if EBSTRICT 175827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} 176f5360d4bSMelanie Blower #endif 177f5360d4bSMelanie Blower #if NOHONOR 178827be690SMelanie Blower //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}} 179f5360d4bSMelanie Blower #endif 180f5360d4bSMelanie Blower #if FAST 181827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} 182f5360d4bSMelanie Blower #endif 183f5360d4bSMelanie Blower 184f5360d4bSMelanie Blower #pragma float_control(precise, off) 185f5360d4bSMelanie Blower float precise_off2 FUN(4) 186f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}} 187f5360d4bSMelanie Blower #if DEFAULT 188f5360d4bSMelanie Blower //CHECK-DDEFAULT: fmul fast float 189f5360d4bSMelanie Blower //CHECK-DDEFAULT: fadd fast float 190f5360d4bSMelanie Blower #endif 191f5360d4bSMelanie Blower #if EBSTRICT 192f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fmul fast float 193f5360d4bSMelanie Blower //CHECK-DEBSTRICT: fadd fast float 194f5360d4bSMelanie Blower #endif 195f5360d4bSMelanie Blower #if NOHONOR 196f5360d4bSMelanie Blower // fast math settings since precise is off 197f5360d4bSMelanie Blower //CHECK-NOHONOR: fmul fast float 198f5360d4bSMelanie Blower //CHECK-NOHONOR: fadd fast float 199f5360d4bSMelanie Blower #endif 200f5360d4bSMelanie Blower #if FAST 201f5360d4bSMelanie Blower //CHECK-FAST: fmul fast float 202f5360d4bSMelanie Blower //CHECK-FAST: fadd fast float 203f5360d4bSMelanie Blower #endif 204f5360d4bSMelanie Blower 205f5360d4bSMelanie Blower #pragma float_control(pop) 206f5360d4bSMelanie Blower float precise_pop2 FUN(3) 207f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}} 208f5360d4bSMelanie Blower #if DEFAULT 209f5360d4bSMelanie Blower //CHECK-DDEFAULT: llvm.fmuladd{{.*}} 210f5360d4bSMelanie Blower #endif 211f5360d4bSMelanie Blower #if EBSTRICT 212827be690SMelanie Blower //CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} 213f5360d4bSMelanie Blower #endif 214f5360d4bSMelanie Blower #if NOHONOR 215827be690SMelanie Blower //CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}} 216f5360d4bSMelanie Blower #endif 217f5360d4bSMelanie Blower #if FAST 218827be690SMelanie Blower //CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} 219f5360d4bSMelanie Blower #endif 220f5360d4bSMelanie Blower 221f5360d4bSMelanie Blower #ifndef FAST 222f5360d4bSMelanie Blower // Rule: precise must be enabled 223f5360d4bSMelanie Blower #pragma float_control(except, on) 224f5360d4bSMelanie Blower #endif 225f5360d4bSMelanie Blower float y(); 226*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress 227*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress 228*bc5b5ea0SMelanie Blower // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone 229*bc5b5ea0SMelanie Blower // CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress 230f5360d4bSMelanie Blower class ON { 23133b1f3f4SMelanie Blower // Settings for top level class initializer use program source setting. 232f5360d4bSMelanie Blower float z = 2 + y() * 7; 233f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} 234f5360d4bSMelanie Blower #if DEFAULT 235*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict 236f5360d4bSMelanie Blower #endif 237f5360d4bSMelanie Blower #if EBSTRICT 238*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict 239f5360d4bSMelanie Blower #endif 240f5360d4bSMelanie Blower #if NOHONOR 241*bc5b5ea0SMelanie Blower // CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict 242f5360d4bSMelanie Blower #endif 243f5360d4bSMelanie Blower #if FAST 24433b1f3f4SMelanie Blower // CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} 245f5360d4bSMelanie Blower #endif 246f5360d4bSMelanie Blower }; 247f5360d4bSMelanie Blower ON on; 248f5360d4bSMelanie Blower #pragma float_control(except, off) 249*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone 250*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone 251*bc5b5ea0SMelanie Blower // CHECK-FAST: Function Attrs: noinline nounwind optnone 252*bc5b5ea0SMelanie Blower // CHECK-NOHONOR Function Attrs: noinline nounwind optnone 253f5360d4bSMelanie Blower class OFF { 254f5360d4bSMelanie Blower float w = 2 + y() * 7; 255f5360d4bSMelanie Blower //CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} 25633b1f3f4SMelanie Blower //CHECK: call float {{.*}}llvm.fmuladd 257f5360d4bSMelanie Blower }; 258f5360d4bSMelanie Blower OFF off; 25933b1f3f4SMelanie Blower 26033b1f3f4SMelanie Blower #pragma clang fp reassociate(on) 26133b1f3f4SMelanie Blower struct MyComplex { 26233b1f3f4SMelanie Blower float xx; 26333b1f3f4SMelanie Blower float yy; 26433b1f3f4SMelanie Blower MyComplex(float x, float y) { 26533b1f3f4SMelanie Blower xx = x; 26633b1f3f4SMelanie Blower yy = y; 26733b1f3f4SMelanie Blower } 26833b1f3f4SMelanie Blower MyComplex() {} 26933b1f3f4SMelanie Blower const MyComplex operator+(const MyComplex other) const { 27033b1f3f4SMelanie Blower //CHECK-LABEL: define {{.*}} @_ZNK9MyComplexplES_ 27133b1f3f4SMelanie Blower //CHECK: fadd reassoc float 27233b1f3f4SMelanie Blower //CHECK: fadd reassoc float 27333b1f3f4SMelanie Blower return MyComplex(xx + other.xx, yy + other.yy); 27433b1f3f4SMelanie Blower } 27533b1f3f4SMelanie Blower }; 27633b1f3f4SMelanie Blower MyComplex useAdd() { 27733b1f3f4SMelanie Blower MyComplex a (1, 3); 27833b1f3f4SMelanie Blower MyComplex b (2, 4); 27933b1f3f4SMelanie Blower return a + b; 28033b1f3f4SMelanie Blower } 281*bc5b5ea0SMelanie Blower 282*bc5b5ea0SMelanie Blower // CHECK-DDEFAULT Function Attrs: noinline nounwind 283*bc5b5ea0SMelanie Blower // CHECK-DEBSTRICT Function Attrs: noinline nounwind strictfp 284*bc5b5ea0SMelanie Blower // CHECK-FAST: Function Attrs: noinline nounwind 285*bc5b5ea0SMelanie Blower // CHECK-NOHONOR Function Attrs: noinline nounwind 286*bc5b5ea0SMelanie Blower // CHECK-LABEL: define{{.*}} @_GLOBAL__sub_I_fp_floatcontrol_stack 287