Skip to content
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

When doing module and division, first cast to unsigned 32 bit then promote to 64 bit #731

Merged
merged 3 commits into from
Oct 15, 2024

Conversation

Alan-Jowett
Copy link
Contributor

@Alan-Jowett Alan-Jowett commented Oct 15, 2024

Resolves: #730

This pull request includes changes to handle different bit-widths for unsigned division and modulo operations in the SplitDBM class, and adds new test cases to verify these changes.

Enhancements to arithmetic operations:

  • src/crab/split_dbm.cpp: Modified the handling of UDIV and UREM operations to correctly cast the immediate value based on the bit-width (32-bit or 64-bit) as specified in the BPF ISA specification.

Addition of new test cases:

  • src/test/test_yaml.cpp: Added a new YAML test case file muldiv.yaml to the test suite.
  • test-data/muldiv.yaml: Created a new test file with cases for 32-bit and 64-bit unsigned division and modulo operations to ensure correct behavior with negative divisors.

Summary by CodeRabbit

  • New Features

    • Enhanced handling of division and modulo operations for both 32-bit and 64-bit contexts, ensuring compliance with BPF ISA specifications.
    • Added new test cases for verifying behavior with negative divisors in arithmetic operations.
  • Bug Fixes

    • Improved precision in division and remainder calculations by implementing conditional logic for data type casting based on finite width.
  • Documentation

    • Improved comments and documentation within the code to clarify the handling of immediate values and arithmetic operations.

Copy link

coderabbitai bot commented Oct 15, 2024

Walkthrough

The pull request introduces modifications to the SplitDBM class in src/crab/split_dbm.cpp, focusing on enhancing the handling of arithmetic operations and improving type safety. It updates function signatures to include const qualifiers and adds two static functions for processing immediate values in division and modulo operations. Additionally, a new test case is added to src/test/test_yaml.cpp, along with a new YAML test data file test-data/muldiv.yaml that contains multiple test cases to validate the behavior of division and modulo operations with negative divisors in both 32-bit and 64-bit contexts.

Changes

File Change Summary
src/crab/split_dbm.cpp Updated function signatures to include const qualifiers; added read_imm_for_udiv_or_umod and read_imm_for_sdiv_or_smod functions; refactored diffcsts_of_assign.
src/test/test_yaml.cpp Added a new test case using YAML_CASE("test-data/muldiv.yaml") for YAML testing.
test-data/muldiv.yaml Introduced a new YAML test data file containing multiple test cases for division and modulo operations with negative divisors in 32-bit and 64-bit contexts.

Assessment against linked issues

Objective Addressed Explanation
Correctly perform unsigned 32-bit division and modulo (#[730])
Validate handling of negative divisors in division and modulo (#[730])

Possibly related PRs

  • Cleanup and modernize array_domain #691: The changes in src/crab/array_domain.cpp involve adding const qualifiers to function parameters, similar to the updates made in src/crab/split_dbm.cpp for methods like try_at and operator-=, enhancing type safety in both PRs.
  • Use gsl::narrow array_domain.cpp #708: This PR also modifies src/crab/array_domain.cpp, focusing on type safety with gsl::narrow, which aligns with the main PR's emphasis on improving type safety in arithmetic operations within SplitDBM.
  • Use gsl::narrow in asm files #710: Changes in src/asm_files.cpp include the use of gsl::narrow for safer type conversions, which is consistent with the main PR's goal of enhancing type safety in arithmetic operations in SplitDBM.

Poem

In the world of code, we hop and play,
With divisions and remainders, bright as day.
Conditional casts, oh what a delight,
Testing our logic, making it right!
From YAML we gather, our cases so neat,
In 32 and 64, our numbers compete! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 3427faa and 5f381d8.

📒 Files selected for processing (3)
  • src/crab/split_dbm.cpp (1 hunks)
  • src/test/test_yaml.cpp (1 hunks)
  • test-data/muldiv.yaml (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
test-data/muldiv.yaml (2)

4-16: LGTM: 32-bit division test case is correct and comprehensive.

This test case effectively verifies the behavior of 32-bit unsigned division with a negative divisor. The expected result (1) matches the actual result of the operation, demonstrating correct handling of unsigned division in 32-bit context.


19-30: LGTM: 32-bit modulo test case is accurate and well-defined.

This test case successfully validates the behavior of 32-bit unsigned modulo operation with a negative divisor. The expected result (97779712) aligns with the actual outcome of the operation, demonstrating proper handling of unsigned modulo in 32-bit context.

src/test/test_yaml.cpp (1)

35-35: LGTM! New test case added correctly.

The addition of YAML_CASE("test-data/muldiv.yaml") is consistent with the existing structure and follows the correct pattern. This new test case aligns with the PR objectives, focusing on unsigned division and modulo operations.

Let's verify the existence of the new test file:

src/crab/split_dbm.cpp (1)

1011-1022: Request Verification of Immediate Value Casting Rules

To ensure compliance with the BPF ISA specification, please verify whether the immediate value for 64-bit unsigned division and modulo operations should be treated as a signed 32-bit integer (int32_t) or an unsigned 32-bit integer (uint32_t). The current implementation casts to int32_t when finite_width is 64, which may not align with the specification if the immediate should be unsigned.

Run the following script to check for any inconsistencies in the immediate value casting within the codebase:

Also applies to: 1024-1034

test-data/muldiv.yaml Show resolved Hide resolved
test-data/muldiv.yaml Show resolved Hide resolved
test-data/muldiv.yaml Show resolved Hide resolved
src/crab/split_dbm.cpp Outdated Show resolved Hide resolved
src/crab/split_dbm.cpp Outdated Show resolved Hide resolved
@coveralls
Copy link

coveralls commented Oct 15, 2024

Coverage Status

coverage: 90.312% (+0.02%) from 90.292%
when pulling a57f728 on Alan-Jowett:issue730
into 3427faa on vbpf:main.

src/crab/split_dbm.cpp Outdated Show resolved Hide resolved
Signed-off-by: Alan Jowett <[email protected]>
Copy link

@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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 5f381d8 and f86ba52.

📒 Files selected for processing (1)
  • src/crab/split_dbm.cpp (2 hunks)
🧰 Additional context used
📓 Learnings (2)
📓 Common learnings
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#731
File: src/crab/split_dbm.cpp:1024-1034
Timestamp: 2024-10-15T16:40:13.215Z
Learning: In the BPF ISA specification, for 64-bit unsigned modulo operations, the immediate value is treated as a 32-bit signed integer, so casting to `int32_t` is correct.
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#731
File: src/crab/split_dbm.cpp:1011-1022
Timestamp: 2024-10-15T16:41:02.868Z
Learning: In the BPF ISA specification, for 64-bit unsigned division operations, the immediate value is sign-extended from 32 bits to 64 bits and then interpreted as a 64-bit unsigned value, so casting to `int32_t` is correct.
src/crab/split_dbm.cpp (2)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#731
File: src/crab/split_dbm.cpp:1024-1034
Timestamp: 2024-10-15T16:40:13.215Z
Learning: In the BPF ISA specification, for 64-bit unsigned modulo operations, the immediate value is treated as a 32-bit signed integer, so casting to `int32_t` is correct.
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#731
File: src/crab/split_dbm.cpp:1011-1022
Timestamp: 2024-10-15T16:41:02.868Z
Learning: In the BPF ISA specification, for 64-bit unsigned division operations, the immediate value is sign-extended from 32 bits to 64 bits and then interpreted as a 64-bit unsigned value, so casting to `int32_t` is correct.
🔇 Additional comments (3)
src/crab/split_dbm.cpp (3)

1001-1012: Correct handling of immediate values for unsigned division and modulo

The function read_imm_for_udiv_or_umod correctly implements the casting of immediate values for unsigned division and modulo operations according to the BPF ISA specification. By casting to uint32_t for 32-bit width and to int32_t for 64-bit width, it ensures that immediate values are interpreted correctly, including proper sign extension for 64-bit operations.


1014-1025: Correct handling of immediate values for signed division and modulo

The function read_imm_for_sdiv_or_smod appropriately handles immediate values for signed division and modulo operations in line with the BPF ISA specification. Casting to int32_t for 32-bit width and to int64_t for 64-bit width ensures that immediate values are correctly sign-extended and interpreted as signed integers of the appropriate width.


1036-1039: Appropriate use of helper functions in arithmetic operations

In the apply method, the updated cases for SDIV, UDIV, SREM, and UREM correctly utilize the helper functions read_imm_for_sdiv_or_smod and read_imm_for_udiv_or_umod to handle immediate values appropriately, ensuring compliance with the BPF ISA specification.

src/crab/split_dbm.cpp Outdated Show resolved Hide resolved
Signed-off-by: Elazar Gershuni <[email protected]>
Copy link

@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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between f86ba52 and a57f728.

📒 Files selected for processing (1)
  • src/crab/split_dbm.cpp (11 hunks)
🧰 Additional context used
📓 Learnings (1)
src/crab/split_dbm.cpp (1)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#731
File: src/crab/split_dbm.cpp:1005-1012
Timestamp: 2024-10-15T18:33:28.643Z
Learning: In `src/crab/split_dbm.cpp`, the functions `read_imm_for_udiv_or_umod` and `read_imm_for_sdiv_or_smod` are intentionally kept separate to clarify the differences between unsigned and signed division and modulo operations.
🔇 Additional comments (4)
src/crab/split_dbm.cpp (4)

1006-1012: read_imm_for_udiv_or_umod and read_imm_for_sdiv_or_smod correctly handle immediate values per BPF ISA specification

The implementation of read_imm_for_udiv_or_umod and read_imm_for_sdiv_or_smod accurately reflects the BPF ISA specification for handling immediate values in unsigned and signed division and modulo operations. Keeping these functions separate enhances code clarity by explicitly distinguishing between the different treatments of immediate values based on operation type and bit width.

Also applies to: 1014-1024


1034-1036: Ensure correct construction of linear_expression_t for multiplication

In the MUL case of the apply method, the line:

assign(x, linear_expression_t(k, y));

It's important to verify that linear_expression_t is correctly constructed to represent the expression y * k. Ensure that the constructor linear_expression_t(k, y) properly initializes the linear expression for multiplication, as this may not be immediately clear and could lead to incorrect behavior if k and y are misinterpreted.


983-984: Consistent handling of finite widths in arithmetic operations

The methods apply for both variable and immediate operations accept finite_width as a parameter. Ensure that the finite_width is consistently used within these methods when calling functions like get_interval, SDiv, UDiv, etc., to correctly handle operations according to the specified bit widths and to prevent unintended behavior due to width mismatches.

Also applies to: 1026-1027


15-15: 🛠️ Refactor suggestion

Consider passing variable_t and fundamental types by const reference

Several functions are updated to pass variable_t and fundamental types like int by value with a const qualifier. For non-trivial types like variable_t, passing by const reference (i.e., const variable_t&) can avoid unnecessary copying and improve performance. For fundamental types like int, passing by value is acceptable and efficient, and the const qualifier can be omitted as it doesn't affect the function signature.

Also applies to: 743-743, 926-926, 950-950, 983-984, 1026-1027, 1223-1223, 1233-1233, 1309-1309, 1336-1336

⛔ Skipped due to learnings
Learnt from: elazarg
PR: vbpf/ebpf-verifier#689
File: src/crab/split_dbm.cpp:910-910
Timestamp: 2024-09-26T00:57:58.072Z
Learning: Avoid suggesting changes that are unrelated to the current PR.

src/crab/split_dbm.cpp Show resolved Hide resolved
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.

Verifier doesn't correctly perform unsigned 32-bit division and modulo
4 participants