Skip to content

Promote straight-line arrays before SROA - #736

Merged
shankarapailoor merged 4 commits into
mainfrom
shankara/r1cs-array-lowering
Sep 24, 2026
Merged

shankarapailoor merged 4 commits into
mainfrom
shankara/r1cs-array-lowering

Conversation

@shankarapailoor

@shankarapailoor shankarapailoor commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This is PR 2 of 3 in the R1CS lowering stack.

Stack:

  1. Scalarize POD values carried by while loops #735
  2. This PR
  3. Cache access analysis during scalar lowering #737

Speed up array-to-scalar lowering by directly promoting eligible straight-line static array elements before the general SROA and mem2reg pipeline. Replace the expensive global dead-value analysis with targeted allocation cleanup and canonicalization.

Related issues

No linked issue.

Changes

  • Promote statically indexed array elements with a single linear access order.
  • Support nested single-block scf.execute_region operations while rejecting CFG backedges and other multi-block paths.
  • Preserve general SROA/mem2reg handling for branches, loops, dynamic indices, and escaping arrays.
  • Replace global dead-value analysis with targeted dead-allocation cleanup and canonicalization.
  • Document that the faster cleanup no longer guarantees removal of every dead function argument/result or loop iteration value.
  • Add focused positive and negative promotion tests and a changelog entry.

Testing

  • nix develop --command bash -c "cmake --build build --target check-lit"
    • 423 discovered: 416 passed, 3 expected failures, 4 unsupported.
  • nix build -L
    • Full release build, lit suite, and unit tests passed.

Submission checklist

  • Internal contribution; the external-contributor issue requirement does not apply.
  • I added or updated tests for all relevant behavior.
  • I updated relevant documentation and implementation comments.
  • I added a changelog entry describing user-visible changes.
  • This branch is hosted in the upstream repository; maintainer-edit permission is not applicable.

AI assistance

  • No AI tools contributed to this PR.
  • AI tools contributed to this PR.

Tools used: OpenAI Codex and Anthropic Claude.

How the tools contributed: Codex assisted with implementation, focused tests, performance-oriented restructuring, and validation. Claude independently reviewed CFG and aliasing assumptions and supplied adversarial reproducers.

How I verified the contribution: I reviewed the diffs, tested positive and negative scf.execute_region shapes, ran the complete lit suite, and completed a full Nix release build with unit tests.

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

  2 files  ±0    2 suites  ±0   3m 9s ⏱️ +34s
446 tests +1  442 ✅ +1  4 💤 ±0  0 ❌ ±0 
892 runs  +2  884 ✅ +2  8 💤 ±0  0 ❌ ±0 

Results for commit d74c02f. ± Comparison against base commit ea08c04.

♻️ This comment has been updated with latest results.

@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch 3 times, most recently from 33093a3 to 99e8926 Compare September 21, 2026 16:40
@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch 2 times, most recently from 58caf55 to 18230cd Compare September 22, 2026 13:44
@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch 2 times, most recently from 273febe to 4e6ddf0 Compare September 22, 2026 16:40
@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch from 4e6ddf0 to ad708ab Compare September 22, 2026 17:18
Comment on lines +982 to +1126
// Cleanup SSA values made dead by removing allocations and writes.
nestedPM.addPass(createRemoveDeadValuesWorkaroundPass());
// Fold and remove local SSA values made dead by array promotion. Avoid the global
// remove-dead-values dataflow analysis here: static array lowering can produce very large,
// straight-line functions, and the targeted allocation cleanup above has already removed the
// memory state that required whole-region reasoning. Consequently, this pass no longer prunes
// dead function arguments/results or loop iteration values that canonicalization cannot remove.
nestedPM.addPass(mlir::createCanonicalizerPass());

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.

As discussed earlier...
Thus far, we have kept "canonicalize" out of standalone passes (only using it in pre-defined pipelines) because of how broad it is (potentially affecting any op in the IR, reordering, etc.). Since it's run at the very end here, it does not provide any additional power to this pass itself so we should remove it and add a comment to this pass declaration stating that running canonicalize after can be beneficial.

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.

@shankarapailoor This is the only feedback I have for now. This will of course change the test output and will require reverting the related part of the header comment in lib/Dialect/Array/Transforms/ArrayToScalarPass.cpp.

@shankarapailoor shankarapailoor Sep 24, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@tim-hoffman Given the changes that will be there in LLVM 23, I think we decided to keep it here no?

@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch from ad708ab to 67c6bbf Compare September 22, 2026 18:14
@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch from 67c6bbf to 041a26b Compare September 22, 2026 18:23
Base automatically changed from shankara/r1cs-scalar-lowering to main September 22, 2026 18:42
@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch from 041a26b to d4fcb64 Compare September 22, 2026 18:42
Replace the global remove-dead-values analysis with canonicalization after array promotion. This avoids costly whole-region dataflow on large straight-line functions, but intentionally no longer guarantees pruning dead function arguments, function results, or loop iteration values that canonicalization cannot remove.
@shankarapailoor
shankarapailoor force-pushed the shankara/r1cs-array-lowering branch from d4fcb64 to c6b25d0 Compare September 24, 2026 20:09
@tim-hoffman

Copy link
Copy Markdown
Member

@codex review — Please focus on correctness: semantic preservation, miscompilations, edge cases, and regressions introduced by this PR. Flag concrete bugs with a triggering example or clear failure scenario. Avoid suggestions for alternative optimizations, performance improvements, refactoring, or style unless they are necessary to fix a correctness issue.

@project-llzk project-llzk deleted a comment from shankarapailoor Sep 24, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T20:19:42.572637Z c6b25d0 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: c6b25d045a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// CHECK-DAG: %[[V11:[0-9a-zA-Z_\.]+]] = struct.readm %[[V0]][@f1_6] : <@ComponentA1>, !felt.type
// CHECK-DAG: %[[V12:[0-9a-zA-Z_\.]+]] = struct.readm %[[V0]][@f1_0] : <@ComponentA1>, !felt.type
// CHECK-DAG: %[[V13:[0-9a-zA-Z_\.]+]] = struct.readm %[[V0]][@f1_1] : <@ComponentA1>, !felt.type
// CHECK-NOT: struct.readm

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.

The 3 CHECK-NOT added to this file are redundant in a chain of CHECK-NEXT

Comment on lines +83 to +85
// CHECK-LABEL: function.def @inside_loop_body
// CHECK-NOT: array.
// CHECK: scf.for

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.

This doesn't seem meaningful to check since there were no array. prior to scf.for originally. Is the pass able to remove the array usage in the loop body or not?

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.

This is why I typically prefer CHECK for the full output.

// straight-line functions, and the targeted allocation cleanup above has already removed the
// memory state that required whole-region reasoning. Consequently, this pass no longer prunes
// dead function arguments/results or loop iteration values that canonicalization cannot remove.
nestedPM.addPass(mlir::createCanonicalizerPass());

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.

You don't need the mlir:: prefix since using namespace mlir is in the file

Regenerate affected FileCheck blocks with generate-test-checks.py, cover the full loop body, and remove the redundant mlir namespace qualifier.

Co-authored-by: Codex <codex@openai.com>

@tim-hoffman tim-hoffman left a comment

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.

LGTM

@shankarapailoor
shankarapailoor merged commit 1e547c8 into main Sep 24, 2026
10 checks passed
@shankarapailoor
shankarapailoor deleted the shankara/r1cs-array-lowering branch September 24, 2026 22:50
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