https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93150
--- Comment #4 from Navid Rahimi <navidrahimi at microsoft dot com> --- Although I wrote a small code to just test this optimization. But I am not able to verify this transformation [1]. https://alive2.llvm.org/ce/z/THP27D The code can be something like this but if I were able to verify the optimization, I don't see any reason why N, M, O should be constant too. /* ((x & N) == CST1) bitop1 (((x & M) == CST2) bitop2 ((x & O) == CST3)) -> ((x & (N | M)) == (CST1 | CST2)) bitopt2 ((x & (N | O)) == (CST1 | CST3)) */ (for bitop1 (bit_and bit_or) bitop2 (bit_or bit_and) (for cmp (eq ne) (simplify (bitop1:c (cmp (bit_and @0 INTEGER_CST@N) INTEGER_CST@CST1) (bitop2 (cmp (bit_and @0 INTEGER_CST@N) INTEGER_CST@CST2) (cmp (bit_and @0 INTEGER_CST@N) INTEGER_CST@CST3))) (bitop2:c (cmp (bit_and:c @0 (bit_or INTEGER_CST@N INTEGER_CST@M)) (bit_or INTEGER_CST@CST1 INTEGER_CST@CST2)) (cmp (bit_and:c @0 (bit_or INTEGER_CST@N INTEGER_CST@O)) (bit_or INTEGER_CST@CST1 INTEGER_CST@CST3))))))