[flang-commits] [flang] b8f029c - [flang] Accept legacy aliases for intrinsic function names
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Mar 18 17:24:06 PDT 2022
Author: Peter Klausler
Date: 2022-03-18T16:53:13-07:00
New Revision: b8f029c3a4e2bfc5e2afbbe0c14bdb01ec3f2087
URL: https://github.com/llvm/llvm-project/commit/b8f029c3a4e2bfc5e2afbbe0c14bdb01ec3f2087
DIFF: https://github.com/llvm/llvm-project/commit/b8f029c3a4e2bfc5e2afbbe0c14bdb01ec3f2087.diff
LOG: [flang] Accept legacy aliases for intrinsic function names
Support the names AND, OR, and XOR for the generic intrinsic
functions IAND, IOR, and IEOR respectively.
Differential Revision: https://reviews.llvm.org/D122034
Added:
Modified:
flang/docs/Extensions.md
flang/lib/Evaluate/intrinsics.cpp
flang/test/Semantics/boz-literal-constants.f90
Removed:
################################################################################
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 8b84045d20116..5e3d4dd092844 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -223,6 +223,9 @@ end
as if they were comment lines, even if not begun with `!`.
* Commas are required in FORMAT statements and character variables
only when they prevent ambiguity.
+* Legacy names `AND`, `OR`, and `XOR` are accepted as aliases for
+ the standard intrinsic functions `IAND`, `IOR`, and `IEOR`
+ respectively.
### Extensions supported when enabled by options
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index dff34f491a080..42b1a89da9183 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -793,16 +793,11 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
DefaultingKIND},
KINDInt},
{"__builtin_ieee_is_nan", {{"a", AnyFloating}}, DefaultLogical},
- {"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_is_negative", {{"a", AnyFloating}}, DefaultLogical},
+ {"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_next_after", {{"x", SameReal}, {"y", AnyReal}}, SameReal},
{"__builtin_ieee_next_down", {{"x", SameReal}}, SameReal},
{"__builtin_ieee_next_up", {{"x", SameReal}}, SameReal},
- {"__builtin_ieee_selected_real_kind", // alias for selected_real_kind
- {{"p", AnyInt, Rank::scalar},
- {"r", AnyInt, Rank::scalar, Optionality::optional},
- {"radix", AnyInt, Rank::scalar, Optionality::optional}},
- DefaultInt, Rank::scalar, IntrinsicClass::transformationalFunction},
{"__builtin_ieee_support_datatype",
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
DefaultLogical},
@@ -839,7 +834,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
// LCOBOUND, UCOBOUND, FAILED_IMAGES, IMAGE_INDEX,
// STOPPED_IMAGES, COSHAPE
// TODO: Non-standard intrinsic functions
-// AND, OR, XOR, LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
+// LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
// COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT,
// QCMPLX, QEXT, QFLOAT, QREAL, DNUM,
// INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN,
@@ -851,6 +846,15 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
// LOC, probably others
// TODO: Optionally warn on operand promotion extension
+// Aliases for a few generic intrinsic functions for legacy
+// compatibility and builtins.
+static const std::pair<const char *, const char *> genericAlias[]{
+ {"and", "iand"},
+ {"or", "ior"},
+ {"xor", "ieor"},
+ {"__builtin_ieee_selected_real_kind", "selected_real_kind"},
+};
+
// The following table contains the intrinsic functions listed in
// Tables 16.2 and 16.3 in Fortran 2018. The "unrestricted" functions
// in Table 16.2 can be used as actual arguments, PROCEDURE() interfaces,
@@ -1897,6 +1901,10 @@ class IntrinsicProcTable::Implementation {
for (const IntrinsicInterface &f : genericIntrinsicFunction) {
genericFuncs_.insert(std::make_pair(std::string{f.name}, &f));
}
+ for (const std::pair<const char *, const char *> &a : genericAlias) {
+ aliases_.insert(
+ std::make_pair(std::string{a.first}, std::string{a.second}));
+ }
for (const SpecificIntrinsicInterface &f : specificIntrinsicFunction) {
specificFuncs_.insert(std::make_pair(std::string{f.name}, &f));
}
@@ -1929,16 +1937,22 @@ class IntrinsicProcTable::Implementation {
SpecificCall HandleNull(ActualArguments &, FoldingContext &) const;
std::optional<SpecificCall> HandleC_F_Pointer(
ActualArguments &, FoldingContext &) const;
+ const std::string &ResolveAlias(const std::string &name) const {
+ auto iter{aliases_.find(name)};
+ return iter == aliases_.end() ? name : iter->second;
+ }
common::IntrinsicTypeDefaultKinds defaults_;
std::multimap<std::string, const IntrinsicInterface *> genericFuncs_;
std::multimap<std::string, const SpecificIntrinsicInterface *> specificFuncs_;
std::multimap<std::string, const IntrinsicInterface *> subroutines_;
const semantics::Scope *builtinsScope_{nullptr};
+ std::map<std::string, std::string> aliases_;
};
bool IntrinsicProcTable::Implementation::IsIntrinsicFunction(
- const std::string &name) const {
+ const std::string &name0) const {
+ const std::string &name{ResolveAlias(name0)};
auto specificRange{specificFuncs_.equal_range(name)};
if (specificRange.first != specificRange.second) {
return true;
@@ -2427,9 +2441,11 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
return std::nullopt;
}};
- // Probe the generic intrinsic function table first.
+ // Probe the generic intrinsic function table first; allow for
+ // the use of a legacy alias.
parser::Messages genericBuffer;
- auto genericRange{genericFuncs_.equal_range(call.name)};
+ const std::string &name{ResolveAlias(call.name)};
+ auto genericRange{genericFuncs_.equal_range(name)};
for (auto iter{genericRange.first}; iter != genericRange.second; ++iter) {
if (auto specificCall{
matchOrBufferMessages(*iter->second, genericBuffer)}) {
diff --git a/flang/test/Semantics/boz-literal-constants.f90 b/flang/test/Semantics/boz-literal-constants.f90
index ca1676a696461..7c4e5928ca517 100644
--- a/flang/test/Semantics/boz-literal-constants.f90
+++ b/flang/test/Semantics/boz-literal-constants.f90
@@ -36,6 +36,7 @@ subroutine explicit(n, x, c)
! B) Argument to intrinsics listed from 16.9 below
! BGE, BGT, BLE, BLT, CMPLX, DBLE, DSHIFTL,
! DSHIFTR, IAND, IEOR, INT, IOR, MERGE_BITS, REAL
+ ! and legacy aliases AND, OR, XOR
! part A
data f / Z"AA" / ! OK
@@ -63,16 +64,25 @@ subroutine explicit(n, x, c)
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
resint = IAND(B"0001", B"0011")
resint = IAND(B"0001", 3)
+ !ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
+ resint = AND(B"0001", B"0011")
+ resint = AND(B"0001", 3)
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
resint = IEOR(B"0001", B"0011")
resint = IEOR(B"0001", 3)
+ !ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
+ resint = XOR(B"0001", B"0011")
+ resint = XOR(B"0001", 3)
resint = INT(B"1010")
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
res = IOR(B"0101", B"0011")
res = IOR(B"0101", 3)
+ !ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
+ res = OR(B"0101", B"0011")
+ res = OR(B"0101", 3)
res = MERGE_BITS(13,3,11)
res = MERGE_BITS(B"1101",3,11)
More information about the flang-commits
mailing list