Repository navigation
Conversation
…tio basis Fixes react#2038. distributeFreeSpaceFirstPass subtracted the frozen item's shrink-scaled factor inline, which the compiler contracts into a fused multiply-add with the unrounded product. It therefore did not cancel against the float accumulator built in calculateFlexLine and left a 2^-19 residual that distributeFreeSpaceSecondPass divided the remaining free space by, measuring the item at ~8.3e9 instead of 0. The absolute 1e-6f guard from react#1974 does not cover it. Round the product to float before subtracting, and replace the epsilon with an exact count of shrinkable items left on the line. 🤖 Co-authored-by: Claude <noreply@anthropic.com>
intergalacticspacehighway
added a commit
to intergalacticspacehighway/yoga
that referenced
this pull request
Oct 18, 2026
Collaborator
|
Thanks @sebholl for the analysis and repro! I've opened #2044, which sums the shrink factors of the unfrozen items instead of subtracting the frozen ones. That makes the total itself exact (0 when every item is frozen), so no separate count is needed, and it also fixes #931. I've also included your aspectRatio tests there. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #2038.
When the only shrinkable item on an overflowing row has its flex basis derived from
aspectRatio,distributeFreeSpaceSecondPassdivides the remaining free space by a2^-19residual left intotalFlexShrinkScaledFactors, and the item is measured at ~8.3e9 instead of 0. Sibling of #1665 / #1974 / #1783; the absolute1e-6fguard from #1974 does not catch this residual.Mechanism (full trace in #2038):
calculateFlexLineaccumulatesround(-3 * 21.083334f) = -63.25.distributeFreeSpaceFirstPassthen subtracts the same product inline, which clang contracts into a fused multiply-add using the unrounded product63.2500019, leaving exactly2^-19 = 1.9e-6. Building with-ffp-contract=offmakes the bug disappear, which is also why it never shows in the wasm playground.Two changes:
distributeFreeSpaceFirstPass: round the excluded product tofloatbefore subtracting it. This is the cause, and on its own it fixes the repro under the default-ffp-contract=on.1e-6fepsilon indistributeFreeSpaceSecondPasswith an exact count of shrinkable items left on the line (FlexLineRunningLayout::numberOfShrinkableItems, kept in lockstep with the total). "Are any shrinkable items left?" is a counting question, and no absolute epsilon is right because the residual scales withflexShrink * flexBasis. This also keeps the fix correct under-ffp-contract=fast, where (1) alone can still be contracted across statements.Left alone deliberately: the first-pass division (
remainingFreeSpace / totalFlexShrinkScaledFactorsinsidedistributeFreeSpaceFirstPass) is structurally exposed to the same issue if an item freezes mid-loop, but I have no repro for it, and a count-based guard cannot apply there because the current item is not yet frozen. Happy to add something if a maintainer prefers.Test plan
tests/YGFlexShrinkAspectRatioBugTest.cpp(3 tests): the 4-node repro from flexShrink runaway (~8e9) when the sole shrinkable item has an aspectRatio basis; FMA residual slips past the 1e-6f guard from #1974 #2038, a sweep over shrink factors that currently diverge, and a basis guard. The first two fail onmainand pass with this change.clang++ -std=c++20 -O2(Apple clang, arm64).-ffp-contract=fast.YGFlexShrinkBorderBugTest(flexBasis+flexShrink+borderWidth result in an wrong value #1665) still passes.