https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120524
Bug ID: 120524
Summary: `(__int128_var >> 127) & 1` is not optimized to
((unsigned __int128)__int128_var ) >> 127 in gimple
level
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Take:
```
__int128_t f(__int128_t a)
{
__int128_t t = a >> 127;
return t & 1;
}
```
This does not opimize to:
```
__int128_t f1(__int128_t a)
{
unsigned __int128 t = a;
t >>= 127;
return t;
}
```
At the gimple level.
This is because the match pattern only works with HOST_WIDE_INT rather than
wi::wide_int:
```
/* Fold (X << C1) & C2 into (X << C1) & (C2 | ((1 << C1) - 1))
(X >> C1) & C2 into (X >> C1) & (C2 | ~((type) -1 >> C1))
if the new mask might be further optimized. */
(for shift (lshift rshift)
(simplify
(bit_and (convert?:s@4 (shift:s@5 (convert1?@3 @0) INTEGER_CST@1))
INTEGER_CST@2)
(if (tree_nop_conversion_p (TREE_TYPE (@4), TREE_TYPE (@5))
&& TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT
&& tree_fits_uhwi_p (@1)
&& tree_to_uhwi (@1) > 0
&& tree_to_uhwi (@1) < TYPE_PRECISION (type))
```
This pattern should be converted to use wi::wide_int instead of the current
`unsigned HOST_WIDE_INT` .