[flang] Make IEEE_INT and IEEE_REAL into builtin intrinsic functions (#109191)

For proper error detection of bad KIND= arguments, make IEEE_INT and
IEEE_REAL actual intrinsic functions. Lowering will have to check for
the new __builtin_ names.
This commit is contained in:
Peter Klausler 2024-09-20 13:52:02 -07:00 committed by GitHub
parent 2e414799d0
commit 751389218e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 57 deletions

View File

@ -935,12 +935,16 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"__builtin_compiler_version", {}, DefaultChar},
{"__builtin_fma", {{"f1", SameReal}, {"f2", SameReal}, {"f3", SameReal}},
SameReal},
{"__builtin_ieee_int",
{{"a", AnyFloating}, {"round", IeeeRoundType}, DefaultingKIND},
KINDInt},
{"__builtin_ieee_is_nan", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_is_negative", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_next_after", {{"x", SameReal}, {"y", AnyReal}}, SameReal},
{"__builtin_ieee_next_down", {{"x", SameReal}}, SameReal},
{"__builtin_ieee_next_up", {{"x", SameReal}}, SameReal},
{"__builtin_ieee_real", {{"a", AnyIntOrReal}, DefaultingKIND}, KINDReal},
{"__builtin_ieee_support_datatype",
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
DefaultLogical},

View File

@ -108,11 +108,13 @@ module __fortran_builtins
end type
intrinsic :: __builtin_fma
intrinsic :: __builtin_ieee_int
intrinsic :: __builtin_ieee_is_nan, __builtin_ieee_is_negative, &
__builtin_ieee_is_normal
intrinsic :: __builtin_ieee_next_after, __builtin_ieee_next_down, &
__builtin_ieee_next_up
intrinsic :: scale ! for ieee_scalb
intrinsic :: __builtin_ieee_real
intrinsic :: __builtin_ieee_selected_real_kind
intrinsic :: __builtin_ieee_support_datatype, &
__builtin_ieee_support_denormal, __builtin_ieee_support_divide, &
@ -123,10 +125,12 @@ module __fortran_builtins
__builtin_ieee_support_standard, __builtin_ieee_support_subnormal, &
__builtin_ieee_support_underflow_control
public :: __builtin_fma
public :: __builtin_ieee_int
public :: __builtin_ieee_is_nan, __builtin_ieee_is_negative, &
__builtin_ieee_is_normal
public :: __builtin_ieee_next_after, __builtin_ieee_next_down, &
__builtin_ieee_next_up
public :: __builtin_ieee_real
public :: scale ! for ieee_scalb
public :: __builtin_ieee_selected_real_kind
public :: __builtin_ieee_support_datatype, &

View File

@ -21,6 +21,7 @@ module ieee_arithmetic
ieee_away => __builtin_ieee_away, &
ieee_down => __builtin_ieee_down, &
ieee_fma => __builtin_fma, &
ieee_int => __builtin_ieee_int, &
ieee_is_nan => __builtin_ieee_is_nan, &
ieee_is_negative => __builtin_ieee_is_negative, &
ieee_is_normal => __builtin_ieee_is_normal, &
@ -29,6 +30,7 @@ module ieee_arithmetic
ieee_next_down => __builtin_ieee_next_down, &
ieee_next_up => __builtin_ieee_next_up, &
ieee_other => __builtin_ieee_other, &
ieee_real => __builtin_ieee_real, &
ieee_round_type => __builtin_ieee_round_type, &
ieee_scalb => scale, &
ieee_selected_real_kind => __builtin_ieee_selected_real_kind, &
@ -57,6 +59,7 @@ module ieee_arithmetic
public :: ieee_away
public :: ieee_down
public :: ieee_fma
public :: ieee_int
public :: ieee_is_nan
public :: ieee_is_negative
public :: ieee_is_normal
@ -65,6 +68,7 @@ module ieee_arithmetic
public :: ieee_next_after
public :: ieee_next_down
public :: ieee_next_up
public :: ieee_real
public :: ieee_round_type
public :: ieee_scalb
public :: ieee_selected_real_kind
@ -303,29 +307,6 @@ module ieee_arithmetic
public :: ieee_get_underflow_mode
#undef IEEE_GET_UNDERFLOW_MODE_L
! When kind argument is present, kind(result) is value(kind), not kind(kind).
! That is not known here, so return integer(16).
#define IEEE_INT_R(AKIND) \
elemental integer function ieee_int_a##AKIND(a, round); \
import ieee_round_type; \
real(AKIND), intent(in) :: a; \
type(ieee_round_type), intent(in) :: round; \
end function ieee_int_a##AKIND;
#define IEEE_INT_RI(AKIND, KKIND) \
elemental integer(16) function ieee_int_a##AKIND##_i##KKIND(a, round, kind); \
import ieee_round_type; \
real(AKIND), intent(in) :: a; \
type(ieee_round_type), intent(in) :: round; \
integer(KKIND), intent(in) :: kind; \
end function ieee_int_a##AKIND##_i##KKIND;
interface ieee_int
SPECIFICS_R(IEEE_INT_R)
SPECIFICS_RI(IEEE_INT_RI)
end interface ieee_int
public :: ieee_int
#undef IEEE_INT_R
#undef IEEE_INT_RI
#define IEEE_IS_FINITE_R(XKIND) \
elemental logical function ieee_is_finite_a##XKIND(x); \
real(XKIND), intent(in) :: x; \
@ -486,40 +467,6 @@ module ieee_arithmetic
public :: ieee_quiet_ne
#undef IEEE_QUIET_NE_R
! When kind argument is present, kind(result) is value(kind), not kind(kind).
! That is not known here, so return real(16).
#define IEEE_REAL_I(AKIND) \
elemental real function ieee_real_i##AKIND(a); \
integer(AKIND), intent(in) :: a; \
end function ieee_real_i##AKIND;
#define IEEE_REAL_R(AKIND) \
elemental real function ieee_real_a##AKIND(a); \
real(AKIND), intent(in) :: a; \
end function ieee_real_a##AKIND;
#define IEEE_REAL_II(AKIND, KKIND) \
elemental real(16) function ieee_real_i##AKIND##_i##KKIND(a, kind); \
integer(AKIND), intent(in) :: a; \
integer(KKIND), intent(in) :: kind; \
end function ieee_real_i##AKIND##_i##KKIND;
#define IEEE_REAL_RI(AKIND, KKIND) \
elemental real(16) function ieee_real_a##AKIND##_i##KKIND(a, kind); \
real(AKIND), intent(in) :: a; \
integer(KKIND), intent(in) :: kind; \
end function ieee_real_a##AKIND##_i##KKIND;
interface ieee_real
SPECIFICS_I(IEEE_REAL_I)
SPECIFICS_R(IEEE_REAL_R)
#if FLANG_SUPPORT_R16
SPECIFICS_II(IEEE_REAL_II)
SPECIFICS_RI(IEEE_REAL_RI)
#endif
end interface ieee_real
public :: ieee_real
#undef IEEE_REAL_I
#undef IEEE_REAL_R
#undef IEEE_REAL_II
#undef IEEE_REAL_RI
#define IEEE_REM_RR(XKIND, YKIND) \
elemental real(XKIND) function ieee_rem_a##XKIND##_a##YKIND(x, y); \
real(XKIND), intent(in) :: x; \

View File

@ -0,0 +1,12 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
use ieee_arithmetic, only: ieee_int, ieee_real, ieee_up
implicit none
print *, ieee_int(1.5, ieee_up)
print *, ieee_int(1.5, ieee_up, 4)
!ERROR: 'kind=' argument must be a constant scalar integer whose value is a supported kind for the intrinsic result type
print *, ieee_int(1.5, ieee_up, 3)
print *, ieee_real(1)
print *, ieee_real(1, 4)
!ERROR: 'kind=' argument must be a constant scalar integer whose value is a supported kind for the intrinsic result type
print *, ieee_real(1, 7)
end