254 lines
7.0 KiB
C++
254 lines
7.0 KiB
C++
// 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
|
|
|
|
#define FUN(n) \
|
|
(float z) { return n * z + n; }
|
|
|
|
float fun_default FUN(1)
|
|
//CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
// 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
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
|
|
#pragma float_control(push)
|
|
#ifndef FAST
|
|
// Rule: precise must be enabled
|
|
#pragma float_control(except, on)
|
|
#endif
|
|
float exc_on FUN(2)
|
|
//CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
|
|
#endif
|
|
#if FAST
|
|
//Not possible to enable float_control(except) in FAST mode.
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
|
|
#pragma float_control(pop)
|
|
float exc_pop FUN(5)
|
|
//CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
|
|
#pragma float_control(except, off)
|
|
float exc_off FUN(5)
|
|
//CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
|
|
#pragma float_control(precise, on, push)
|
|
float precise_on FUN(3)
|
|
//CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if NOHONOR
|
|
// If precise is pushed then all fast-math should be off!
|
|
//CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
|
|
#pragma float_control(pop)
|
|
float precise_pop FUN(3)
|
|
//CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
#pragma float_control(precise, off)
|
|
float precise_off FUN(4)
|
|
//CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}}
|
|
#if DEFAULT
|
|
// 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
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: fmul fast float
|
|
//CHECK-DEBSTRICT: fadd fast float
|
|
#endif
|
|
#if NOHONOR
|
|
// fast math should be enabled, and contract should be fast
|
|
//CHECK-NOHONOR: fmul fast float
|
|
//CHECK-NOHONOR: fadd fast float
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
|
|
#pragma float_control(precise, on)
|
|
float precise_on2 FUN(3)
|
|
//CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if NOHONOR
|
|
// fast math should be off, and contract should be on
|
|
//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
|
|
#pragma float_control(push)
|
|
float precise_push FUN(3)
|
|
//CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
|
|
#pragma float_control(precise, off)
|
|
float precise_off2 FUN(4)
|
|
//CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: fmul fast float
|
|
//CHECK-DDEFAULT: fadd fast float
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: fmul fast float
|
|
//CHECK-DEBSTRICT: fadd fast float
|
|
#endif
|
|
#if NOHONOR
|
|
// fast math settings since precise is off
|
|
//CHECK-NOHONOR: fmul fast float
|
|
//CHECK-NOHONOR: fadd fast float
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
|
|
#pragma float_control(pop)
|
|
float precise_pop2 FUN(3)
|
|
//CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
|
|
#endif
|
|
|
|
#ifndef FAST
|
|
// Rule: precise must be enabled
|
|
#pragma float_control(except, on)
|
|
#endif
|
|
float y();
|
|
class ON {
|
|
// Settings for top level class initializer revert to command line
|
|
// source pragma's do not pertain.
|
|
float z = 2 + y() * 7;
|
|
//CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: call float {{.*}}llvm.fmuladd
|
|
#endif
|
|
#if EBSTRICT
|
|
//Currently, same as default [command line options not considered]
|
|
//CHECK-DEBSTRICT: call float {{.*}}llvm.fmuladd
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
};
|
|
ON on;
|
|
#pragma float_control(except, off)
|
|
class OFF {
|
|
float w = 2 + y() * 7;
|
|
//CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
|
|
#if DEFAULT
|
|
//CHECK-DDEFAULT: call float {{.*}}llvm.fmuladd
|
|
#endif
|
|
#if EBSTRICT
|
|
//CHECK-DEBSTRICT: call float {{.*}}llvm.fmuladd
|
|
#endif
|
|
#if NOHONOR
|
|
//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}}
|
|
#endif
|
|
#if FAST
|
|
//CHECK-FAST: fmul fast float
|
|
//CHECK-FAST: fadd fast float
|
|
#endif
|
|
};
|
|
OFF off;
|