diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -37,6 +37,11 @@ def warn_fe_override_module : Warning< "overriding the module target triple with %0">, InGroup>; +def warn_fe_backend_unsupported_fp_rounding : Warning< + "overriding currently unsupported rounding mode on this target">; +def warn_fe_backend_unsupported_fp_exceptions : Warning< + "overriding currently unsupported use of floating point exceptions " + "on this target">; def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo, InGroup; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -188,6 +188,7 @@ // LLVM IR type. bool HasFloat128; bool HasFloat16; + bool HasStrictFP; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short SimdDefaultAlign; @@ -567,6 +568,9 @@ /// Determine whether the _Float16 type is supported on this target. virtual bool hasFloat16Type() const { return HasFloat16; } + /// Determine whether constrained floating point is supported on this target. + virtual bool hasStrictFP() const { return HasStrictFP; } + /// Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -36,6 +36,7 @@ HasLegalHalfType = false; HasFloat128 = false; HasFloat16 = false; + HasStrictFP = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -48,6 +48,7 @@ MinGlobalAlign = 16; resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + HasStrictFP = true; } void getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -149,6 +149,7 @@ : TargetInfo(Triple) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); AddrSpaceMap = &X86AddrSpaceMap; + HasStrictFP = true; } const char *getLongDoubleMangling() const override { diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -935,6 +935,19 @@ setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); } + if (!getTarget().hasStrictFP()) { + if (getLangOpts().getFPRoundingMode() != + llvm::RoundingMode::NearestTiesToEven) { + getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_rounding); + getLangOpts().setFPRoundingMode(llvm::RoundingMode::NearestTiesToEven); + } + if (getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore) { + getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_exceptions); + getLangOpts().setFPExceptionMode(LangOptions::FPE_Ignore); + } + // FIXME: can we disable FEnvAccess? + } + // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once diff --git a/clang/test/CodeGen/aarch64-neon-misc-constrained.c b/clang/test/CodeGen/aarch64-neon-misc-constrained.c --- a/clang/test/CodeGen/aarch64-neon-misc-constrained.c +++ b/clang/test/CodeGen/aarch64-neon-misc-constrained.c @@ -15,6 +15,9 @@ // REQUIRES: aarch64-registered-target +// Disabled until constrained floating point is implemented for arm64. +// XFAIL: * + // Test new aarch64 intrinsics and types but constrained #include diff --git a/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c b/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c --- a/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c +++ b/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c @@ -15,6 +15,9 @@ // REQUIRES: aarch64-registered-target +// Disabled until constrained floating point is implemented for arm64. +// XFAIL: * + // Test new aarch64 intrinsics and types but constrained #include diff --git a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c --- a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c +++ b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c @@ -19,6 +19,9 @@ // REQUIRES: aarch64-registered-target +// Disabled until constrained floating point is implemented for arm64. +// XFAIL: * + #include // COMMON-LABEL: test_vsqrt_f16 diff --git a/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c b/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c --- a/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c +++ b/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c @@ -32,6 +32,9 @@ // REQUIRES: arm-registered-target,aarch64-registered-target +// Disabled until constrained floating point is implemented for arm64. +// XFAIL: * + #include // COMMON-LABEL: test_vrndi_f32 diff --git a/clang/test/CodeGen/arm64-vrnd-constrained.c b/clang/test/CodeGen/arm64-vrnd-constrained.c --- a/clang/test/CodeGen/arm64-vrnd-constrained.c +++ b/clang/test/CodeGen/arm64-vrnd-constrained.c @@ -9,6 +9,9 @@ // REQUIRES: aarch64-registered-target +// Disabled until constrained floating point is implemented for arm64. +// XFAIL: * + #include float64x2_t rnd5(float64x2_t a) { return vrndq_f64(a); } diff --git a/clang/test/CodeGen/fp-strictfp.cpp b/clang/test/CodeGen/fp-strictfp.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/fp-strictfp.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple powerpc64-linux-gnu -frounding-math -ffp-exception-behavior=strict -O2 -verify=rounding,exception -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-linux-gnu -ffp-exception-behavior=strict -O2 -verify=exception -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-linux-gnu -frounding-math -O2 -verify=rounding -emit-llvm -o - %s | FileCheck %s +// +// Verify that constrained intrinsics are not used. +// As more targets gain support for constrained intrinsics the triple +// in this test will need to change. + +// rounding-warning@* {{overriding currently unsupported rounding mode on this target}} +// exception-warning@* {{overriding currently unsupported use of floating point exceptions on this target}} +float fp_precise_1(float a, float b, float c) { +// CHECK: _Z12fp_precise_1fff +// CHECK: %[[M:.+]] = fmul fast float{{.*}} +// CHECK: fadd fast float %[[M]], %c +#pragma float_control(precise, off) + return a * b + c; +} + +