// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s
// 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
// 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
// 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
// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
float fun_default //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
// Note that backend wants constrained intrinsics used
// throughout the function if they are needed anywhere in the function.
// In that case, operations are built with constrained intrinsics operator
// but using default settings for exception behavior and rounding mode.
//CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
// Rule: precise must be enabled
// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
float exc_on //CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
//CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
//Not possible to enable float_control(except) in FAST mode.
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}}
// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
float exc_pop //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
float exc_off //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}}
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
float precise_on //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
// If precise is pushed then all fast-math should be off!
//CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}}
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
float precise_pop //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
float precise_off // Note: precise_off enables fp_contract=fast and the instructions
// generated do not include the contract flag, although it was enabled
// in IRBuilder.
//CHECK-DDEFAULT: fmul fast float
//CHECK-DDEFAULT: fadd fast float
//CHECK-DEBSTRICT: fmul fast float
//CHECK-DEBSTRICT: fadd fast float
// fast math should be enabled, and contract should be fast
//CHECK-NOHONOR: fmul fast float
//CHECK-NOHONOR: fadd fast float
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
float precise_on2 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
// fast math should be off, and contract should be on
//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
float precise_push //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
float precise_off2 //CHECK-DDEFAULT: fmul fast float
//CHECK-DDEFAULT: fadd fast float
//CHECK-DEBSTRICT: fmul fast float
//CHECK-DEBSTRICT: fadd fast float
// fast math settings since precise is off
//CHECK-NOHONOR: fmul fast float
//CHECK-NOHONOR: fadd fast float
//CHECK-FAST: fmul fast float
//CHECK-FAST: fadd fast float
float precise_pop2 //CHECK-DDEFAULT: llvm.fmuladd{{.*}}
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
// Rule: precise must be enabled
float ;
// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}}
// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}}
;
ON on;
// CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}}
// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}}
// CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}}
// CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}}
;
OFF off;
;
MyComplex
// CHECK-DDEFAULT: Function Attrs: noinline nounwind{{$$}}
// CHECK-DEBSTRICT: Function Attrs: noinline nounwind strictfp{{$$}}
// CHECK-FAST: Function Attrs: noinline nounwind{{$$}}
// CHECK-NOHONOR: Function Attrs: noinline nounwind{{$$}}
// CHECK-LABEL: define{{.*}} @_GLOBAL__sub_I_fp_floatcontrol_stack