[RFC] Ignore NaNs for MINVAL/MAXVAL/MINLOC/MAXLOC

I would like to ask for a concensus about changing the current behavior of the above intrinsics in Flang.

The discussion started in [flang] Fetch the initial reduction value from the input array. by vzakhari · Pull Request #136790 · llvm/llvm-project · GitHub

This comment shows the current behavior of different compilers on x86: [flang] Fetch the initial reduction value from the input array. by vzakhari · Pull Request #136790 · llvm/llvm-project · GitHub

It seems that we can get more consistency across the compilers by making Flang behave like nagfor and xlf. The change will also produce fewer comparison instructions and simplify HLFIR inlining pass.

The downside of the change is that Flang will not match gfortran and some gfortran suite tests will fail.

The change is basically to ignore NaN values in the input arrays for MINVAL/MAXVAL/MINLOC/MAXLOC, i.e. a NaN value will never result in an update of the reduction value initially set to +/-LARGEST.

Please let me know if you are in favor of the change or not.

The change here seems to be in the treatment of arrays whose unmasked elements are all NaN. And for those, a NaN result would seem to be most consistent with the semantics in the IEEE floating-point standard for max/min(Num) and their bindings in the Fortran standard. It seems weird to me to return a value for maxval/minval that never appears in the unmasked data.

Thank you. It is a valid argument.

At the same time, it might be confusing for MINLOC/MAXLOC: since NaNs are unordered, why would we return the position of the first NaN instead of 0 coordinate(s) (meaning to me something like “no valid values in the input”).

Can you please clarify/quote which max/minNum IEEE text you are referring to?

I found this:

minimumNumber(x, y) is x if x<y, y if y<x, and the number if one operand is a number and the
other is a NaN. For this operation, −0 compares less than +0. If x=y and signs are the same it is
either x or y. If both operands are NaNs, a quiet NaN is returned, according to 6.2. If either
operand is a signaling NaN, an invalid operation exception is signaled, but unless both operands
are NaNs, the signaling NaN is otherwise ignored and not converted to a quiet NaN as stated in
6.2 for other operations.

To me it does not 100% define how a MIN/MAX-LOC/VAL reduction should be made, because the result depends on the initial value that we choose for the reduction computation. If we pick +/-LARGEST, then the result will never be NaN even if the whole array consists of NaNs.

Okay, I get your point:

If both operands are NaNs, a quiet NaN is returned

Amongst all the NaNs a NaN should be the answer.