Skip to content

More ArrayCmpxchg expected opts in Heap2Local#8567

Merged
tlively merged 2 commits intomainfrom
heap2local-index-effects
Apr 2, 2026
Merged

More ArrayCmpxchg expected opts in Heap2Local#8567
tlively merged 2 commits intomainfrom
heap2local-index-effects

Conversation

@tlively
Copy link
Copy Markdown
Member

@tlively tlively commented Apr 2, 2026

When non-escaping allocations flow into the expected field of an ArrayCmpxchg, optimize even if the ArrayCmpxchg has a non-constant index. We typically only optimize array instructions with constant fields, but that's because we need to know what field of the array is accessed. Arrays flowing into the expected field are not accessed, though, so there is no need for the accessed index to be constant.

Make sure that effects in the potentially non-constant index field are preserved in the correct order by using a new scratch local to propagate the index value past the expected and replacement expressions to the newly generated struct.atomic.get.

When non-escaping allocations flow into the `expected` field of an ArrayCmpxchg, optimize even if the ArrayCmpxchg has a non-constant index. We typically only optimize array instructions with constant fields, but that's because we need to know what field of the array is accessed. Arrays flowing into the `expected` field are not accessed, though, so there is no need for the accessed index to be constant.

Make sure that effects in the potentially non-constant index field are preserved in the correct order by using a new scratch local to propagate the index value past the `expected` and `replacement` expressions to the newly generated `struct.atomic.get`.
@tlively tlively requested a review from kripken April 2, 2026 01:02
@tlively tlively requested a review from a team as a code owner April 2, 2026 01:02
return;
}
if (curr->ref == child || curr->expected == child) {
if (child == curr->expected ||
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth a comment here I think, as in the PR description.

return;
}

// The accessed array is being optimzied. Convert the ArrayCmpxchg into a
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The accessed array is being optimzied. Convert the ArrayCmpxchg into a
// The accessed array is being optimized. Convert the ArrayCmpxchg into a

(pre-existing, but while we are here)

// The `expected` value must be getting optimized. Since the accessed object
// is remaining an array for now, do not change anything. The ArrayCmpxchg
// will be optimized later by Struct2Local.
return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC this moves the trapping case into the handling of ref. But the case of expected should still trap, I think? I don't see that handled in the code that is reached later?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the optimization for expected creates a new array.atomic.get, it will still trap on OOB access precisely when the original code would, no matter what the expression for the index looks like.

(call $effect-i32)
(array.new_default $array (i32.const 1))
(call $effect-eq)
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test for array.atomic.rmw.cmpxchg where we optimize the expected field but the index is out of bounds?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output will look the same, but I will add a test where the index is an OOB constant.

@tlively tlively requested a review from kripken April 2, 2026 17:02
@tlively tlively enabled auto-merge (squash) April 2, 2026 17:34
@tlively tlively merged commit 0bb686f into main Apr 2, 2026
16 checks passed
@tlively tlively deleted the heap2local-index-effects branch April 2, 2026 17:59
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.

2 participants