-
Notifications
You must be signed in to change notification settings - Fork 340
[Bugfix] Fix index handling to promote 64-bit integers #796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…it integers - Updated index processing in `BufferStore` and `BufferLoad` to ensure that integer indices with less than 64 bits are promoted to 64-bit integers. - Introduced a new array to store the modified indices before updating the original indices, enhancing clarity and maintainability of the code.
WalkthroughUpdates BufferStore and BufferLoad visitors to rebuild index vectors locally, compute bounds for sub-64-bit integer indices, promote to int64 when overflow risk is detected using Int64Promoter, and replace original indices with the rebuilt list to avoid missed in-place mutations. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant V as Visitor
participant N as Buffer{Load/Store} Node
participant B as BoundsAnalyzer
participant P as Int64Promoter
V->>N: Visit indices[]
loop For each index i
V->>B: Compute bounds of i (if int<64 bits)
alt May overflow when widened
V->>P: Promote i to int64
P-->>V: i'
V->>V: Push i' to new_indices
else
V->>V: Push i to new_indices
end
end
V->>N: Replace indices with new_indices
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Pre-merge checks (2 passed, 1 warning)❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Poem
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. ✨ Finishing Touches
🧪 Generate unit tests
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. Comment |
|
👋 Hi! Thank you for contributing to the TileLang project. Please remember to run We appreciate you taking this step! Our team will review your contribution, and we look forward to your awesome work! 🚀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @LeiWang1999, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request addresses a bug in the index handling within BufferStore and BufferLoad operations. The primary goal is to ensure that all integer indices are correctly promoted to 64-bit when their current bitwidth is insufficient to hold their potential values, thereby preventing data overflow and incorrect memory access. The changes also refactor the index processing loop for better code clarity.
Highlights
- Index Promotion: Integer indices with less than 64 bits are now correctly promoted to 64-bit integers within BufferStore and BufferLoad operations to prevent potential overflow issues.
- Code Clarity and Maintainability: A new temporary array (new_indices) is used to collect all processed indices before updating the original indices array, improving the readability and maintainability of the index processing logic.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request correctly fixes a bug where integer indices were not being promoted to 64-bit integers as intended, because the modifications were made to a copy within a range-based for loop. The introduction of a new_indices array to collect the results is the right approach. My review includes suggestions to simplify the loop logic for better readability and to address code duplication between the VisitStmt_ and VisitExpr_ methods, which would improve the overall maintainability of the code.
| for (auto index : indices) { | ||
| if (index->dtype.is_int() && index->dtype.bits() < 64) { | ||
| auto int_bound = analyzer_->const_int_bound(index); | ||
| if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 || | ||
| int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) { | ||
| Int64Promoter promoter; | ||
| index = promoter(index); | ||
| new_indices.push_back(index); | ||
| continue; | ||
| } | ||
| } | ||
| new_indices.push_back(index); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic inside this for-loop can be simplified by removing the continue and the redundant push_back call. This improves readability.
for (auto index : indices) {
if (index->dtype.is_int() && index->dtype.bits() < 64) {
auto int_bound = analyzer_->const_int_bound(index);
if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 ||
int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) {
Int64Promoter promoter;
index = promoter(index);
}
}
new_indices.push_back(index);
}| for (auto index : indices) { | ||
| if (index->dtype.is_int() && index->dtype.bits() < 64) { | ||
| auto int_bound = analyzer_->const_int_bound(index); | ||
| if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 || | ||
| int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) { | ||
| Int64Promoter promoter; | ||
| index = promoter(index); | ||
| new_indices.push_back(index); | ||
| continue; | ||
| } | ||
| } | ||
| new_indices.push_back(index); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loop can be simplified in the same way as in VisitStmt_. Additionally, the logic in VisitStmt_(const BufferStoreNode *op) and VisitExpr_(const BufferLoadNode *op) is identical after this change. It would be good to extract this logic into a private helper function to avoid code duplication and improve maintainability.
for (auto index : indices) {
if (index->dtype.is_int() && index->dtype.bits() < 64) {
auto int_bound = analyzer_->const_int_bound(index);
if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 ||
int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) {
Int64Promoter promoter;
index = promoter(index);
}
}
new_indices.push_back(index);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/transform/config_index_bitwidth.cc (2)
134-135: Consider simplifying the control flow logic.The current implementation uses
continueafter pushing the promoted index, which works but creates slightly complex control flow. The logic could be simplified by removing thecontinuestatement.Apply this diff to simplify the control flow:
Int64Promoter promoter; index = promoter(index); - new_indices.push_back(index); - continue; } + new_indices.push_back(index);
156-157: Consider simplifying the control flow logic.Same simplification opportunity exists here as in the BufferStore implementation.
Apply this diff to simplify the control flow:
Int64Promoter promoter; index = promoter(index); - new_indices.push_back(index); - continue; } + new_indices.push_back(index);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/transform/config_index_bitwidth.cc(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/transform/config_index_bitwidth.cc (4)
src/transform/atomicadd_vectorize.cc (2)
indices(83-131)indices(83-83)src/transform/loop_vectorize.cc (2)
indices(113-168)indices(113-113)src/transform/loop_vectorize_dynamic.cc (2)
indices(141-194)indices(141-141)src/transform/flatten_buffer.cc (12)
op(67-100)op(67-67)op(102-166)op(102-102)op(168-174)op(168-168)op(198-215)op(198-198)op(217-232)op(217-217)op(234-242)op(234-234)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: format-check
🔇 Additional comments (2)
src/transform/config_index_bitwidth.cc (2)
126-141: LGTM! Index rebuilding fixes in-place mutation issue.The introduction of
new_indicesarray and rebuilding logic correctly addresses the problem where in-place modifications to indices within the loop weren't persisting. This ensures all processed indices (both promoted and original) are properly captured and assigned back to the buffer store.
148-163: LGTM! Consistent fix applied to BufferLoad.The same index rebuilding pattern is correctly applied to BufferLoad, maintaining consistency with the BufferStore implementation and ensuring both code paths handle index promotion properly.
| if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 || | ||
| int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify overflow detection logic for signed integer bounds.
The overflow detection uses (1LL << (index->dtype.bits() - 1)) - 1 for max_value and -(1LL << (index->dtype.bits() - 1)) for min_value. This appears to check if the value exceeds the representable range for the current bit width, but the logic seems to promote indices that are already at the boundary of their type's range.
Let me verify the signed integer overflow detection logic:
Also applies to: 152-153
🏁 Script executed:
#!/bin/bash
# Description: Verify the overflow detection logic for different integer bit widths
# Expected: Check if the boundary calculations match standard signed integer ranges
python3 << 'EOF'
def check_signed_bounds(bits):
# Current logic from the code
max_boundary = (1 << (bits - 1)) - 1
min_boundary = -(1 << (bits - 1))
# Standard signed integer bounds
actual_max = (1 << (bits - 1)) - 1
actual_min = -(1 << (bits - 1))
print(f"{bits}-bit signed integer:")
print(f" Code logic: max >= {max_boundary} or min < {min_boundary}")
print(f" Actual range: [{actual_min}, {actual_max}]")
print(f" Logic promotes when: value >= {max_boundary} or value < {min_boundary}")
print(f" This means promotion occurs for values AT the boundary")
print()
# Test common bit widths
for bits in [8, 16, 32]:
check_signed_bounds(bits)
EOFLength of output: 652
Fix signed overflow check to exclude boundary value
In src/transform/config_index_bitwidth.cc (lines 130–131), the current condition
if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 ||
int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) {will promote indices already equal to the max representable value (e.g. 127 for 8 bits). Change the max‐side comparison to > so only values exceeding the range trigger promotion:
- if (int_bound->max_value >= (1LL << (index->dtype.bits() - 1)) - 1 ||
+ if (int_bound->max_value > (1LL << (index->dtype.bits() - 1)) - 1 ||
int_bound->min_value < -(1LL << (index->dtype.bits() - 1))) {🤖 Prompt for AI Agents
In src/transform/config_index_bitwidth.cc around lines 130-131, the signed
overflow check currently uses a >= comparison on the max side which will
incorrectly treat values equal to the type's maximum (e.g., 127 for 8-bit) as
overflow; change the max-side comparison from >= to > so only values strictly
greater than the representable maximum trigger promotion, leaving the min-side
check as-is.
…it integers (tile-ai#796) - Updated index processing in `BufferStore` and `BufferLoad` to ensure that integer indices with less than 64 bits are promoted to 64-bit integers. - Introduced a new array to store the modified indices before updating the original indices, enhancing clarity and maintainability of the code.
BufferStoreandBufferLoadto ensure that integer indices with less than 64 bits are promoted to 64-bit integers.Summary by CodeRabbit