aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Evaluate/fold-logical.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Evaluate/fold-logical.cpp')
-rw-r--r--flang/lib/Evaluate/fold-logical.cpp69
1 files changed, 59 insertions, 10 deletions
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index a7c655b..ee6655f 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -620,6 +620,24 @@ static Expr<Type<TypeCategory::Logical, KIND>> RewriteOutOfRange(
return AsExpr(std::move(funcRef));
}
+static std::optional<common::RoundingMode> GetRoundingMode(
+ const std::optional<ActualArgument> &arg) {
+ if (arg) {
+ if (const auto *cst{UnwrapExpr<Constant<SomeDerived>>(*arg)}) {
+ if (auto constr{cst->GetScalarValue()}) {
+ if (StructureConstructorValues & values{constr->values()};
+ values.size() == 1) {
+ const Expr<SomeType> &value{values.begin()->second.value()};
+ if (auto code{ToInt64(value)}) {
+ return static_cast<common::RoundingMode>(*code);
+ }
+ }
+ }
+ }
+ }
+ return std::nullopt;
+}
+
template <int KIND>
Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
FoldingContext &context,
@@ -831,17 +849,48 @@ 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") {
+ if (context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Rounding)) {
+ if (auto mode{GetRoundingMode(args[0])}) {
+ return Expr<T>{mode != common::RoundingMode::TiesAwayFromZero};
+ }
+ }
+ } 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)};
}