diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -235,6 +235,11 @@ respectively. * A digit count of d=0 is accepted in Ew.0, Dw.0, and Gw.0 output editing if no nonzero scale factor (kP) is in effect. +* The name `IMAG` is accepted as an alias for the generic intrinsic + function `AIMAG`. +* The legacy extension intrinsic functions `IZEXT` and `JZEXT` + are supported; `ZEXT` has different behavior with various older + compilers, so it is not supported. ### Extensions supported when enabled by options diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -762,6 +762,17 @@ return i.ISHFTC(countVal); })); } + } else if (name == "izext" || name == "jzext") { + if (args.size() == 1) { + if (auto *expr{UnwrapExpr>(args[0])}) { + // Rewrite to IAND(INT(n,k),255_k) for k=KIND(T) + intrinsic->name = "iand"; + auto converted{ConvertToType(std::move(*expr))}; + *expr = Fold(context, Expr{std::move(converted)}); + args.emplace_back(AsGenericExpr(Expr{Scalar{255}})); + return FoldIntrinsicFunction(context, std::move(funcRef)); + } + } } else if (name == "lbound") { return LBOUND(context, std::move(funcRef)); } else if (name == "leadz" || name == "trailz" || name == "poppar" || diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -507,6 +507,8 @@ DefaultLogical, Rank::elemental, IntrinsicClass::inquiryFunction}, {"is_iostat_end", {{"i", AnyInt}}, DefaultLogical}, {"is_iostat_eor", {{"i", AnyInt}}, DefaultLogical}, + {"izext", {{"i", AnyInt}}, TypePattern{IntType, KindCode::exactKind, 2}}, + {"jzext", {{"i", AnyInt}}, DefaultInt}, {"kind", {{"x", AnyIntrinsic}}, DefaultInt, Rank::elemental, IntrinsicClass::inquiryFunction}, {"lbound", @@ -844,7 +846,7 @@ // TODO: Coarray intrinsic functions // LCOBOUND, UCOBOUND, IMAGE_INDEX, COSHAPE // TODO: Non-standard intrinsic functions -// LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT, +// LSHIFT, RSHIFT, SHIFT, // COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, // QCMPLX, QEXT, QFLOAT, QREAL, DNUM, // INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, @@ -860,6 +862,7 @@ // compatibility and builtins. static const std::pair genericAlias[]{ {"and", "iand"}, + {"imag", "aimag"}, {"or", "ior"}, {"xor", "ieor"}, {"__builtin_ieee_selected_real_kind", "selected_real_kind"}, diff --git a/flang/test/Evaluate/fold-jzext.f90 b/flang/test/Evaluate/fold-jzext.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Evaluate/fold-jzext.f90 @@ -0,0 +1,10 @@ +! RUN: %python %S/test_folding.py %s %flang_fc1 +! Tests folding of IZEXT() & JZEXT() +module m + logical, parameter :: test_1 = kind(izext(-1_1)) == 2 + logical, parameter :: test_2 = izext(-1_1) == 255_2 + logical, parameter :: test_3 = kind(jzext(-1_1)) == 4 + logical, parameter :: test_4 = jzext(-1_1) == 255_4 + logical, parameter :: test_5 = kind(jzext(-1_2)) == 4 + logical, parameter :: test_6 = jzext(-1_2) == 255_4 +end module