This is an archive of the discontinued LLVM Phabricator instance.

[Intrinsic] Add llvm.minnan and llvm.maxnan instrinsic functions
AbandonedPublic

Authored by tlively on Sep 24 2018, 9:00 PM.

Details

Summary

These are NaN-propagating versions of llvm.minnum and
llvm.maxnum. These intrinsics lower to the existing fminnan and
fmaxnan instruction selection DAG nodes, so targets that already
support lowering from these nodes should not need to do anything.

WebAssembly in particular requires these intrinsic functions to exist
in order to make its min and max instructions generally available at
the IR level.

Diff Detail

Event Timeline

tlively created this revision.Sep 24 2018, 9:00 PM
aheejin added a comment.EditedSep 25 2018, 12:28 PM

Does this cover all the places we need to handle these new intrinsics? Searching by minnum or maxnum in the llvm directory yields other occurrences in files like lib/Analysis/ValueTracking.cpp, lib/Analysis/VectorUtils.cpp, and lib/Analysis/InstructionSimplify.cpp. (There are more). For test cases as well.

include/llvm/ADT/APFloat.h
1262

Maybe add 1-2 line comments to these two, like other functions?

tlively updated this revision to Diff 167214.Sep 26 2018, 5:03 PM
  • Add comments as requested
  • Add analogous functionality and tests for every target-independent usage of minnum and maxnum
dschuff added inline comments.Sep 27 2018, 8:52 AM
docs/LangRef.rst
11596

Does IEEE-754 2018 say anything about which NaN (i.e. is the payload required to be propagated too)?

sunfish added inline comments.Sep 27 2018, 9:56 AM
docs/LangRef.rst
11596

No, it falls under the general rules for NaN propagation in binary operators (6.2.3). That is, it non-normatively suggests that if two NaN operands are given, one of the payloads be propagated, but it does't give a suggestion as to which.

11599

Another thing that changed in IEEE 754-2018 is that unlike 754-2008's minNum and maxNum, 754-2018's minimum. maximum, minimumNumber, and maximumNumber are defined to treat -0 as if it were less than +0. It'd be nice to adopt this new rule for these new intrinsics, however llvm.minnum already exists and doesn't follow this rule, and existing libm fmin and fmax implementations don't all follow this rule. So, it may not be practical to do so at this time. It'd be useful to mention this discrepancy with the 754-2018 rules here at least though.

tlively updated this revision to Diff 167364.Sep 27 2018, 12:07 PM
  • Add notes about exception to IEEE 754-2018 semantics for +0/-0
  • Split into multiple commits to make reviewing more pleasant
tlively updated this revision to Diff 167388.Sep 27 2018, 1:31 PM
  • Reduce CL to just initial commit, others incoming.
tlively marked an inline comment as done.Sep 27 2018, 2:06 PM
tlively added inline comments.
docs/LangRef.rst
11599

Thanks, @sunfish! I've added notes about this.

tlively planned changes to this revision.Sep 27 2018, 2:54 PM
tlively marked an inline comment as done.

WebAssembly's handling of +0/-0 *does* match IEEE 754-2018, so these intrinsics (whether target-independent or not) need to be changed to match those semantics as well. I will have to investigate whether the fminnan and fmaxnan ISel DAG nodes are already being used in ways that do not respect these semantics. If they are, we will need new ISel DAG nodes as well.

WebAssembly's handling of +0/-0 *does* match IEEE 754-2018, so these intrinsics (whether target-independent or not) need to be changed to match those semantics as well. I will have to investigate whether the fminnan and fmaxnan ISel DAG nodes are already being used in ways that do not respect these semantics. If they are, we will need new ISel DAG nodes as well.

It's ok for WebAssembly's semantics to be more constrained than LLVM's. It's the reverse that would be a problem.

It's ok for WebAssembly's semantics to be more constrained than LLVM's. It's the reverse that would be a problem.

That's true, except that if the semantics of the LLVM intrinsics were not as strict as the semantics of the WebAssembly instructions, then there would be no way for programmers to access WebAssembly's exact semantics at the source level, which is the whole point of implementing these intrinsics at all.

That's true, except that if the semantics of the LLVM intrinsics were not as strict as the semantics of the WebAssembly instructions, then there would be no way for programmers to access WebAssembly's exact semantics at the source level, which is the whole point of implementing these intrinsics at all.

Oh, right. So in that case, the existing minnum/maxnum intrinsics do have the same problem. That's probably not easy to fix, because it would require changes to existing implementations on other platforms. So we may have to add wasm-specific versions of these intrinsics after all :-/.

Oh, right. So in that case, the existing minnum/maxnum intrinsics do have the same problem. That's probably not easy to fix, because it would require changes to existing implementations on other platforms. So we may have to add wasm-specific versions of these intrinsics after all :-/.

I don't think adding new intrinsics necessarily means we need to change anything about the old intrinsics. A the C language level, we won't expose builtin functions for wasm that lower to minnum or maxnum, since those don't match wasm semantics. To prevent people from assuming that the only difference between minnum/maxnum and the new intrinsics is NaN propagation, I propose we name the new instrinsics minimum/maximum (after the new IEEE operations) rather than minnan/maxnan.

tlively abandoned this revision.Oct 1 2018, 7:53 PM

Abandoned in favor of D52764.