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.

Reply via email to