https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125707

Drea Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
           Severity|normal                      |enhancement
   Last reconfirmed|                            |2026-06-10
     Ever confirmed|0                           |1
            Summary|Possible missed             |(~a)>>a should be
                   |optimization at O3 (also O2 |simplified into -1
                   |and O1)                     |
           Keywords|                            |easyhack,
                   |                            |missed-optimization

--- Comment #1 from Drea Pinski <pinskia at gcc dot gnu.org> ---

  # RANGE [irange] int8_t [0, 2] MASK 0x3 VALUE 0x0
  int8_t v3_i8_5(D) = v3_i8;

  # RANGE [irange] int8_t [-3, -1] MASK 0x3 VALUE 0xfc
  i0_i8_6 = ~v3_i8_5(D);
  # RANGE [irange] int [-3, -1] MASK 0x3 VALUE 0xfffffffc
  _2 = (int) i0_i8_6;
  # RANGE [irange] int [0, 2] MASK 0x3 VALUE 0x0
  _3 = (int) v3_i8_5(D);
  # RANGE [irange] int [-3, -1] MASK 0x3 VALUE 0xfffffffc
  _4 = _2 >> _3;

GCC does not see the relationship between _2 and _3.

I am not even sure this is worth it.


Changing to use int/unsigned, GCC gets:
  # RANGE [irange] unsigned int [0, 2] MASK 0x3 VALUE 0x0
  v3_i8.0_1 = (unsigned int) v3_i8_2(D);
  # RANGE [irange] int [-3, -1] MASK 0x3 VALUE 0xfffffffc
  i0_i8_3 = ~v3_i8_2(D);
  # RANGE [irange] int [-3, -1] MASK 0x3 VALUE 0xfffffffc
  i1_i8_4 = i0_i8_3 >> v3_i8.0_1;

So this is (~a)>>a; with a range of [0,2]. -3>>2 is -1.

So the Actually missed optimization is just:
int src(int a) {
  return (~a)>>a;
}
is -1.

Reply via email to