Dealing with invalid arguments in intrinsics

What is the policy to deal with invalid arguments in intrinsics?

For instance, in the ISHFT(I, SHIFT) intrinsic requires that “the absolute value of SHIFT shall be less than or equal to BIT_SIZE(I)”. The current implementation of ISHFT in IntrinsicCall.cpp returns 0 if ABS(SHIFT) > BIT_SIZE(I).

This is fairly intuitive behavior if a programmer passes an invalid value to ISHFT, but the case for other intrinsics is less clear. For example SHIFTR(I, SHIFT) requires that SHIFT be non-negative. What should we do if a programmer passes negative value? I suppose we could just shift left but that feels odd. Is it reasonable to throw a runtime error?

Whether something is “reasonable” or not is of course subjective, but since (1) the bit intrinsics are in the language for high performance and can map directly to machine instructions, (2) the requirement on the shift count value is not required by the standard to be validated by a compiler, and (3) none of the six other Fortran compilers that I tried emit a runtime error for a negative shift count, I think that the overhead of a runtime check would not be justifiable to HPC users.

@klausler

Thanks. I looked at the standard (admittedly rather quickly), but didn’t find anything about dealing with this. Would this be the Fortran equivalent of “undefined behavior” in C/C++? Is the compiler allowed to do whatever it sees fit in such situations?

It is not quite the same thing as “undefined behavior” in C/C++, but the Fortran standards have always said that they describe conforming programs and conforming implementations only. But the Fortran standards are not as well known to Fortran users as the C standards are to C programmers, and what really seems to matter most is that Fortran programs not change behavior when compiled by new releases of compilers (or new compilers); existing precedents need to be respected unless there’s a good reason to the contrary. Unlike C/C++, there’s not much new development taking place in Fortran, and the primary motivation is preserving the value of existing Fortran codes, standard or otherwise.

In the case of SHIFTR with a negative shift count, every Fortran compiler I tried that supports SHIFTR – which is a Fortran 2008 feature intended to avoid the runtime sign test on the shift count of the “MIL-SPEC” bit intrinsic ISHFT – returns 0 in that case on x86-64. There may be codes out there that rely on that behavior, no matter what the standards say. And that’s the de facto standard that f18 needs to implement, absent a really compelling reason to the contrary.

(That said, the constant folding code for SHIFTR will emit a compile-time error if a shift count is a known constant that is negative or excessive, but I will not hesitate to change that to a warning if some user complains and can’t change their code.)

@klausler,

Thanks, that was very insightful. I am not a Fortran programmer, so the background was very helpful.

gfortran fails at compile-time if the shift count is a known constant and is negative or excessive. But I haven’t tested any other compilers.