forked from OSchip/llvm-project
[flang] Legacy extension intrinsic functions IMAG, IZEXT, JZEXT
Support these legacy extension intrinsic functions with unambiguous semantics in those existing compilers that support them by means of recognizing them as aliases for standard intrinsics (IMAG) or with simple rewrites (IZEXT, JZEXT). Note that ZEXT has different semantics in different existing compilers, so we will not support it due to lack of a broad unambiguous precedent. Differential Revision: https://reviews.llvm.org/D132154
This commit is contained in:
parent
b066195b3f
commit
6d279f4051
|
@ -235,6 +235,11 @@ end
|
||||||
respectively.
|
respectively.
|
||||||
* A digit count of d=0 is accepted in Ew.0, Dw.0, and Gw.0 output
|
* 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.
|
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
|
### Extensions supported when enabled by options
|
||||||
|
|
||||||
|
|
|
@ -762,6 +762,17 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
|
||||||
return i.ISHFTC(countVal);
|
return i.ISHFTC(countVal);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
} else if (name == "izext" || name == "jzext") {
|
||||||
|
if (args.size() == 1) {
|
||||||
|
if (auto *expr{UnwrapExpr<Expr<SomeInteger>>(args[0])}) {
|
||||||
|
// Rewrite to IAND(INT(n,k),255_k) for k=KIND(T)
|
||||||
|
intrinsic->name = "iand";
|
||||||
|
auto converted{ConvertToType<T>(std::move(*expr))};
|
||||||
|
*expr = Fold(context, Expr<SomeInteger>{std::move(converted)});
|
||||||
|
args.emplace_back(AsGenericExpr(Expr<T>{Scalar<T>{255}}));
|
||||||
|
return FoldIntrinsicFunction(context, std::move(funcRef));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (name == "lbound") {
|
} else if (name == "lbound") {
|
||||||
return LBOUND(context, std::move(funcRef));
|
return LBOUND(context, std::move(funcRef));
|
||||||
} else if (name == "leadz" || name == "trailz" || name == "poppar" ||
|
} else if (name == "leadz" || name == "trailz" || name == "poppar" ||
|
||||||
|
|
|
@ -507,6 +507,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
|
||||||
DefaultLogical, Rank::elemental, IntrinsicClass::inquiryFunction},
|
DefaultLogical, Rank::elemental, IntrinsicClass::inquiryFunction},
|
||||||
{"is_iostat_end", {{"i", AnyInt}}, DefaultLogical},
|
{"is_iostat_end", {{"i", AnyInt}}, DefaultLogical},
|
||||||
{"is_iostat_eor", {{"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,
|
{"kind", {{"x", AnyIntrinsic}}, DefaultInt, Rank::elemental,
|
||||||
IntrinsicClass::inquiryFunction},
|
IntrinsicClass::inquiryFunction},
|
||||||
{"lbound",
|
{"lbound",
|
||||||
|
@ -844,7 +846,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
|
||||||
// TODO: Coarray intrinsic functions
|
// TODO: Coarray intrinsic functions
|
||||||
// LCOBOUND, UCOBOUND, IMAGE_INDEX, COSHAPE
|
// LCOBOUND, UCOBOUND, IMAGE_INDEX, COSHAPE
|
||||||
// TODO: Non-standard intrinsic functions
|
// TODO: Non-standard intrinsic functions
|
||||||
// LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
|
// LSHIFT, RSHIFT, SHIFT,
|
||||||
// COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT,
|
// COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT,
|
||||||
// QCMPLX, QEXT, QFLOAT, QREAL, DNUM,
|
// QCMPLX, QEXT, QFLOAT, QREAL, DNUM,
|
||||||
// INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN,
|
// INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN,
|
||||||
|
@ -860,6 +862,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
|
||||||
// compatibility and builtins.
|
// compatibility and builtins.
|
||||||
static const std::pair<const char *, const char *> genericAlias[]{
|
static const std::pair<const char *, const char *> genericAlias[]{
|
||||||
{"and", "iand"},
|
{"and", "iand"},
|
||||||
|
{"imag", "aimag"},
|
||||||
{"or", "ior"},
|
{"or", "ior"},
|
||||||
{"xor", "ieor"},
|
{"xor", "ieor"},
|
||||||
{"__builtin_ieee_selected_real_kind", "selected_real_kind"},
|
{"__builtin_ieee_selected_real_kind", "selected_real_kind"},
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue