diff options
Diffstat (limited to 'flang/lib/Evaluate/fold-logical.cpp')
-rw-r--r-- | flang/lib/Evaluate/fold-logical.cpp | 69 |
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)}; } |