Index: flang/lib/Evaluate/fold-integer.cpp =================================================================== --- flang/lib/Evaluate/fold-integer.cpp +++ flang/lib/Evaluate/fold-integer.cpp @@ -562,6 +562,28 @@ } return std::invoke(fptr, i, posVal); })); + } else if (name == "ibits") { + return FoldElementalIntrinsic(context, std::move(funcRef), + ScalarFunc([&](const Scalar &i, + const Scalar &pos, + const Scalar &len) -> Scalar { + auto posVal{static_cast(pos.ToInt64())}; + auto lenVal{static_cast(len.ToInt64())}; + if (posVal < 0) { + context.messages().Say( + "bit position for IBITS(POS=%d,LEN=%d) is negative"_err_en_US, + posVal, lenVal); + } else if (lenVal < 0) { + context.messages().Say( + "bit length for IBITS(POS=%d,LEN=%d) is negative"_err_en_US, + posVal, lenVal); + } else if (posVal + lenVal > i.bits) { + context.messages().Say( + "IBITS(POS=%d,LEN=%d) must have POS+LEN no greater than %d"_err_en_US, + posVal + lenVal, i.bits); + } + return i.IBITS(posVal, lenVal); + })); } else if (name == "index" || name == "scan" || name == "verify") { if (auto *charExpr{UnwrapExpr>(args[0])}) { return std::visit( @@ -949,7 +971,7 @@ } else if (name == "ubound") { return UBOUND(context, std::move(funcRef)); } - // TODO: dot_product, ibits, ishftc, matmul, sign, transfer + // TODO: dot_product, ishftc, matmul, sign, transfer return Expr{std::move(funcRef)}; } Index: flang/test/Evaluate/fold-ibits.f90 =================================================================== --- /dev/null +++ flang/test/Evaluate/fold-ibits.f90 @@ -0,0 +1,13 @@ +! RUN: %python %S/test_folding.py %s %flang_fc1 +! Tests folding of IBITS exhaustively over POS/LEN ranges +module m1 + implicit integer(a-z) + integer, parameter :: res1(*) = [((ibits(not(0),pos,len),len=0,31-pos),pos=0,31)] + integer, parameter :: expect1(*) = [((maskr(len),len=0,31-pos),pos=0,31)] + logical, parameter :: test1 = all(res1 == expect1) + logical, parameter :: test2 = all([((ibits(0,pos,len),len=0,31-pos),pos=0,31)] == 0) + integer, parameter :: mess = z'a5a55a5a' + integer, parameter :: res3(*) = [((ibits(mess,pos,len),len=0,31-pos),pos=0,31)] + integer, parameter :: expect3(*) = [((iand(shiftr(mess,pos),maskr(len)),len=0,31-pos),pos=0,31)] + logical, parameter :: test3 = all(res3 == expect3) +end module