https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81601
--- Comment #20 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- Created attachment 43233 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43233&action=edit WIP that fixes PR, but causes other regressions I am attaching a proof of concept hack that fixes this PR by moving the optimize_bit_field_compare functionality from the front-end to the gimple reassoc pass (picked at random, we could do it anywhere else). It recognizes the following pattern: _1 = some.bit_field; if (_1 == 99) ...and converts it to a BIT_FIELD_REF + comparison. Although it works for the PR, it creates various regressions, because it seems fold_truth_andor can create optimized bit field comparisons as well, which would be challenging to deconstruct later in gimple. For example. Imagine this: enum output_type { type_pde, type_relocatable, type_pie, type_dll, }; struct bfd_link_info { enum output_type type : 2; }; void test_pic (struct bfd_link_info *info) { if ((((info)->type == type_dll) || ((info)->type == type_pie))) blah(); } Thanks to fold_truth_andor (fold_range_test specifically), if we were to delay optimize_bit_field_compare(), we would generate the following coming out of the front-end: if (info->type + 2 <= 1) blah(); That is, not only have we merged the set of bit field comparisons, we have also introduced an unsigned overflow to make the comparison simpler. So now our gimple optimize bit field compare function would also have to deal with this: _1 = info_7(D)->type; _2 = _1 + 2; if (_2 <= 1) and perhaps convert it to: _5 = BIT_FIELD_REF <*info, 8, 0> _6 = (_5 + 2) & 3 if (_6 <= 1) My worry is that we can handle optimizations of the following quite easily (attached patch): _1 = some.bit_field; if (_1 == 99) but with things like the following, it starts getting harder and harder: _1 = info_7(D)->type; _2 = _1 + 2; if (_2 <= 1) And I'm pretty sure fold_truth_andor() has a lot more tricks up its sleeve, that we'll have to mop up in gimple. All in all, I doubt we can sensibly move optimize_bit_field_compare() to the middle end, without having to bend over backwards to reconstruct things or port some of fold_truth_andor() to the middle end as well. I doubt this is stage4 material. I can certainly teach my WIP to handle the _2 = _1 + 2 case above without porting fold_truth_andor*() to the middle end, but I'm afraid this is just one of the many scenarios we'll have to deal with. I could be wrong, and could certainly take a stab at it. Oh, and I'm completely ignoring the reassocation suggestions Jakub makes in comment 19. That would make even more work for stage4 :). Thoughts?