Skip to content

[Util] Add int narrowing pattern for arith.select#23928

Open
Max191 wants to merge 1 commit intoiree-org:mainfrom
Max191:select-narrowing
Open

[Util] Add int narrowing pattern for arith.select#23928
Max191 wants to merge 1 commit intoiree-org:mainfrom
Max191:select-narrowing

Conversation

@Max191
Copy link
Copy Markdown
Contributor

@Max191 Max191 commented Mar 25, 2026

Narrow arith.select through index_cast ops when both true/false operands are either index_cast from a narrower type or arith.constant. For example:

  %t = arith.index_cast %a : i32 to index
  %f = arith.constant 0 : index
  %s = arith.select %cond, %t, %f : index
  ->
  %f_narrow = arith.constant 0 : i32
  %s_narrow = arith.select %cond, %a, %f_narrow : i32
  %s = arith.index_cast %s_narrow : i32 to index

Narrow arith.select through index_cast ops when both true/false
operands are either index_cast from a narrower type or arith.constant.
This handles the common pattern from boolean mask computation:

  %t = arith.index_cast %a : i32 to index
  %f = arith.constant 0 : index
  %s = arith.select %cond, %t, %f : index
  ->
  %f_narrow = arith.constant 0 : i32
  %s_narrow = arith.select %cond, %a, %f_narrow : i32
  %s = arith.index_cast %s_narrow : i32 to index

Signed-off-by: Max Dawkins <max.dawkins@gmail.com>
@Max191 Max191 requested a review from benvanik as a code owner March 25, 2026 19:55
@Max191 Max191 requested a review from krzysz00 March 25, 2026 19:55
Comment on lines +382 to +386
// Constant with a value that fits in the narrow type.
auto constOp = dyn_cast<arith::ConstantOp>(defOp);
if (!constOp) {
return false;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we use ConstantLikeInterface maybe?

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.

I don't think an interface exists for it, but I think I can use the ConstantLike trait. I'll update the implementation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are m_Constant-type matchers.

Copy link
Copy Markdown
Contributor

@krzysz00 krzysz00 left a comment

Choose a reason for hiding this comment

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

I've got some implementation comments

if (!trueDef || !falseDef) {
return failure();
}
Operation *castOp =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This could probably work on extsi/extui also, and I colud've sworn there's a nice helper for this.

Also, what you're looking for is isa<IndexCastOp, IndexCastUIOp>(trueDef) and similar for falseDef - if it isa one of these, you've found the castOp.

narrowElemTy;
}
// Constant with a value that fits in the narrow type.
auto constOp = dyn_cast<arith::ConstantOp>(defOp);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You could check for the range being constant here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I think the check is if the min == max of this value fits in the narrower type.

Also, I think there's code elsewhere around here that handles similar tests for for lops.

if (defOp->getName() == castOp->getName()) {
return defOp->getOperand(0);
}
auto intAttr = cast<IntegerAttr>(cast<arith::ConstantOp>(defOp).getValue());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think for this case I'd either follow existing logic for materializing constants in a generic way or I'd just createOrFold the relevant truncation to get the new constant.

@Groverkss
Copy link
Copy Markdown
Contributor

(my comment is drive-by, non need to wait for me)

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.

3 participants