Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -37,6 +37,12 @@ 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">, + InGroup; +def warn_fe_backend_unsupported_fp_exceptions : Warning< + "overriding currently unsupported use of floating point exceptions " + "on this target">, InGroup; def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo, InGroup; Index: clang/include/clang/Basic/DiagnosticGroups.td =================================================================== --- clang/include/clang/Basic/DiagnosticGroups.td +++ clang/include/clang/Basic/DiagnosticGroups.td @@ -107,6 +107,7 @@ def EnumTooLarge : DiagGroup<"enum-too-large">; def UnsupportedNan : DiagGroup<"unsupported-nan">; def UnsupportedAbs : DiagGroup<"unsupported-abs">; +def UnsupportedFPOpt : DiagGroup<"unsupported-floating-point-opt">; def UnsupportedCB : DiagGroup<"unsupported-cb">; def UnsupportedGPOpt : DiagGroup<"unsupported-gpopt">; def UnsupportedTargetOpt : DiagGroup<"unsupported-target-opt">; Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -192,6 +192,7 @@ bool HasFloat128; bool HasFloat16; bool HasBFloat16; + bool HasStrictFP; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short SimdDefaultAlign; @@ -577,6 +578,9 @@ /// Determine whether the _BFloat16 type is supported on this target. virtual bool hasBFloat16Type() const { return HasBFloat16; } + /// 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; } Index: clang/lib/Basic/TargetInfo.cpp =================================================================== --- clang/lib/Basic/TargetInfo.cpp +++ clang/lib/Basic/TargetInfo.cpp @@ -37,6 +37,7 @@ HasFloat128 = false; HasFloat16 = false; HasBFloat16 = false; + HasStrictFP = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; Index: clang/lib/Basic/Targets/PPC.h =================================================================== --- clang/lib/Basic/Targets/PPC.h +++ clang/lib/Basic/Targets/PPC.h @@ -82,6 +82,8 @@ SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); + + HasStrictFP = true; } // Set the language option for altivec based on our value. Index: clang/lib/Basic/Targets/SystemZ.h =================================================================== --- clang/lib/Basic/Targets/SystemZ.h +++ 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, Index: clang/lib/Basic/Targets/X86.h =================================================================== --- clang/lib/Basic/Targets/X86.h +++ clang/lib/Basic/Targets/X86.h @@ -138,6 +138,7 @@ : TargetInfo(Triple) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); AddrSpaceMap = &X86AddrSpaceMap; + HasStrictFP = true; } const char *getLongDoubleMangling() const override { Index: clang/lib/Frontend/CompilerInstance.cpp =================================================================== --- clang/lib/Frontend/CompilerInstance.cpp +++ 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 Index: clang/test/CodeGen/aarch64-neon-misc-constrained.c =================================================================== --- clang/test/CodeGen/aarch64-neon-misc-constrained.c +++ 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 Index: clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c =================================================================== --- clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c +++ 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 Index: clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c =================================================================== --- clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c +++ 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 Index: clang/test/CodeGen/arm-neon-directed-rounding-constrained.c =================================================================== --- clang/test/CodeGen/arm-neon-directed-rounding-constrained.c +++ 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 Index: clang/test/CodeGen/arm64-vrnd-constrained.c =================================================================== --- clang/test/CodeGen/arm64-vrnd-constrained.c +++ 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); } Index: clang/test/CodeGen/fp-strictfp.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/fp-strictfp.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips64-linux-gnu -frounding-math -ffp-exception-behavior=strict -O2 -verify=rounding,exception -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple mips64-linux-gnu -ffp-exception-behavior=strict -O2 -verify=exception -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple mips64-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 float{{.*}} +// CHECK: fadd float %[[M]], %c + return a * b + c; +} + +