[flang-commits] [flang] d393ce3 - [flang] Support extension intrinsic function variations on ABS

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Jan 13 17:33:05 PST 2022


Author: Peter Klausler
Date: 2022-01-13T17:10:44-08:00
New Revision: d393ce3b3e8a80c55844ec1386ec38764d95843c

URL: https://github.com/llvm/llvm-project/commit/d393ce3b3e8a80c55844ec1386ec38764d95843c
DIFF: https://github.com/llvm/llvm-project/commit/d393ce3b3e8a80c55844ec1386ec38764d95843c.diff

LOG: [flang] Support extension intrinsic function variations on ABS

Accept the legacy specific intrinsic names BABS, IIABS, JIABS,
KIABS, and ZABS as well.

Differential Revision: https://reviews.llvm.org/D117155

Added: 
    

Modified: 
    flang/docs/Extensions.md
    flang/lib/Evaluate/fold-integer.cpp
    flang/lib/Evaluate/fold-real.cpp
    flang/lib/Evaluate/intrinsics-library.cpp
    flang/lib/Evaluate/intrinsics.cpp
    flang/test/Evaluate/folding02.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index e58176e89befa..c5d1e7c060d54 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -199,6 +199,7 @@ end
 * Objects in blank COMMON may be initialized.
 * Multiple specifications of the SAVE attribute on the same object
   are allowed, with a warning.
+* Specific intrinsic functions BABS, IIABS, JIABS, KIABS, ZABS, and CDABS.
 
 ### Extensions supported when enabled by options
 

diff  --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index ea8d779f27aab..f7a661da2f800 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -413,7 +413,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
   auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
   CHECK(intrinsic);
   std::string name{intrinsic->name};
-  if (name == "abs") {
+  if (name == "abs") { // incl. babs, iiabs, jiaabs, & kiabs
     return FoldElementalIntrinsic<T, T>(context, std::move(funcRef),
         ScalarFunc<T, T>([&context](const Scalar<T> &i) -> Scalar<T> {
           typename Scalar<T>::ValueWithOverflow j{i.ABS()};

diff  --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index f73b733dce6e6..f7c7f5713fd8d 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -64,7 +64,7 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
             name, KIND);
       }
     }
-  } else if (name == "abs") {
+  } else if (name == "abs") { // incl. zabs & cdabs
     // Argument can be complex or real
     if (auto *x{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
       return FoldElementalIntrinsic<T, T>(

diff  --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp
index e1e1c97c3f024..8230a595e6a6e 100644
--- a/flang/lib/Evaluate/intrinsics-library.cpp
+++ b/flang/lib/Evaluate/intrinsics-library.cpp
@@ -202,13 +202,12 @@ template <typename HostT, LibraryVersion> struct HostRuntimeLibrary {
 using HostRuntimeMap = common::StaticMultimapView<HostRuntimeFunction>;
 
 // Map numerical intrinsic to  <cmath>/<complex> functions
+// (Note: ABS() is folded in fold-real.cpp.)
 template <typename HostT>
 struct HostRuntimeLibrary<HostT, LibraryVersion::Libm> {
   using F = FuncPointer<HostT, HostT>;
   using F2 = FuncPointer<HostT, HostT, HostT>;
-  using ComplexToRealF = FuncPointer<HostT, const std::complex<HostT> &>;
   static constexpr HostRuntimeFunction table[]{
-      FolderFactory<ComplexToRealF, ComplexToRealF{std::abs}>::Create("abs"),
       FolderFactory<F, F{std::acos}>::Create("acos"),
       FolderFactory<F, F{std::acosh}>::Create("acosh"),
       FolderFactory<F, F{std::asin}>::Create("asin"),

diff  --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 4dd0df1c9693e..a29d6865c2aa2 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -87,11 +87,13 @@ ENUM_CLASS(KindCode, none, defaultIntegerKind,
     size, // default KIND= for SIZE(), UBOUND, &c.
     addressable, // for PRESENT(), &c.; anything (incl. procedure) but BOZ
     nullPointerType, // for ASSOCIATED(NULL())
+    exactKind, // a single explicit exactKindValue
 )
 
 struct TypePattern {
   CategorySet categorySet;
   KindCode kindCode{KindCode::none};
+  int exactKindValue{0}; // for KindCode::exactBind
   llvm::raw_ostream &Dump(llvm::raw_ostream &) const;
 };
 
@@ -914,6 +916,9 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
     {{"asin", {{"x", DefaultReal}}, DefaultReal}},
     {{"atan", {{"x", DefaultReal}}, DefaultReal}},
     {{"atan2", {{"y", DefaultReal}, {"x", DefaultReal}}, DefaultReal}},
+    {{"babs", {{"a", TypePattern{IntType, KindCode::exactKind, 1}}},
+         TypePattern{IntType, KindCode::exactKind, 1}},
+        "abs"},
     {{"cabs", {{"a", DefaultComplex}}, DefaultReal}, "abs"},
     {{"ccos", {{"a", DefaultComplex}}, DefaultComplex}, "cos"},
     {{"cdabs", {{"a", DoublePrecisionComplex}}, DoublePrecision}, "abs"},
@@ -988,9 +993,18 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
     {{"idint", {{"a", AnyReal}}, DefaultInt}, "int", true},
     {{"idnint", {{"a", DoublePrecision}}, DefaultInt}, "nint"},
     {{"ifix", {{"a", AnyReal}}, DefaultInt}, "int", true},
+    {{"iiabs", {{"a", TypePattern{IntType, KindCode::exactKind, 2}}},
+         TypePattern{IntType, KindCode::exactKind, 2}},
+        "abs"},
     {{"index", {{"string", DefaultChar}, {"substring", DefaultChar}},
         DefaultInt}},
     {{"isign", {{"a", DefaultInt}, {"b", DefaultInt}}, DefaultInt}, "sign"},
+    {{"jiabs", {{"a", TypePattern{IntType, KindCode::exactKind, 4}}},
+         TypePattern{IntType, KindCode::exactKind, 4}},
+        "abs"},
+    {{"kiabs", {{"a", TypePattern{IntType, KindCode::exactKind, 8}}},
+         TypePattern{IntType, KindCode::exactKind, 8}},
+        "abs"},
     {{"len", {{"string", DefaultChar, Rank::anyOrAssumedRank}}, DefaultInt,
         Rank::scalar}},
     {{"lge", {{"string_a", DefaultChar}, {"string_b", DefaultChar}},
@@ -1036,6 +1050,9 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
     {{"sqrt", {{"x", DefaultReal}}, DefaultReal}},
     {{"tan", {{"x", DefaultReal}}, DefaultReal}},
     {{"tanh", {{"x", DefaultReal}}, DefaultReal}},
+    {{"zabs", {{"a", TypePattern{ComplexType, KindCode::exactKind, 8}}},
+         TypePattern{RealType, KindCode::exactKind, 8}},
+        "abs"},
 };
 
 static const IntrinsicInterface intrinsicSubroutine[]{
@@ -1424,6 +1441,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
     case KindCode::nullPointerType:
       argOk = true;
       break;
+    case KindCode::exactKind:
+      argOk = type->kind() == d.typePattern.exactKindValue;
+      break;
     default:
       CRASH_NO_CASE;
     }
@@ -1694,6 +1714,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
       resultType = DynamicType{
           GetBuiltinDerivedType(builtinsScope, "__builtin_team_type")};
       break;
+    case KindCode::exactKind:
+      resultType = DynamicType{*category, result.exactKindValue};
+      break;
     case KindCode::defaultCharKind:
     case KindCode::typeless:
     case KindCode::any:

diff  --git a/flang/test/Evaluate/folding02.f90 b/flang/test/Evaluate/folding02.f90
index 9b0ab2b03e8f0..7ee3652734845 100644
--- a/flang/test/Evaluate/folding02.f90
+++ b/flang/test/Evaluate/folding02.f90
@@ -261,4 +261,18 @@ module m
     (1.3223499632715445262221010125358588993549346923828125_8, &
      1.7371201007364975854585509296157397329807281494140625_8))
 
+! Extension specific intrinsic variants of ABS
+  logical, parameter, test_babs1 = kind(babs(-1_1)) == 1
+  logical, parameter, test_babs2 = babs(-1_1) == 1_1
+  logical, parameter, test_iiabs1 = kind(iiabs(-1_2)) == 2
+  logical, parameter, test_iiabs2 = iiabs(-1_2) == 1_2
+  logical, parameter, test_jiabs1 = kind(jiabs(-1_4)) == 4
+  logical, parameter, test_jiabs2 = jiabs(-1_4) == 1_4
+  logical, parameter, test_kiabs1 = kind(kiabs(-1_8)) == 8
+  logical, parameter, test_kiabs2 = kiabs(-1_8) == 1_8
+  logical, parameter, test_zabs1 = kind(zabs((3._8,4._8))) == 8
+  logical, parameter, test_zabs2 = zabs((3._8,4._8)) == 5_8
+  logical, parameter, test_cdabs1 = kind(cdabs((3._8,4._8))) == kind(1.d0)
+  logical, parameter, test_cdabs2 = cdabs((3._8,4._8)) == real(5, kind(1.d0))
+
 end


        


More information about the flang-commits mailing list