https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93131
--- Comment #18 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Guess best would be to go through the ranges from first to last, check for the pattern we are interested in (ranges[i].exp being SSA_NAME with BIT_AND_EXPR def with constant where ranges[i].low == ranges[i].high is an integer, so is the second operand of BIT_AND_EXPR, verify also the condition we've discussed above ((CST1&~N) == 0) and whether ranges[i].in_p matches the kind of operation (opcode and for opcode ERROR_MARK dig out the || vs. &&), push e.g. indexes of those ranges into a vector, then have a gcc_sort_r callback that will put the indexes for the same BIT_AND_EXPR first operand next to each other and then just go through them, construct a new comparison for all the adjacent entries for the same base var and nullify the rest. Testcase showing why it is needed: void bar (void); int f1 (int a) { return (a & 8) == 8 && (a & 2) == 2 && (a & 4) == 4; } int f2 (int a) { int x = (a & 8) == 8; int y = (a & 2) == 2; int z = (a & 4) == 4; return x && y && z; } int f3 (int a) { return (a & (8 | 2 | 4)) == (8 | 2 | 4); } void f4 (int a) { int x = (a & 8) == 8; int y = (a & 2) == 2; int z = (a & 4) == 4; int u = (a & 16) == 16; int v = (a & 64) == 64; int w = (a & 256) == 256; if (x && y && z && u && v && w) bar (); } int f5 (int a) { return (a & 8) != 8 || (a & 2) != 2 || (a & 4) != 4; } int f6 (int a) { int x = (a & 8) != 8; int y = (a & 2) != 2; int z = (a & 4) != 4; return x || y || z; } int f7 (int a) { return (a & (8 | 2 | 4)) != (8 | 2 | 4); } void f8 (int a) { int x = (a & 8) != 8; int y = (a & 2) != 2; int z = (a & 4) != 4; int u = (a & 16) != 16; int v = (a & 64) != 64; int w = (a & 256) != 256; if (x || y || z || u || v || w) bar (); }