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`  .

Reply via email to