[flang-commits] [flang] [flang] Fold IEEE_SUPPORT_xxx() intrinsic functions (PR #95866)

via flang-commits flang-commits at lists.llvm.org
Mon Jun 17 16:37:12 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

All of the IEEE_SUPPORT_xxx() intrinsic functions must fold to constant logical values when they have constant arguments; and since they fold to .TRUE. for currently support architectures, always fold them.  But also put in the infrastructure whereby a driver can initialize Evaluate's target information to set some of them to .FALSE. if that becomes necessary.

---

Patch is 185.06 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/95866.diff


20 Files Affected:

- (modified) flang/include/flang/Common/Fortran.h (+5-3) 
- (modified) flang/include/flang/Evaluate/common.h (+3-3) 
- (modified) flang/include/flang/Evaluate/target.h (+15) 
- (modified) flang/include/flang/Evaluate/tools.h (+4) 
- (modified) flang/include/flang/Optimizer/Builder/IntrinsicCall.h (-4) 
- (modified) flang/lib/Evaluate/fold-logical.cpp (+37-10) 
- (modified) flang/lib/Evaluate/intrinsics.cpp (+25) 
- (modified) flang/lib/Evaluate/tools.cpp (+8) 
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (-57) 
- (modified) flang/module/__fortran_builtins.f90 (+44-2) 
- (modified) flang/module/__fortran_ieee_exceptions.f90 (+13-40) 
- (modified) flang/module/ieee_arithmetic.f90 (+18-30) 
- (added) flang/test/Evaluate/fold-ieee.f90 (+64) 
- (modified) flang/test/Lower/Intrinsics/ieee_femodes.f90 (+30-30) 
- (modified) flang/test/Lower/Intrinsics/ieee_festatus.f90 (+26-26) 
- (modified) flang/test/Lower/Intrinsics/ieee_flag.f90 (+89-104) 
- (modified) flang/test/Lower/Intrinsics/ieee_logb.f90 (+6-6) 
- (modified) flang/test/Lower/Intrinsics/ieee_max_min.f90 (+34-34) 
- (modified) flang/test/Lower/Intrinsics/ieee_operator_eq.f90 (+18-18) 
- (modified) flang/test/Lower/Intrinsics/ieee_rounding.f90 (+11-23) 


``````````diff
diff --git a/flang/include/flang/Common/Fortran.h b/flang/include/flang/Common/Fortran.h
index 0701e3e8b64cc..5b2ed43a8f99c 100644
--- a/flang/include/flang/Common/Fortran.h
+++ b/flang/include/flang/Common/Fortran.h
@@ -67,12 +67,14 @@ ENUM_CLASS(
 const char *AsFortran(DefinedIo);
 
 // Floating-point rounding modes; these are packed into a byte to save
-// room in the runtime's format processing context structure.
+// room in the runtime's format processing context structure.  These
+// enumerators are defined with the corresponding values returned from
+// llvm.get.rounding.
 enum class RoundingMode : std::uint8_t {
-  TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
   ToZero, // ROUND=ZERO, RZ - truncation
-  Down, // ROUND=DOWN, RD
+  TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
   Up, // ROUND=UP, RU
+  Down, // ROUND=DOWN, RD
   TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
 };
 
diff --git a/flang/include/flang/Evaluate/common.h b/flang/include/flang/Evaluate/common.h
index c2c7711c4684e..d493e5fe04417 100644
--- a/flang/include/flang/Evaluate/common.h
+++ b/flang/include/flang/Evaluate/common.h
@@ -128,9 +128,9 @@ static constexpr bool Satisfies(RelationalOperator op, Relation relation) {
   return false; // silence g++ warning
 }
 
-ENUM_CLASS(
-    RealFlag, Overflow, DivideByZero, InvalidArgument, Underflow, Inexact)
-
+// These are ordered like the bits in a common fenv.h header file.
+ENUM_CLASS(RealFlag, InvalidArgument, Denorm, DivideByZero, Overflow, Underflow,
+    Inexact)
 using RealFlags = common::EnumSet<RealFlag, RealFlag_enumSize>;
 
 template <typename A> struct ValueWithRealFlags {
diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h
index 10033d02a5409..d076fcbf08307 100644
--- a/flang/include/flang/Evaluate/target.h
+++ b/flang/include/flang/Evaluate/target.h
@@ -13,6 +13,8 @@
 #define FORTRAN_EVALUATE_TARGET_H_
 
 #include "flang/Common/Fortran.h"
+#include "flang/Common/enum-class.h"
+#include "flang/Common/enum-set.h"
 #include "flang/Evaluate/common.h"
 #include <cstdint>
 
@@ -32,6 +34,11 @@ struct Rounding {
 #endif
 };
 
+ENUM_CLASS(IeeeFeature, Denormal, Divide, Flags, Halting, Inf, Io, NaN,
+    Rounding, Sqrt, Standard, Subnormal, UnderflowControl)
+
+using IeeeFeatures = common::EnumSet<IeeeFeature, 16>;
+
 class TargetCharacteristics {
 public:
   TargetCharacteristics();
@@ -95,6 +102,9 @@ class TargetCharacteristics {
   bool isPPC() const { return isPPC_; }
   void set_isPPC(bool isPPC = false);
 
+  IeeeFeatures &ieeeFeatures() { return ieeeFeatures_; }
+  const IeeeFeatures &ieeeFeatures() const { return ieeeFeatures_; }
+
 private:
   static constexpr int maxKind{32};
   std::uint8_t byteSize_[common::TypeCategory_enumSize][maxKind]{};
@@ -110,6 +120,11 @@ class TargetCharacteristics {
   std::size_t maxAlignment_{8 /*at least*/};
   std::string compilerOptionsString_;
   std::string compilerVersionString_;
+  IeeeFeatures ieeeFeatures_{IeeeFeature::Denormal, IeeeFeature::Divide,
+      IeeeFeature::Flags, IeeeFeature::Halting, IeeeFeature::Inf,
+      IeeeFeature::Io, IeeeFeature::NaN, IeeeFeature::Rounding,
+      IeeeFeature::Sqrt, IeeeFeature::Standard, IeeeFeature::Subnormal,
+      IeeeFeature::UnderflowControl};
 };
 
 } // namespace Fortran::evaluate
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index 378a5fca03264..35640c283f52d 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -1320,6 +1320,10 @@ bool IsBuiltinCPtr(const Symbol &);
 bool IsEventType(const DerivedTypeSpec *);
 bool IsLockType(const DerivedTypeSpec *);
 bool IsNotifyType(const DerivedTypeSpec *);
+// Is this derived type IEEE_FLAG_TYPE from module ISO_IEEE_EXCEPTIONS?
+bool IsIeeeFlagType(const DerivedTypeSpec *);
+// Is this derived type IEEE_ROUND_TYPE from module ISO_IEEE_ARITHMETIC?
+bool IsIeeeRoundType(const DerivedTypeSpec *);
 // Is this derived type TEAM_TYPE from module ISO_FORTRAN_ENV?
 bool IsTeamType(const DerivedTypeSpec *);
 // Is this derived type TEAM_TYPE, C_PTR, or C_FUNPTR?
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index ec1fb411ff0e2..d3c44d00b79f9 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -275,10 +275,6 @@ struct IntrinsicLibrary {
   mlir::Value genIeeeSignalingCompare(mlir::Type resultType,
                                       llvm::ArrayRef<mlir::Value>);
   mlir::Value genIeeeSignbit(mlir::Type, llvm::ArrayRef<mlir::Value>);
-  fir::ExtendedValue
-      genIeeeSupportFlagOrHalting(mlir::Type,
-                                  llvm::ArrayRef<fir::ExtendedValue>);
-  mlir::Value genIeeeSupportRounding(mlir::Type, llvm::ArrayRef<mlir::Value>);
   template <mlir::arith::CmpIPredicate pred>
   mlir::Value genIeeeTypeCompare(mlir::Type, llvm::ArrayRef<mlir::Value>);
   mlir::Value genIeeeUnordered(mlir::Type, llvm::ArrayRef<mlir::Value>);
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index a7c655b72f56e..37c2ae6c6bbe5 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -831,17 +831,44 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
         }
       }
     }
-  } else if (name == "__builtin_ieee_support_datatype" ||
-      name == "__builtin_ieee_support_denormal" ||
-      name == "__builtin_ieee_support_divide" ||
-      name == "__builtin_ieee_support_inf" ||
-      name == "__builtin_ieee_support_io" ||
-      name == "__builtin_ieee_support_nan" ||
-      name == "__builtin_ieee_support_sqrt" ||
-      name == "__builtin_ieee_support_standard" ||
-      name == "__builtin_ieee_support_subnormal" ||
-      name == "__builtin_ieee_support_underflow_control") {
+  } else if (name == "__builtin_ieee_support_datatype") {
     return Expr<T>{true};
+  } else if (name == "__builtin_ieee_support_denormal") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Denormal)};
+  } else if (name == "__builtin_ieee_support_divide") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Divide)};
+  } else if (name == "__builtin_ieee_support_flag") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Flags)};
+  } else if (name == "__builtin_ieee_support_halting") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Halting)};
+  } else if (name == "__builtin_ieee_support_inf") {
+    return Expr<T>{
+        context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Inf)};
+  } else if (name == "__builtin_ieee_support_io") {
+    return Expr<T>{
+        context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Io)};
+  } else if (name == "__builtin_ieee_support_nan") {
+    return Expr<T>{
+        context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::NaN)};
+  } else if (name == "__builtin_ieee_support_rounding") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Rounding)};
+  } else if (name == "__builtin_ieee_support_sqrt") {
+    return Expr<T>{
+        context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Sqrt)};
+  } else if (name == "__builtin_ieee_support_standard") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Standard)};
+  } else if (name == "__builtin_ieee_support_subnormal") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::Subnormal)};
+  } else if (name == "__builtin_ieee_support_underflow_control") {
+    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+        IeeeFeature::UnderflowControl)};
   }
   return Expr<T>{std::move(funcRef)};
 }
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index ace316174a892..5b3dcd65ecd55 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -88,6 +88,8 @@ ENUM_CLASS(KindCode, none, defaultIntegerKind,
     sameKind,
     operand, // match any kind, with promotion (non-standard)
     typeless, // BOZ literals are INTEGER with this kind
+    ieeeFlagType, // IEEE_FLAG_TYPE from ISO_FORTRAN_EXCEPTION
+    ieeeRoundType, // IEEE_ROUND_TYPE from ISO_FORTRAN_ARITHMETIC
     teamType, // TEAM_TYPE from module ISO_FORTRAN_ENV (for coarrays)
     kindArg, // this argument is KIND=
     effectiveKind, // for function results: "kindArg" value, possibly defaulted
@@ -121,6 +123,9 @@ static constexpr TypePattern DefaultChar{CharType, KindCode::defaultCharKind};
 static constexpr TypePattern DefaultLogical{
     LogicalType, KindCode::defaultLogicalKind};
 static constexpr TypePattern BOZ{IntType, KindCode::typeless};
+static constexpr TypePattern IeeeFlagType{DerivedType, KindCode::ieeeFlagType};
+static constexpr TypePattern IeeeRoundType{
+    DerivedType, KindCode::ieeeRoundType};
 static constexpr TypePattern TeamType{DerivedType, KindCode::teamType};
 static constexpr TypePattern DoublePrecision{
     RealType, KindCode::doublePrecision};
@@ -940,6 +945,12 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
     {"__builtin_ieee_support_divide",
         {{"x", AnyReal, Rank::elemental, Optionality::optional}},
         DefaultLogical},
+    {"__builtin_ieee_support_flag",
+        {{"flag", IeeeFlagType, Rank::scalar},
+            {"x", AnyReal, Rank::elemental, Optionality::optional}},
+        DefaultLogical},
+    {"__builtin_ieee_support_halting", {{"flag", IeeeFlagType, Rank::scalar}},
+        DefaultLogical},
     {"__builtin_ieee_support_inf",
         {{"x", AnyReal, Rank::elemental, Optionality::optional}},
         DefaultLogical},
@@ -949,6 +960,10 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
     {"__builtin_ieee_support_nan",
         {{"x", AnyReal, Rank::elemental, Optionality::optional}},
         DefaultLogical},
+    {"__builtin_ieee_support_rounding",
+        {{"round_value", IeeeRoundType, Rank::scalar},
+            {"x", AnyReal, Rank::elemental, Optionality::optional}},
+        DefaultLogical},
     {"__builtin_ieee_support_sqrt",
         {{"x", AnyReal, Rank::elemental, Optionality::optional}},
         DefaultLogical},
@@ -1851,6 +1866,16 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
     case KindCode::typeless:
       argOk = false;
       break;
+    case KindCode::ieeeFlagType:
+      argOk = !type->IsUnlimitedPolymorphic() &&
+          type->category() == TypeCategory::Derived &&
+          semantics::IsIeeeFlagType(&type->GetDerivedTypeSpec());
+      break;
+    case KindCode::ieeeRoundType:
+      argOk = !type->IsUnlimitedPolymorphic() &&
+          type->category() == TypeCategory::Derived &&
+          semantics::IsIeeeRoundType(&type->GetDerivedTypeSpec());
+      break;
     case KindCode::teamType:
       argOk = !type->IsUnlimitedPolymorphic() &&
           type->category() == TypeCategory::Derived &&
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 4699c5312868c..19fabb693a1ce 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -1790,6 +1790,14 @@ bool IsNotifyType(const DerivedTypeSpec *derived) {
   return IsBuiltinDerivedType(derived, "notify_type");
 }
 
+bool IsIeeeFlagType(const DerivedTypeSpec *derived) {
+  return IsBuiltinDerivedType(derived, "ieee_flag_type");
+}
+
+bool IsIeeeRoundType(const DerivedTypeSpec *derived) {
+  return IsBuiltinDerivedType(derived, "ieee_round_type");
+}
+
 bool IsTeamType(const DerivedTypeSpec *derived) {
   return IsBuiltinDerivedType(derived, "team_type");
 }
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 3204369b9328a..6f1c43ed74540 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -373,12 +373,6 @@ static constexpr IntrinsicHandler handlers[]{
     {"ieee_signaling_ne",
      &I::genIeeeSignalingCompare<mlir::arith::CmpFPredicate::UNE>},
     {"ieee_signbit", &I::genIeeeSignbit},
-    {"ieee_support_flag",
-     &I::genIeeeSupportFlagOrHalting,
-     {{{"flag", asValue}, {"x", asInquired, handleDynamicOptional}}},
-     /*isElemental=*/false},
-    {"ieee_support_halting", &I::genIeeeSupportFlagOrHalting},
-    {"ieee_support_rounding", &I::genIeeeSupportRounding},
     {"ieee_unordered", &I::genIeeeUnordered},
     {"ieee_value", &I::genIeeeValue},
     {"ieor", &I::genIeor},
@@ -4710,57 +4704,6 @@ mlir::Value IntrinsicLibrary::genIeeeSignbit(mlir::Type resultType,
   return builder.createConvert(loc, resultType, sign);
 }
 
-// IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING
-fir::ExtendedValue IntrinsicLibrary::genIeeeSupportFlagOrHalting(
-    mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
-  // Check if a floating point exception or halting mode FLAG is supported.
-  // An IEEE_SUPPORT_FLAG flag is supported either for all type kinds or none.
-  // An optional kind argument X is therefore ignored.
-  // Standard flags are all supported.
-  // The nonstandard DENORM extension is not supported. (At least for now.)
-  assert(args.size() == 1 || args.size() == 2);
-  auto [fieldRef, fieldTy] = getFieldRef(builder, loc, fir::getBase(args[0]));
-  mlir::Value flag = builder.create<fir::LoadOp>(loc, fieldRef);
-  mlir::Value mask = builder.createIntegerConstant( // values are powers of 2
-      loc, fieldTy,
-      _FORTRAN_RUNTIME_IEEE_INVALID | _FORTRAN_RUNTIME_IEEE_DIVIDE_BY_ZERO |
-          _FORTRAN_RUNTIME_IEEE_OVERFLOW | _FORTRAN_RUNTIME_IEEE_UNDERFLOW |
-          _FORTRAN_RUNTIME_IEEE_INEXACT);
-  return builder.createConvert(
-      loc, resultType,
-      builder.create<mlir::arith::CmpIOp>(
-          loc, mlir::arith::CmpIPredicate::ne,
-          builder.create<mlir::arith::AndIOp>(loc, flag, mask),
-          builder.createIntegerConstant(loc, fieldTy, 0)));
-}
-
-// IEEE_SUPPORT_ROUNDING
-mlir::Value
-IntrinsicLibrary::genIeeeSupportRounding(mlir::Type resultType,
-                                         llvm::ArrayRef<mlir::Value> args) {
-  // Check if floating point rounding mode ROUND_VALUE is supported.
-  // Rounding is supported either for all type kinds or none.
-  // An optional X kind argument is therefore ignored.
-  // Values are chosen to match the llvm.get.rounding encoding:
-  //  0 - toward zero [supported]
-  //  1 - to nearest, ties to even [supported] - default
-  //  2 - toward positive infinity [supported]
-  //  3 - toward negative infinity [supported]
-  //  4 - to nearest, ties away from zero [not supported]
-  assert(args.size() == 1 || args.size() == 2);
-  auto [fieldRef, fieldTy] = getFieldRef(builder, loc, args[0]);
-  mlir::Value mode = builder.create<fir::LoadOp>(loc, fieldRef);
-  mlir::Value lbOk = builder.create<mlir::arith::CmpIOp>(
-      loc, mlir::arith::CmpIPredicate::sge, mode,
-      builder.createIntegerConstant(loc, fieldTy,
-                                    _FORTRAN_RUNTIME_IEEE_TO_ZERO));
-  mlir::Value ubOk = builder.create<mlir::arith::CmpIOp>(
-      loc, mlir::arith::CmpIPredicate::sle, mode,
-      builder.createIntegerConstant(loc, fieldTy, _FORTRAN_RUNTIME_IEEE_DOWN));
-  return builder.createConvert(
-      loc, resultType, builder.create<mlir::arith::AndIOp>(loc, lbOk, ubOk));
-}
-
 // IEEE_UNORDERED
 mlir::Value
 IntrinsicLibrary::genIeeeUnordered(mlir::Type resultType,
diff --git a/flang/module/__fortran_builtins.f90 b/flang/module/__fortran_builtins.f90
index 4746ca20a13a7..b33d843710127 100644
--- a/flang/module/__fortran_builtins.f90
+++ b/flang/module/__fortran_builtins.f90
@@ -6,6 +6,8 @@
 !
 !===------------------------------------------------------------------------===!
 
+include '../include/flang/Runtime/magic-numbers.h'
+
 ! These naming shenanigans prevent names from Fortran intrinsic modules
 ! from being usable on INTRINSIC statements, and force the program
 ! to USE the standard intrinsic modules in order to access the
@@ -49,6 +51,42 @@
     integer(kind=int64), private :: __count
   end type
 
+  type, public :: __builtin_ieee_flag_type
+    integer(kind=1), private :: flag = 0
+  end type
+
+  type(__builtin_ieee_flag_type), parameter, public :: &
+    __builtin_ieee_invalid = &
+      __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INVALID), &
+    __builtin_ieee_overflow = &
+      __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_OVERFLOW), &
+    __builtin_ieee_divide_by_zero = &
+      __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_DIVIDE_BY_ZERO), &
+    __builtin_ieee_underflow = &
+      __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_UNDERFLOW), &
+    __builtin_ieee_inexact = &
+      __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INEXACT), &
+    __builtin_ieee_denorm = & ! extension
+      __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_DENORM)
+
+  type, public :: __builtin_ieee_round_type
+    integer(kind=1), private :: mode = 0
+  end type
+
+  type(__builtin_ieee_round_type), parameter, public :: &
+    __builtin_ieee_to_zero = &
+      __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_TO_ZERO), &
+    __builtin_ieee_nearest = &
+      __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_NEAREST), &
+    __builtin_ieee_up = &
+      __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_UP), &
+    __builtin_ieee_down = &
+      __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_DOWN), &
+    __builtin_ieee_away = &
+      __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_AWAY), &
+    __builtin_ieee_other = &
+      __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_OTHER)
+
   type, public :: __builtin_team_type
     integer(kind=int64), private :: __id
   end type
@@ -74,8 +112,10 @@
   intrinsic :: __builtin_ieee_selected_real_kind
   intrinsic :: __builtin_ieee_support_datatype, &
     __builtin_ieee_support_denormal, __builtin_ieee_support_divide, &
+    __builtin_ieee_support_flag, __builtin_ieee_support_halting, &
     __builtin_ieee_support_inf, __builtin_ieee_support_io, &
-    __builtin_ieee_support_nan, __builtin_ieee_support_sqrt, &
+    __builtin_ieee_support_nan, __builtin_ieee_support_rounding, &
+    __builtin_ieee_support_sqrt, &
     __builtin_ieee_support_standard, __builtin_ieee_support_subnormal, &
     __builtin_ieee_support_underflow_control
   public :: __builtin_fma
@@ -87,8 +127,10 @@
   public :: __builtin_ieee_selected_real_kind
   public :: __builtin_ieee_support_datatype, &
     __builtin_ieee_support_denormal, __builtin_ieee_support_divide, &
+    __builtin_ieee_support_flag, __builtin_ieee_support_halting, &
     __builtin_ieee_support_inf, __builtin_ieee_support_io, &
-    __builtin_ieee_support_nan, __builtin_ieee_support_sqrt, &
+    __builtin_ieee_support_nan, __builtin_ieee_support_rounding, &
+    __builtin_ieee_support_sqrt, &
     __builtin_ieee_support_standard, __builtin_ieee_support_subnormal, &
     __builtin_ieee_support_underflow_control
 
diff --git a/flang/module/__fortran_ieee_exceptions.f90 b/flang/module/__fortran_ieee_exceptions.f90
index afcd183553192..810a2b0e400f2 100644
--- a/flang/module/__fortran_ieee_exceptions.f90
+++ b/flang/module/__fortran_ieee_exceptions.f90
@@ -14,25 +14,22 @@
 include '../include/flang/Runtime/magic-numbers.h'
 
 module __fortran_ieee_exceptions
+  use __fortran_builtins, only: &
+    ieee_flag_type => __builtin_ieee_flag_type, &
+    ieee_support_flag => __builtin_ieee_support_flag, &
+    ieee_support_halting => __builtin_ieee_support_halting, &
+    ieee_invalid => __builtin_ieee_invalid, &
+    ieee_overflow => __builtin_ieee_overflow, &
+    ieee_divide_by_zero => __builtin_ieee_divide_by_zero, &
+    ieee_underflow => __builtin_ieee_underflow, &
+    ieee_inexact => __builtin_ieee_inexact, &
+    ieee_denorm => __builtin_ieee_denorm
   implicit none
-
-  ! Set PRIVATE by default to explicitly only export what is meant
-  ! to be exported by this MODULE.
   private
 
-  type, public :: ieee_flag_type ! Fortran 2018, 17.2 & 17.3
-    private
-    integer(kind=1) :: flag = 0
-  end type ieee_flag_type
-
-  type(ieee_flag_type), parameter, public :: &
-    ieee_invalid = ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INVALID), &
-    ieee_overflow = ieee_flag_t...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/95866


More information about the flang-commits mailing list