Author: peter klausler Date: 2021-01-22T10:08:51-08:00 New Revision: 59bf9a89d825c1f23b249e0ce43d8bf7b486a203
URL: https://github.com/llvm/llvm-project/commit/59bf9a89d825c1f23b249e0ce43d8bf7b486a203 DIFF: https://github.com/llvm/llvm-project/commit/59bf9a89d825c1f23b249e0ce43d8bf7b486a203.diff LOG: [flang] Remove some needless operations in expr rewriting Expressions emitted to module files and error messages sometimes contain conversions of integer results of inquiry intrinsics; these are usually not needed, and can conflict with "int" in the user's namespace. Improve folding so that these conversions don't appear, and do some other clean-up in adjacent code. Differential Revision: https://reviews.llvm.org/D95172 Added: Modified: flang/lib/Evaluate/fold-implementation.h flang/test/Semantics/modfile17.f90 flang/test/Semantics/modfile30.f90 Removed: ################################################################################ diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h index 7232715600fd..37116bb6bca4 100644 --- a/flang/lib/Evaluate/fold-implementation.h +++ b/flang/lib/Evaluate/fold-implementation.h @@ -1105,12 +1105,13 @@ Expr<TO> FoldOperation( // This variable is a workaround for msvc which emits an error when // using the FROMCAT template parameter below. TypeCategory constexpr FromCat{FROMCAT}; + static_assert(FromCat == Operand::category); auto &convert{msvcWorkaround.convert}; char buffer[64]; if (auto value{GetScalarConstantValue<Operand>(kindExpr)}) { FoldingContext &ctx{msvcWorkaround.context}; if constexpr (TO::category == TypeCategory::Integer) { - if constexpr (Operand::category == TypeCategory::Integer) { + if constexpr (FromCat == TypeCategory::Integer) { auto converted{Scalar<TO>::ConvertSigned(*value)}; if (converted.overflow) { ctx.messages().Say( @@ -1118,7 +1119,7 @@ Expr<TO> FoldOperation( Operand::kind, TO::kind); } return ScalarConstantToExpr(std::move(converted.value)); - } else if constexpr (Operand::category == TypeCategory::Real) { + } else if constexpr (FromCat == TypeCategory::Real) { auto converted{value->template ToInteger<Scalar<TO>>()}; if (converted.flags.test(RealFlag::InvalidArgument)) { ctx.messages().Say( @@ -1132,7 +1133,7 @@ Expr<TO> FoldOperation( return ScalarConstantToExpr(std::move(converted.value)); } } else if constexpr (TO::category == TypeCategory::Real) { - if constexpr (Operand::category == TypeCategory::Integer) { + if constexpr (FromCat == TypeCategory::Integer) { auto converted{Scalar<TO>::FromInteger(*value)}; if (!converted.flags.empty()) { std::snprintf(buffer, sizeof buffer, @@ -1141,7 +1142,7 @@ Expr<TO> FoldOperation( RealFlagWarnings(ctx, converted.flags, buffer); } return ScalarConstantToExpr(std::move(converted.value)); - } else if constexpr (Operand::category == TypeCategory::Real) { + } else if constexpr (FromCat == TypeCategory::Real) { auto converted{Scalar<TO>::Convert(*value)}; if (!converted.flags.empty()) { std::snprintf(buffer, sizeof buffer, @@ -1154,7 +1155,7 @@ Expr<TO> FoldOperation( return ScalarConstantToExpr(std::move(converted.value)); } } else if constexpr (TO::category == TypeCategory::Complex) { - if constexpr (Operand::category == TypeCategory::Complex) { + if constexpr (FromCat == TypeCategory::Complex) { return FoldOperation(ctx, ComplexConstructor<TO::kind>{ AsExpr(Convert<typename TO::Part>{AsCategoryExpr( @@ -1163,17 +1164,31 @@ Expr<TO> FoldOperation( Constant<typename Operand::Part>{value->AIMAG()})})}); } } else if constexpr (TO::category == TypeCategory::Character && - Operand::category == TypeCategory::Character) { + FromCat == TypeCategory::Character) { if (auto converted{ConvertString<Scalar<TO>>(std::move(*value))}) { return ScalarConstantToExpr(std::move(*converted)); } } else if constexpr (TO::category == TypeCategory::Logical && - Operand::category == TypeCategory::Logical) { + FromCat == TypeCategory::Logical) { return Expr<TO>{value->IsTrue()}; } - } else if constexpr (std::is_same_v<Operand, TO> && + } else if constexpr (TO::category == FromCat && FromCat != TypeCategory::Character) { - return std::move(kindExpr); // remove needless conversion + // Conversion of non-constant in same type category + if constexpr (std::is_same_v<Operand, TO>) { + return std::move(kindExpr); // remove needless conversion + } else if constexpr (std::is_same_v<TO, DescriptorInquiry::Result>) { + if (auto *innerConv{ + std::get_if<Convert<Operand, TypeCategory::Integer>>( + &kindExpr.u)}) { + if (auto *x{std::get_if<Expr<TO>>(&innerConv->left().u)}) { + if (std::holds_alternative<DescriptorInquiry>(x->u)) { + // int(int(size(...),kind=k),kind=8) -> size(...) + return std::move(*x); + } + } + } + } } return Expr<TO>{std::move(convert)}; }, @@ -1201,7 +1216,9 @@ Expr<T> FoldOperation(FoldingContext &context, Negate<T> &&x) { return *array; } auto &operand{x.left()}; - if (auto value{GetScalarConstantValue<T>(operand)}) { + if (auto *nn{std::get_if<Negate<T>>(&x.left().u)}) { + return std::move(nn->left()); // -(-x) -> x + } else if (auto value{GetScalarConstantValue<T>(operand)}) { if constexpr (T::category == TypeCategory::Integer) { auto negated{value->Negate()}; if (negated.overflow) { @@ -1308,6 +1325,20 @@ Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) { } return Expr<T>{Constant<T>{product.value}}; } + } else if constexpr (T::category == TypeCategory::Integer) { + if (auto c{GetScalarConstantValue<T>(x.right())}) { + x.right() = std::move(x.left()); + x.left() = Expr<T>{std::move(*c)}; + } + if (auto c{GetScalarConstantValue<T>(x.left())}) { + if (c->IsZero()) { + return std::move(x.left()); + } else if (c->CompareSigned(Scalar<T>{1}) == Ordering::Equal) { + return std::move(x.right()); + } else if (c->CompareSigned(Scalar<T>{-1}) == Ordering::Equal) { + return Expr<T>{Negate<T>{std::move(x.right())}}; + } + } } return Expr<T>{std::move(x)}; } diff --git a/flang/test/Semantics/modfile17.f90 b/flang/test/Semantics/modfile17.f90 index 414043c02d3a..3c7361b03bfd 100644 --- a/flang/test/Semantics/modfile17.f90 +++ b/flang/test/Semantics/modfile17.f90 @@ -98,7 +98,7 @@ module m !end type !type::defaulted(n1,n2,n4,n8) !integer(1),kind::n1=1_1 -!integer(2),kind::n2=int(int(int(n1,kind=1),kind=4)*2_4,kind=2) +!integer(2),kind::n2=int(2_4*int(int(n1,kind=1),kind=4),kind=2) !integer(4),kind::n4=2_4*int(int(n2,kind=2),kind=4) !integer(8),kind::n8=int(12_4-int(n4,kind=4),kind=8) !type(capture(k1=int(n1,kind=1),k2=int(n2,kind=2),k4=int(n4,kind=4),k8=n8))::cap diff --git a/flang/test/Semantics/modfile30.f90 b/flang/test/Semantics/modfile30.f90 index dba950c2737a..275f72cdbf67 100644 --- a/flang/test/Semantics/modfile30.f90 +++ b/flang/test/Semantics/modfile30.f90 @@ -19,11 +19,11 @@ function f2(x) !contains ! function f1(x) result(y) ! integer(4)::x(:) -! integer(4)::y(1_8:int(int(1_8*size(x,dim=1),kind=4),kind=8)) +! integer(4)::y(1_8:size(x,dim=1)) ! end ! function f2(x) ! integer(4)::x(:) -! integer(4)::f2(1_8:int(int(1_8*size(x,dim=1),kind=4),kind=8)) +! integer(4)::f2(1_8:size(x,dim=1)) ! end !end _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits