[AggressiveInstCombine] Recognizing tail truncation in the popcount pattern (#198658)
We're currently able to recognize the following popcount pattern
```
int popcnt(unsigned x) {
x = x - ((x >> 1) & 0x55555555);
x = x - 3*((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 0x0000003F;
}
```
but if a truncation follows right after the last AND instruction:
```
int16_t popcnt(unsigned x) {
x = x - ((x >> 1) & 0x55555555);
x = x - 3*((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x >> 8);
x = x + (x >> 16);
return int16_t(x & 0x0000003F);
}
```
since InstCombine canonicalizes `(trunc (and y, C))` into `(and
trunc(y), C')`, we might loose the opportunity to turn the above snippet
into `(trunc (popcount x))` as there is a `trunc` interrupting the
pattern matching.
This patch fixes this issue by considering this extra `trunc` during
pattern matching, and appending it in the final popcount result, if
there is any.