Skip to content

[P4HIR] Fix unsound CastOp chain folding (#317)#333

Open
AbdallahRashed wants to merge 1 commit intop4lang:mainfrom
AbdallahRashed:fix_castop_canonicalization
Open

[P4HIR] Fix unsound CastOp chain folding (#317)#333
AbdallahRashed wants to merge 1 commit intop4lang:mainfrom
AbdallahRashed:fix_castop_canonicalization

Conversation

@AbdallahRashed
Copy link
Copy Markdown

Cast chains A→B→C were unconditionally folded to A→C, but this changes semantics when B alters signedness before a widening cast (e.g. bit<8>→int<8>→int<16> sign-extends, but bit<8>→int<16> zero-extends).

Only fold when the second cast doesn't widen, or the first cast preserves signedness without truncating.

Fixes #317

Cast chains A→B→C were unconditionally folded to A→C, but this
changes semantics when B alters signedness before a widening cast
(e.g. bit<8>→int<8>→int<16> sign-extends, but bit<8>→int<16>
zero-extends).

Only fold when the second cast doesn't widen, or the first cast
preserves signedness without truncating.

Fixes p4lang#317
@AbdallahRashed AbdallahRashed force-pushed the fix_castop_canonicalization branch from f6c8a4c to 29ea2fd Compare March 28, 2026 18:47
@AbdallahRashed
Copy link
Copy Markdown
Author

I am opening this PR, to express my interest in GSOC: [Project 3.1: Alkali-P4MLIR: Bridging P4 and SmartNICs Through MLIR Dialect Conversion Between Alkali IR and P4MLIR]
Thank you

Copy link
Copy Markdown
Collaborator

@mtsamis mtsamis left a comment

Choose a reason for hiding this comment

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

Please see some adjustments to make

/// signedness, so the widening in the second cast uses the same extension
/// type as the direct A -> C cast would.
static bool isSafeCastComposition(mlir::Type srcType, mlir::Type midType, mlir::Type dstType) {
if (srcType == midType || midType == dstType) return true;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Shouldn't be needed due to what we have in CastOp::fold

return wA <= wB && srcBits.isSigned() == midBits.isSigned();
}

// For non-BitsType chains, be conservative and don't fold.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you please make this more complete by also handling booleans? They should be fairly easy to add and then you can also remove this comment.

/// The key unsafe case is when the second cast widens (w_B < w_C), because
/// the extension type (zero vs sign) depends on the source's signedness.
/// If the intermediate type B differs from A in a way that changes how
/// the widening is performed, the fold would alter semantics.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think this middle section of comments is overly verbose.
The safe cases are explained below and naming this the "key unsafe case" is somewhat misleading (I would say truncation is also key).

@mtsamis mtsamis assigned mtsamis and unassigned mtsamis Apr 1, 2026
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.

Fix CastOp canonicalization

2 participants