[flang] Implement IEEE_SUPPORT_xxx inquiry functions
Implement IEEE_SUPPORT_DATATYPE() and other inquiry intrinisic
functions from the intrinsic module IEEE_ARITHMETIC, folding all of
their results to .TRUE.
Differential Revision: https://reviews.llvm.org/D95830
GitOrigin-RevId: aa39ddd0a320c1d615171fef98694e5726c3fa4f
diff --git a/lib/Evaluate/fold-logical.cpp b/lib/Evaluate/fold-logical.cpp
index 827127f..64e4bd8 100644
--- a/lib/Evaluate/fold-logical.cpp
+++ b/lib/Evaluate/fold-logical.cpp
@@ -108,6 +108,18 @@
}
} else if (name == "merge") {
return FoldMerge<T>(context, std::move(funcRef));
+ } else if (name == "__builtin_ieee_support_datatype" ||
+ name == "__builtin_ieee_support_denormal" ||
+ name == "__builtin_ieee_support_divide" ||
+ 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") {
+ return Expr<T>{true};
}
// TODO: btest, cshift, dot_product, eoshift, is_iostat_end,
// is_iostat_eor, lge, lgt, lle, llt, logical, matmul, out_of_range,
diff --git a/lib/Evaluate/intrinsics.cpp b/lib/Evaluate/intrinsics.cpp
index 98fbe92..b54ff78 100644
--- a/lib/Evaluate/intrinsics.cpp
+++ b/lib/Evaluate/intrinsics.cpp
@@ -772,6 +772,36 @@
{"back", AnyLogical, Rank::elemental, Optionality::optional},
DefaultingKIND},
KINDInt},
+ {"__builtin_ieee_support_datatype",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_denormal",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_divide",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_inf",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_io",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_nan",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_sqrt",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_standard",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_subnormal",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_underflow_control",
+ {{"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
};
// TODO: Coarray intrinsic functions
diff --git a/module/__fortran_builtins.f90 b/module/__fortran_builtins.f90
index 852a7a9..c9cf111 100644
--- a/module/__fortran_builtins.f90
+++ b/module/__fortran_builtins.f90
@@ -31,4 +31,11 @@
end type
procedure(type(__builtin_c_ptr)) :: __builtin_c_loc
+
+ intrinsic :: __builtin_ieee_support_datatype, &
+ __builtin_ieee_support_denormal, __builtin_ieee_support_divide, &
+ __builtin_ieee_support_inf, __builtin_ieee_support_io, &
+ __builtin_ieee_support_nan, __builtin_ieee_support_sqrt, &
+ __builtin_ieee_support_standard, __builtin_ieee_support_subnormal, &
+ __builtin_ieee_support_underflow_control
end module
diff --git a/module/ieee_arithmetic.f90 b/module/ieee_arithmetic.f90
index 3e0ad85..488a950 100644
--- a/module/ieee_arithmetic.f90
+++ b/module/ieee_arithmetic.f90
@@ -9,6 +9,18 @@
! See Fortran 2018, clause 17.2
module ieee_arithmetic
+ use __Fortran_builtins, only: &
+ ieee_support_datatype => __builtin_ieee_support_datatype, &
+ ieee_support_denormal => __builtin_ieee_support_denormal, &
+ ieee_support_divide => __builtin_ieee_support_divide, &
+ ieee_support_inf => __builtin_ieee_support_inf, &
+ ieee_support_io => __builtin_ieee_support_io, &
+ ieee_support_nan => __builtin_ieee_support_nan, &
+ ieee_support_sqrt => __builtin_ieee_support_sqrt, &
+ ieee_support_standard => __builtin_ieee_support_standard, &
+ ieee_support_subnormal => __builtin_ieee_support_subnormal, &
+ ieee_support_underflow_control => __builtin_ieee_support_underflow_control
+
type :: ieee_class_type
private
integer(kind=1) :: which = 0
@@ -72,6 +84,15 @@
module procedure ieee_copy_sign_a16
end interface ieee_copy_sign
+ generic :: ieee_support_rounding => ieee_support_rounding_, &
+ ieee_support_rounding_2, ieee_support_rounding_3, &
+ ieee_support_rounding_4, ieee_support_rounding_8, &
+ ieee_support_rounding_10, ieee_support_rounding_16
+ private :: ieee_support_rounding_, &
+ ieee_support_rounding_2, ieee_support_rounding_3, &
+ ieee_support_rounding_4, ieee_support_rounding_8, &
+ ieee_support_rounding_10, ieee_support_rounding_16
+
! TODO: more interfaces (_fma, &c.)
private :: classify
@@ -181,4 +202,39 @@
_COPYSIGN(16,16,128)
#undef _COPYSIGN
+ pure logical function ieee_support_rounding_(round_type)
+ type(ieee_round_type), intent(in) :: round_type
+ ieee_support_rounding_ = .true.
+ end function
+ pure logical function ieee_support_rounding_2(round_type,x)
+ type(ieee_round_type), intent(in) :: round_type
+ real(kind=2), intent(in) :: x
+ ieee_support_rounding_2 = .true.
+ end function
+ pure logical function ieee_support_rounding_3(round_type,x)
+ type(ieee_round_type), intent(in) :: round_type
+ real(kind=3), intent(in) :: x
+ ieee_support_rounding_3 = .true.
+ end function
+ pure logical function ieee_support_rounding_4(round_type,x)
+ type(ieee_round_type), intent(in) :: round_type
+ real(kind=4), intent(in) :: x
+ ieee_support_rounding_4 = .true.
+ end function
+ pure logical function ieee_support_rounding_8(round_type,x)
+ type(ieee_round_type), intent(in) :: round_type
+ real(kind=8), intent(in) :: x
+ ieee_support_rounding_8 = .true.
+ end function
+ pure logical function ieee_support_rounding_10(round_type,x)
+ type(ieee_round_type), intent(in) :: round_type
+ real(kind=10), intent(in) :: x
+ ieee_support_rounding_10 = .true.
+ end function
+ pure logical function ieee_support_rounding_16(round_type,x)
+ type(ieee_round_type), intent(in) :: round_type
+ real(kind=16), intent(in) :: x
+ ieee_support_rounding_16 = .true.
+ end function
+
end module ieee_arithmetic
diff --git a/test/Evaluate/folding18.f90 b/test/Evaluate/folding18.f90
new file mode 100644
index 0000000..613e57a
--- /dev/null
+++ b/test/Evaluate/folding18.f90
@@ -0,0 +1,75 @@
+! RUN: %S/test_folding.sh %s %t %f18
+! Test implementations of IEEE inquiry functions
+module m
+ use ieee_arithmetic
+ logical, parameter :: test_ieee_support_datatype = ieee_support_datatype() &
+ .and. ieee_support_datatype(1.0_2) &
+ .and. ieee_support_datatype(1.0_3) &
+ .and. ieee_support_datatype(1.0_4) &
+ .and. ieee_support_datatype(1.0_8) &
+ .and. ieee_support_datatype(1.0_10) &
+ .and. ieee_support_datatype(1.0_16)
+ logical, parameter :: test_ieee_support_denormal = ieee_support_denormal() &
+ .and. ieee_support_denormal(1.0_2) &
+ .and. ieee_support_denormal(1.0_3) &
+ .and. ieee_support_denormal(1.0_4) &
+ .and. ieee_support_denormal(1.0_8) &
+ .and. ieee_support_denormal(1.0_10) &
+ .and. ieee_support_denormal(1.0_16)
+ logical, parameter :: test_ieee_support_divide = ieee_support_divide() &
+ .and. ieee_support_divide(1.0_2) &
+ .and. ieee_support_divide(1.0_3) &
+ .and. ieee_support_divide(1.0_4) &
+ .and. ieee_support_divide(1.0_8) &
+ .and. ieee_support_divide(1.0_10) &
+ .and. ieee_support_divide(1.0_16)
+ logical, parameter :: test_ieee_support_inf = ieee_support_inf() &
+ .and. ieee_support_inf(1.0_2) &
+ .and. ieee_support_inf(1.0_3) &
+ .and. ieee_support_inf(1.0_4) &
+ .and. ieee_support_inf(1.0_8) &
+ .and. ieee_support_inf(1.0_10) &
+ .and. ieee_support_inf(1.0_16)
+ logical, parameter :: test_ieee_support_io = ieee_support_io() &
+ .and. ieee_support_io(1.0_2) &
+ .and. ieee_support_io(1.0_3) &
+ .and. ieee_support_io(1.0_4) &
+ .and. ieee_support_io(1.0_8) &
+ .and. ieee_support_io(1.0_10) &
+ .and. ieee_support_io(1.0_16)
+ logical, parameter :: test_ieee_support_nan = ieee_support_nan() &
+ .and. ieee_support_nan(1.0_2) &
+ .and. ieee_support_nan(1.0_3) &
+ .and. ieee_support_nan(1.0_4) &
+ .and. ieee_support_nan(1.0_8) &
+ .and. ieee_support_nan(1.0_10) &
+ .and. ieee_support_nan(1.0_16)
+ logical, parameter :: test_ieee_support_sqrt = ieee_support_sqrt() &
+ .and. ieee_support_sqrt(1.0_2) &
+ .and. ieee_support_sqrt(1.0_3) &
+ .and. ieee_support_sqrt(1.0_4) &
+ .and. ieee_support_sqrt(1.0_8) &
+ .and. ieee_support_sqrt(1.0_10) &
+ .and. ieee_support_sqrt(1.0_16)
+ logical, parameter :: test_ieee_support_standard = ieee_support_standard() &
+ .and. ieee_support_standard(1.0_2) &
+ .and. ieee_support_standard(1.0_3) &
+ .and. ieee_support_standard(1.0_4) &
+ .and. ieee_support_standard(1.0_8) &
+ .and. ieee_support_standard(1.0_10) &
+ .and. ieee_support_standard(1.0_16)
+ logical, parameter :: test_ieee_support_subnormal = ieee_support_subnormal() &
+ .and. ieee_support_subnormal(1.0_2) &
+ .and. ieee_support_subnormal(1.0_3) &
+ .and. ieee_support_subnormal(1.0_4) &
+ .and. ieee_support_subnormal(1.0_8) &
+ .and. ieee_support_subnormal(1.0_10) &
+ .and. ieee_support_subnormal(1.0_16)
+ logical, parameter :: test_ieee_support_underflow_control = ieee_support_underflow_control() &
+ .and. ieee_support_underflow_control(1.0_2) &
+ .and. ieee_support_underflow_control(1.0_3) &
+ .and. ieee_support_underflow_control(1.0_4) &
+ .and. ieee_support_underflow_control(1.0_8) &
+ .and. ieee_support_underflow_control(1.0_10) &
+ .and. ieee_support_underflow_control(1.0_16)
+end module