llvm / llvm/llvm-project

x86: lowering of `llvm.minnum` and `llvm.maxnum` does not handle signed zeroes correctly

Open
#169,122 4 comments 0 reactions 0 assignees View on GitHub
backend:X86
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://github.com/llvm/llvm-project/pull/112852 updated the documentation and semantics around the `llvm.minnum` and `llvm.maxnum` intrinsics. The langref for e.g. `llvm.minnum` now says (emphasis mine):

> Follows the semantics of minNum in IEEE-754-2008, **except that -0.0 < +0.0 for the purposes of this intrinsic.**
[...]
> **If the intrinsic is marked with the nsz attribute,** then the effect is as in the definition in C and IEEE-754-2008: the result of `minnum(-0.0, +0.0)` may be either -0.0 or +0.0.

However, this is not respected for x86. It lowers these operations to a `minps`/`minpd` plus a `cmpunord` to handle NaN, but makes no effort to handle signed zeroes if the nsz attribute is absent.

You can see this behavior in [this godbolt example](https://godbolt.org/z/Wz39s5czr). Note that the Rust `min` intrinsic is lowered to `llvm.minnum` (without any nsz attribute), which is then compiled into a `minps`+`cmpunordps` sequence.

Contributor guide

Open the contributing guide

Research direction

Start by reading the linked PR 112852 and reproducing the behavior in the linked Godbolt example. Then trace the x86 lowering of llvm.minnum and llvm.maxnum, comparing minps/minpd plus cmpunord behavior with the documented signed-zero semantics; done means both intrinsic forms lower correctly with and without nsz.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.