Skip to content

[Fix][Codegen] Preserve NaNs in floating-point min and max - #20054

Open
tlopex wants to merge 3 commits into
apache:mainfrom
tlopex:max-nan-preserving
Open

[Fix][Codegen] Preserve NaNs in floating-point min and max#20054
tlopex wants to merge 3 commits into
apache:mainfrom
tlopex:max-nan-preserving

Conversation

@tlopex

@tlopex tlopex commented Jul 27, 2026

Copy link
Copy Markdown
Member

This PR fixes NaN handling in floating-point min and max code generation, partly fixed #19579

Previously, the ordered comparison caused a NaN in the left operand to be discarded, while a NaN in the right operand was preserved.

For floating-point operands, this PR implements the following semantics:

max: (a > b || isnan(a)) ? a : b
min: (a < b || isnan(a)) ? a : b

This preserves a NaN from either operand while retaining the existing behavior of selecting the second operand when the operands compare equal.

For the C host backend, a != a is used as the NaN check:

(a > b || a != a) ? a : b
(a < b || a != a) ? a : b

This compact form also produces better optimized code than the equivalent nested conditional expression.

For LLVM, the lowering combines an ordered comparison with an unordered self-comparison and emits a single select. This avoids relying on llvm.maximum/llvm.minimum, whose signed-zero semantics differ from the existing TVM behavior and whose legalization may vary across LLVM targets.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] maximum/minimum/relu/clip do not propagate NaN (IEEE 754 violation)

1 participant