I compared the generated code with an equivalent explicit test, and discovered that gcc uses a separate rtx for the intermediate:
i = 0xfffff; if (j >= 16) { int i2; i2 = i >> 8; i = i2 >> 8; j -= 16; } This seems to avoid the combiner problem, becuase you don't have the same register being set and being used in one insn. Does this explain why combine was having a problem, or was this a legitimate thing to do and the combiner is still wrong? Using a temp in the expander works around the problem.