[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