Skip to content

Conversation

@alister-chowdhury
Copy link
Contributor

@alister-chowdhury alister-chowdhury commented Dec 8, 2025

It seems that things like (a ? 1u : 0u) == 1u are surprisingly prevalent.
When the select results are constants and a binary op is constant, we can merge the result directly into the select.
The following cases have been added:

  ((a ? C0 : C1) == C2)  =  ((a ? (C0 == C2) : (C1 == C2))
  ((a ? C0 : C1) != C2)  =  ((a ? (C0 != C2) : (C1 != C2))
  ((a ? C0 : C1) <  C2)  =  ((a ? (C0 <  C2) : (C1 <  C2))
  ((a ? C0 : C1) <= C2)  =  ((a ? (C0 <= C2) : (C1 <= C2))
  ((a ? C0 : C1) >  C2)  =  ((a ? (C0 >  C2) : (C1 >  C2))
  ((a ? C0 : C1) >= C2)  =  ((a ? (C0 >= C2) : (C1 >= C2))
  ((a ? C0 : C1) || C2)  =  ((a ? (C0 || C2) : (C1 || C2))
  ((a ? C0 : C1) && C2)  =  ((a ? (C0 && C2) : (C1 && C2))
  ((a ? C0 : C1) +  C2)  =  ((a ? (C0 +  C2) : (C1 +  C2))
  ((a ? C0 : C1) -  C2)  =  ((a ? (C0 -  C2) : (C1 -  C2))
  ((a ? C0 : C1) *  C2)  =  ((a ? (C0 *  C2) : (C1 *  C2))
  ((a ? C0 : C1) /  C2)  =  ((a ? (C0 /  C2) : (C1 /  C2))
  ((a ? C0 : C1) >> C2)  =  ((a ? (C0 >> C2) : (C1 >> C2))
  ((a ? C0 : C1) << C2)  =  ((a ? (C0 << C2) : (C1 << C2))
  ((a ? C0 : C1) ^  C2)  =  ((a ? (C0 ^  C2) : (C1 ^  C2))
  ((a ? C0 : C1) |  C2)  =  ((a ? (C0 |  C2) : (C1 |  C2))
  ((a ? C0 : C1) &  C2)  =  ((a ? (C0 &  C2) : (C1 &  C2))

This further opens the door to further collapses like: (a ? true : false) = a

It seems that things like `(a ? 1u : 0u) == 1u` are surprisingly prevalent.

When the select results in constants and the comparison is constant, we can
merge the result directly into the select.

The following cases have been added:
```
  ((a ? C0 : C1) == C2)  =  ((a ? (C0 == C2) : (C1 == C2))
  ((a ? C0 : C1) != C2)  =  ((a ? (C0 != C2) : (C1 != C2))
  ((a ? C0 : C1) <  C2)  =  ((a ? (C0 <  C2) : (C1 <  C2))
  ((a ? C0 : C1) <= C2)  =  ((a ? (C0 <= C2) : (C1 <= C2))
  ((a ? C0 : C1) >  C2)  =  ((a ? (C0 >  C2) : (C1 >  C2))
  ((a ? C0 : C1) >= C2)  =  ((a ? (C0 >= C2) : (C1 >= C2))
  ((a ? C0 : C1) || C2)  =  ((a ? (C0 || C2) : (C1 || C2))
  ((a ? C0 : C1) && C2)  =  ((a ? (C0 && C2) : (C1 && C2))
```

This further opens the door to further collapses like: `(a ? true : false) = a`
@alister-chowdhury
Copy link
Contributor Author

alister-chowdhury commented Dec 9, 2025

I'm not sure why I didn't realise this, but I should really extend this to other binary ops that could practically be constant folded (adds, subs, muls etc)

Updated review and description.

@s-perron s-perron self-requested a review December 10, 2025 16:17
```
  ((a ? C0 : C1) +  C2)  =  ((a ? (C0 +  C2) : (C1 +  C2))
  ((a ? C0 : C1) -  C2)  =  ((a ? (C0 -  C2) : (C1 -  C2))
  ((a ? C0 : C1) *  C2)  =  ((a ? (C0 *  C2) : (C1 *  C2))
  ((a ? C0 : C1) /  C2)  =  ((a ? (C0 /  C2) : (C1 /  C2))
  ((a ? C0 : C1) >> C2)  =  ((a ? (C0 >> C2) : (C1 >> C2))
  ((a ? C0 : C1) << C2)  =  ((a ? (C0 << C2) : (C1 << C2))
  ((a ? C0 : C1) ^  C2)  =  ((a ? (C0 ^  C2) : (C1 ^  C2))
  ((a ? C0 : C1) |  C2)  =  ((a ? (C0 |  C2) : (C1 |  C2))
  ((a ? C0 : C1) &  C2)  =  ((a ? (C0 &  C2) : (C1 &  C2))
```

Also sprinkled a few tests which switch lhs and rhs for the op being
folded.
@alister-chowdhury alister-chowdhury changed the title spriv-opt: Adding a rule to merge select-comparisons spriv-opt: Adding a rule to merge select-binaryop Dec 11, 2025
@s-perron s-perron requested review from luciechoi and removed request for s-perron December 12, 2025 19:37
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.

1 participant