Skip to content

Keep the stage_mem load unless the block overwrites the whole window - #859

Open
konstde00 wants to merge 2 commits into
exo-lang:mainfrom
konstde00:fix/stage-mem-partial-overwrite
Open

konstde00 wants to merge 2 commits into
exo-lang:mainfrom
konstde00:fix/stage-mem-partial-overwrite

Conversation

@konstde00

@konstde00 konstde00 commented Oct 14, 2026 •

Copy link
Copy Markdown

Fixes #318.

stage_mem skips the initial load whenever the staged block writes to the buffer, even if the block writes only part of the window, so the unwritten elements are stored back as garbage. The #318 example still miscompiles on main (defe172): compiled and run, x[8] goes from 9 to 0, and a window written only under a condition loses its value the same way (x[0] goes from 7 to 0).

With this change the load is skipped only when the block provably overwrites every in-bounds element of the window. Loop nests that sweep the window with unit stride (including divide_loop guard tails) are checked structurally, without the solver. Other shapes go through the existing location-set analysis, and if the solver can't decide - the load is kept.

Tests: 7 new ones (the #318 case and a compile-and-run check of it, a full overwrite, a conditional write, a guarded and a reversed write, the solver-unknown case). Full suite: 734 passed, 44 skipped (727 on main), no golden output changed. In 400 random stage_mem rewrites, 25 of 103 accepted ones changed the program's output on main, and 0 with this change.

Questions: is new_eff.py the right place for the structural check? Would a small compile-and-compare test module be useful?

Currently stage_mem skips the initial load whenever the staged block
writes to the buffer, even if the block writes only part of the window,
so the elements it doesn't write are stored back as garbage (exo-lang#318).

Now the load is skipped only when the block provably overwrites every
in-bounds element of the window. A structural check covers loop nests
which sweep the window with unit stride (including divide_loop guard
tails), other shapes go through the existing location-set analysis,
and if the solver can't decide - the load is kept.

Added 4 tests: the exo-lang#318 case, a full overwrite (no load), a conditional
single-element write and a compile-and-run check of the exo-lang#318 case.

Fixes exo-lang#318
Two more stage_mem cases: a block under a divide_loop style bounds
guard, which overwrites the whole window (no load), and a reversed
write which covers only part of the window (the load is kept).

Also a direct test of Check_Window_Overwritten for the case when the
solver can't decide - the window is treated as not overwritten.
@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.03974% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.59%. Comparing base (defe172) to head (2fb5ac0).

Files with missing lines Patch % Lines
src/exo/rewrite/new_eff.py 91.96% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #859      +/-   ##
==========================================
+ Coverage   88.56%   88.59%   +0.03%     
==========================================
  Files         100      100              
  Lines       21917    22066     +149     
==========================================
+ Hits        19410    19550     +140     
- Misses       2507     2516       +9     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Need to Add Overwrite Analysis to stage_mem

1 participant