Skip to content

[Feat] Extend LegalizeNegativeIndex to support buffer store stmts#1339

Merged
LeiWang1999 merged 1 commit intotile-ai:mainfrom
ConvolutedDog:enhance-legalize-negative-index
Nov 26, 2025
Merged

[Feat] Extend LegalizeNegativeIndex to support buffer store stmts#1339
LeiWang1999 merged 1 commit intotile-ai:mainfrom
ConvolutedDog:enhance-legalize-negative-index

Conversation

@ConvolutedDog
Copy link
Contributor

@ConvolutedDog ConvolutedDog commented Nov 25, 2025

This commit enhances the LegalizeNegativeIndex transformation pass to handle both buffer load and store operations with negative indices and adds some test cases.

Summary by CodeRabbit

  • Tests

    • Added comprehensive test coverage for negative index legalization in buffer operations, including single/multi-dimensional cases, mixed indices, vectorized operations, and conditional scenarios.
  • Refactor

    • Unified negative index handling for buffer load and store operations with improved state tracking and diagnostics.

✏️ Tip: You can customize this high-level summary in your review settings.

This commit enhances the LegalizeNegativeIndex transformation pass to handle
both buffer load and store operations with negative indices and adds some
test cases.
@github-actions
Copy link

👋 Hi! Thank you for contributing to the TileLang project.

Please remember to run pre-commit run --all-files in the root directory of the project to ensure your changes are properly linted and formatted. This will help ensure your contribution passes the format check.

We appreciate you taking this step! Our team will review your contribution, and we look forward to your awesome work! 🚀

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

Walkthrough

Exposes FFI Function through support headers and refactors the LegalizeNegativeIndex transformation to use a unified LoadStore2StateMap tracking both BufferLoad and BufferStore indices. Adds comprehensive test coverage with 17 test cases validating negative index legalization across various scenarios.

Changes

Cohort / File(s) Summary
FFI Support
src/support/ffi_aliases.h
Includes tvm/ffi/function.h and exposes ffi::Function in the tvm namespace via using declaration.
Legalize Negative Index Refactoring
src/transform/legalize_negative_index.cc
Replaces per-load unordered_map with unified LoadStore2StateMap supporting both BufferLoadNode and BufferStoreNode via BufferAccessVariant. Introduces ProcessIdx helper, NeedRecord predicate, and UpdateIdx routine. Updates NegativeIndexAnalyzer and NegativeIndexRewriter constructor/method signatures to accept LoadStore2StateMap references. Refactors analysis and rewriting phases to handle both load and store indices uniformly.
Legalize Negative Index Tests
testing/python/transform/test_tilelang_transform_legalize_negative_index.py
New test module with 17 test functions covering negative index legalization: single/multi-dimensional indices, mixed negative-positive indices, nested/vectorized operations, conditional code, unknown-sign handling, and buffer stores. Each test validates transformation via IRModule equality assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Data structure migration: Understand how LoadStore2StateMap with BufferAccessVariant variant replaces the per-load unordered_map and propagates through both analyzer and rewriter
  • ProcessIdx and NeedRecord logic: Verify correctness of index classification (NonNegative/Negative/Unknown) and recording decision logic
  • UpdateIdx implementation: Confirm proper index adjustment using buffer shapes and state vectors for both loads and stores
  • Signature consistency: Ensure constructor and method signature updates are consistently applied across both NegativeIndexAnalyzer and NegativeIndexRewriter

Possibly related PRs

Poem

🐰 Through FFI's gate, a function hops in view,
Negative indices turn to positive and true!
Load and store together, in a map so bright,
Seventeen tests ensure the legalization's right! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: extending LegalizeNegativeIndex to support buffer store statements in addition to buffer loads.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/transform/legalize_negative_index.cc (1)

68-68: Potential null pointer dereference if ramp->lanes is not a constant.

as_const_int may return std::nullopt or nullptr if ramp->lanes is a symbolic expression. Dereferencing without a check will crash.

Consider adding a defensive check:

-        int lanes = *as_const_int(ramp->lanes);
+        auto lanes_opt = as_const_int(ramp->lanes);
+        if (!lanes_opt) {
+          DLOG(WARNING)
+              << "LegalizeNegativeIndex: cannot determine lanes for ramp "
+              << simplified << " for buffer " << buffer_name << " (axis " << i
+              << ").";
+          states.push_back(IndexSignState::kUnknown);
+          continue;
+        }
+        int lanes = static_cast<int>(*lanes_opt);
🧹 Nitpick comments (2)
src/transform/legalize_negative_index.cc (1)

116-116: Remove unnecessary std::move on return value.

Using std::move on a local variable being returned prevents Named Return Value Optimization (NRVO). The compiler would otherwise elide the copy/move automatically.

-    return std::move(states);
+    return states;
testing/python/transform/test_tilelang_transform_legalize_negative_index.py (1)

157-157: Typo in comment: "delimed" should be "eliminated".

This typo appears in multiple test comments (lines 157, 180, 290, 311).

-        # vec is unused and can be delimed by Simplify.
+        # vec is unused and can be eliminated by Simplify.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2b10c5 and f67143c.

📒 Files selected for processing (3)
  • src/support/ffi_aliases.h (1 hunks)
  • src/transform/legalize_negative_index.cc (4 hunks)
  • testing/python/transform/test_tilelang_transform_legalize_negative_index.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
testing/python/transform/test_tilelang_transform_legalize_negative_index.py (2)
src/transform/legalize_negative_index.cc (4)
  • func (153-159)
  • func (153-153)
  • LegalizeNegativeIndex (209-222)
  • LegalizeNegativeIndex (209-209)
tilelang/language/ast/ir.py (1)
  • alloc_buffer (441-508)
🔇 Additional comments (7)
src/transform/legalize_negative_index.cc (4)

27-30: LGTM!

std::hash<std::variant<Types...>> is enabled if every specialization in std::hash<std::remove_const_t<Types>>... is enabled. Since both BufferLoadNode* and BufferStoreNode* are pointers with default hash support, the LoadStore2StateMap will work correctly as an std::unordered_map.


127-145: LGTM!

The visitor implementations for BufferLoadNode and BufferStoreNode correctly use the unified ProcessIdx helper and conditionally record states based on NeedRecord. The logic properly extends the pass to handle stores in addition to loads.


166-179: LGTM!

The UpdateIdx helper correctly adds the buffer dimension to negative indices (buffer_shape[i] + indices[i]), converting them to valid positive indices. The size check on line 169-171 provides appropriate validation.


209-222: LGTM!

The main pass function correctly orchestrates the analysis and rewriting phases with appropriate early returns for edge cases.

src/support/ffi_aliases.h (1)

6-6: LGTM!

The addition of ffi::Function exposure follows the existing pattern established for other FFI types (Array, Map, Optional, String).

Also applies to: 13-13

testing/python/transform/test_tilelang_transform_legalize_negative_index.py (2)

7-13: LGTM!

The _check helper is well-designed and follows the standard testing pattern for TIR transformation passes.


16-338: Comprehensive test coverage for the LegalizeNegativeIndex pass.

The test suite thoroughly covers:

  • Single and multi-dimensional negative indices
  • Mixed negative/positive indices
  • Negative indices in expressions (e.g., -i in loops)
  • Non-negative indices (unchanged)
  • Unknown sign indices (warning path)
  • Vector indices (Broadcast and Ramp)
  • Nested buffer accesses
  • Buffer stores in conditional statements

@LeiWang1999
Copy link
Member

cc @kurisu6912

@LeiWang1999
Copy link
Member

Thanks @ConvolutedDog , merged:)

@LeiWang1999 LeiWang1999 merged commit fac0400 into tile-ai:main Nov 26, 2025
7 checks passed
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