https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108370
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed| |2023-01-11
Ever confirmed|0 |1
Keywords| |missed-optimization
Status|UNCONFIRMED |NEW
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
The good case is handled by ifcombine:
optimizing bits or bits test to _5 & T != 0
with temporary T = 2 | 1
Merging blocks 2 and 3
<bb 2> [local count: 1073741824]:
_5 = bio_4(D)->bi_flags;
_8 = _5 & 1;
if (_8 != 0)
goto <bb 4>; [33.00%]
else
goto <bb 3>; [67.00%]
<bb 3> [local count: 719407025]:
_9 = _5 & 2;
if (_9 != 0)
goto <bb 4>; [50.00%]
else
goto <bb 5>; [50.00%]
<bb 4> [local count: 714038313]:
_1 = (int) mark_dirty_6(D);
__bio_release_pages (bio_4(D), _1);
but the bad case is not handled:
<bb 2> [local count: 1073741824]:
_6 = bio_4(D)->bi_flags;
_5 = (unsigned int) _6;
_9 = (_Bool) _6;
if (_9 != 0)
goto <bb 4>; [33.00%]
else
goto <bb 3>; [67.00%]
<bb 3> [local count: 719407025]:
_10 = _5 >> 1;
_11 = (_Bool) _10;
if (_11 != 0)
goto <bb 4>; [50.00%]
else
goto <bb 5>; [50.00%]
<bb 4> [local count: 714038313]:
_1 = (int) mark_dirty_7(D);
__bio_release_pages (bio_4(D), _1);
it looks like some premature optimization triggered (not) there.
.original is (good)
;; Function bio_flagged (null)
;; enabled by -tree-original
{
return ((unsigned int) bio->bi_flags & 1 << bit) != 0;
}
vs (bad)
;; Function bio_flagged (null)
;; enabled by -tree-original
{
return ((unsigned int) bio->bi_flags >> bit & 1) != 0;
}
I suppose one variant is folded after the promotion to bool and one
before only.