Skip to content

Commit 62d4cc8

Browse files
authored
[flang] Modifications to ieee_support_standard (#128895)
Some Arm processors support exception halting control and some do not. An Arm executable will run on either type of processor, so it is effectively unknown at compile time whether or not this support will be available. ieee_support_halting is therefore implemented with a runtime check. The result of a call to ieee_support_standard depends in part on support for halting control. Update the ieee_support_standard implementation to check for support for halting control at runtime.
1 parent 70828d9 commit 62d4cc8

File tree

5 files changed

+57
-36
lines changed

5 files changed

+57
-36
lines changed

flang/docs/Extensions.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,15 @@ end
150150
have this capability. An Arm executable will run on either type of
151151
processor, so it is effectively unknown at compile time whether or
152152
not this support will be available at runtime. The standard requires
153-
that a call to intrinsic module procedure `IEEE_SUPPORT_HALTING` with
153+
that a call to intrinsic module procedure `ieee_support_halting` with
154154
a constant argument has a compile time constant result in `constant
155155
expression` and `specification expression` contexts. In compilations
156156
where this information is not known at compile time, f18 generates code
157157
to determine the absence or presence of this capability at runtime.
158-
A call to `IEEE_SUPPORT_HALTING` in contexts that the standard requires
159-
to be constant will generate a compilation error.
158+
A call to `ieee_support_halting` in contexts that the standard requires
159+
to be constant will generate a compilation error. `ieee_support_standard`
160+
depends in part on `ieee_support_halting`, so this also applies to
161+
`ieee_support_standard` calls.
160162

161163
## Extensions, deletions, and legacy features supported by default
162164

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,10 @@ struct IntrinsicLibrary {
313313
llvm::ArrayRef<fir::ExtendedValue>);
314314
fir::ExtendedValue genIeeeSupportHalting(mlir::Type,
315315
llvm::ArrayRef<fir::ExtendedValue>);
316-
mlir::Value genIeeeSupportRounding(mlir::Type, llvm::ArrayRef<mlir::Value>);
316+
fir::ExtendedValue genIeeeSupportRounding(mlir::Type,
317+
llvm::ArrayRef<fir::ExtendedValue>);
318+
fir::ExtendedValue genIeeeSupportStandard(mlir::Type,
319+
llvm::ArrayRef<fir::ExtendedValue>);
317320
template <mlir::arith::CmpIPredicate pred>
318321
mlir::Value genIeeeTypeCompare(mlir::Type, llvm::ArrayRef<mlir::Value>);
319322
mlir::Value genIeeeUnordered(mlir::Type, llvm::ArrayRef<mlir::Value>);

flang/lib/Evaluate/fold-logical.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
882882
IeeeFeature::Flags)};
883883
} else if (name == "__builtin_ieee_support_halting") {
884884
if (!context.targetCharacteristics()
885-
.haltingSupportIsUnknownAtCompileTime()) {
885+
.haltingSupportIsUnknownAtCompileTime()) {
886886
return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
887887
IeeeFeature::Halting)};
888888
}
@@ -906,8 +906,12 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
906906
return Expr<T>{
907907
context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Sqrt)};
908908
} else if (name == "__builtin_ieee_support_standard") {
909-
return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
910-
IeeeFeature::Standard)};
909+
// ieee_support_standard depends in part on ieee_support_halting.
910+
if (!context.targetCharacteristics()
911+
.haltingSupportIsUnknownAtCompileTime()) {
912+
return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
913+
IeeeFeature::Standard)};
914+
}
911915
} else if (name == "__builtin_ieee_support_subnormal") {
912916
return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
913917
IeeeFeature::Subnormal)};

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,45 +1022,35 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
10221022
{"__builtin_ieee_next_up", {{"x", SameReal}}, SameReal},
10231023
{"__builtin_ieee_real", {{"a", AnyIntOrReal}, DefaultingKIND}, KINDReal},
10241024
{"__builtin_ieee_support_datatype",
1025-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1026-
DefaultLogical},
1025+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10271026
{"__builtin_ieee_support_denormal",
1028-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1029-
DefaultLogical},
1027+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10301028
{"__builtin_ieee_support_divide",
1031-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1032-
DefaultLogical},
1029+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10331030
{"__builtin_ieee_support_flag",
10341031
{{"flag", IeeeFlagType, Rank::scalar},
1035-
{"x", AnyReal, Rank::elemental, Optionality::optional}},
1032+
{"x", AnyReal, Rank::known, Optionality::optional}},
10361033
DefaultLogical},
10371034
{"__builtin_ieee_support_halting", {{"flag", IeeeFlagType, Rank::scalar}},
10381035
DefaultLogical},
10391036
{"__builtin_ieee_support_inf",
1040-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1041-
DefaultLogical},
1037+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10421038
{"__builtin_ieee_support_io",
1043-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1044-
DefaultLogical},
1039+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10451040
{"__builtin_ieee_support_nan",
1046-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1047-
DefaultLogical},
1041+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10481042
{"__builtin_ieee_support_rounding",
10491043
{{"round_value", IeeeRoundType, Rank::scalar},
1050-
{"x", AnyReal, Rank::elemental, Optionality::optional}},
1044+
{"x", AnyReal, Rank::known, Optionality::optional}},
10511045
DefaultLogical},
10521046
{"__builtin_ieee_support_sqrt",
1053-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1054-
DefaultLogical},
1047+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10551048
{"__builtin_ieee_support_standard",
1056-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1057-
DefaultLogical},
1049+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10581050
{"__builtin_ieee_support_subnormal",
1059-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1060-
DefaultLogical},
1051+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10611052
{"__builtin_ieee_support_underflow_control",
1062-
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
1063-
DefaultLogical},
1053+
{{"x", AnyReal, Rank::known, Optionality::optional}}, DefaultLogical},
10641054
{"__builtin_numeric_storage_size", {}, DefaultInt},
10651055
};
10661056

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,18 @@ static constexpr IntrinsicHandler handlers[]{
456456
&I::genIeeeSupportFlag,
457457
{{{"flag", asValue}, {"x", asInquired, handleDynamicOptional}}},
458458
/*isElemental=*/false},
459-
{"ieee_support_halting", &I::genIeeeSupportHalting},
460-
{"ieee_support_rounding", &I::genIeeeSupportRounding},
459+
{"ieee_support_halting",
460+
&I::genIeeeSupportHalting,
461+
{{{"flag", asValue}}},
462+
/*isElemental=*/false},
463+
{"ieee_support_rounding",
464+
&I::genIeeeSupportRounding,
465+
{{{"round_value", asValue}, {"x", asInquired, handleDynamicOptional}}},
466+
/*isElemental=*/false},
467+
{"ieee_support_standard",
468+
&I::genIeeeSupportStandard,
469+
{{{"flag", asValue}, {"x", asInquired, handleDynamicOptional}}},
470+
/*isElemental=*/false},
461471
{"ieee_unordered", &I::genIeeeUnordered},
462472
{"ieee_value", &I::genIeeeValue},
463473
{"ieor", &I::genIeor},
@@ -5629,7 +5639,7 @@ IntrinsicLibrary::genIeeeSupportFlag(mlir::Type resultType,
56295639
// is therefore ignored. Standard flags are all supported. The nonstandard
56305640
// DENORM extension is not supported, at least for now.
56315641
assert(args.size() == 1 || args.size() == 2);
5632-
auto [fieldRef, fieldTy] = getFieldRef(builder, loc, fir::getBase(args[0]));
5642+
auto [fieldRef, fieldTy] = getFieldRef(builder, loc, getBase(args[0]));
56335643
mlir::Value flag = builder.create<fir::LoadOp>(loc, fieldRef);
56345644
mlir::Value mask = builder.createIntegerConstant( // values are powers of 2
56355645
loc, fieldTy,
@@ -5661,9 +5671,8 @@ fir::ExtendedValue IntrinsicLibrary::genIeeeSupportHalting(
56615671
}
56625672

56635673
// IEEE_SUPPORT_ROUNDING
5664-
mlir::Value
5665-
IntrinsicLibrary::genIeeeSupportRounding(mlir::Type resultType,
5666-
llvm::ArrayRef<mlir::Value> args) {
5674+
fir::ExtendedValue IntrinsicLibrary::genIeeeSupportRounding(
5675+
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
56675676
// Check if floating point rounding mode ROUND_VALUE is supported.
56685677
// Rounding is supported either for all type kinds or none.
56695678
// An optional X kind argument is therefore ignored.
@@ -5674,7 +5683,7 @@ IntrinsicLibrary::genIeeeSupportRounding(mlir::Type resultType,
56745683
// 3 - toward negative infinity [supported]
56755684
// 4 - to nearest, ties away from zero [not supported]
56765685
assert(args.size() == 1 || args.size() == 2);
5677-
auto [fieldRef, fieldTy] = getFieldRef(builder, loc, args[0]);
5686+
auto [fieldRef, fieldTy] = getFieldRef(builder, loc, getBase(args[0]));
56785687
mlir::Value mode = builder.create<fir::LoadOp>(loc, fieldRef);
56795688
mlir::Value lbOk = builder.create<mlir::arith::CmpIOp>(
56805689
loc, mlir::arith::CmpIPredicate::sge, mode,
@@ -5687,6 +5696,19 @@ IntrinsicLibrary::genIeeeSupportRounding(mlir::Type resultType,
56875696
loc, resultType, builder.create<mlir::arith::AndIOp>(loc, lbOk, ubOk));
56885697
}
56895698

5699+
// IEEE_SUPPORT_STANDARD
5700+
fir::ExtendedValue IntrinsicLibrary::genIeeeSupportStandard(
5701+
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
5702+
// Check if IEEE standard support is available, which reduces to checking
5703+
// if halting control is supported, as that is the only support component
5704+
// that may not be available.
5705+
assert(args.size() <= 1);
5706+
mlir::Value nearest = builder.createIntegerConstant(
5707+
loc, builder.getIntegerType(32), _FORTRAN_RUNTIME_IEEE_NEAREST);
5708+
return builder.createConvert(
5709+
loc, resultType, fir::runtime::genSupportHalting(builder, loc, nearest));
5710+
}
5711+
56905712
// IEEE_UNORDERED
56915713
mlir::Value
56925714
IntrinsicLibrary::genIeeeUnordered(mlir::Type resultType,

0 commit comments

Comments
 (0)