https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99082
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- ``` _8 = (unsigned int) _7; _9 = _8 << 16; _10 = _6 | _9; r8_20 = (const uint8_t) _10; ``` Obviously r8_20 should be assigned from (const uint8_t)_6 since _9's lower values are 0. Having a simple pattern like: (simplify (maybe_truncate (bit_or:c @0 @1)) (if (known_zero_bits (@1) & wi::typemask(type, TREE_TYPE (@0)) == 0) (convert @0)) Will help fix this I think but I am not sure if this is a reasonable thing to do though. We also have: _9 = _8 << 16; _10 = _6 | _9; r8_20 = (const uint8_t) _10; _21 = _10 >> 8; b8_22 = (const uint8_t) _21; _23 = _10 >> 16; Where we know that _6's upper 16 bits are 0 so _23 becomes _9 >> 16. and we know _8 already has only possible 8 bits in lower so further down to just _8.