https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110413

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
      Known to work|                            |11.4.0, 12.3.0
   Last reconfirmed|                            |2023-06-27

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
GCC 13 eliminates the call in DOM3.  The differences into that pass are quite
big with trunk having performed many more optimizations, in particular
we have elided the __builtin_unreachable () call already in DOM2 where
the first differences appears.  We now manage to simplify the _24 != 0
branch.

@@ -79,22 +80,15 @@
   _22 = _2 <= &d;
   _23 = _2 != 0B;
   _24 = _23 & _22;
-  if (_24 != 0)
-    goto <bb 5>; [100.00%]
-  else
-    goto <bb 4>; [0.00%]
+  goto <bb 4>; [100.00%]

   <bb 3> [local count: 850510901]:
   k = _2;
   _3 = 1;
   _1 = 1;
   _15 = 1;
-  goto <bb 5>; [100.00%]
-
-  <bb 4> [count: 0]:
-  __builtin_unreachable ();

-  <bb 5> [local count: 955630225]:
+  <bb 4> [local count: 955630225]:

So we manage to optimize

  <bb 3> [local count: 105119324]:
  k = _2;
  _22 = _2 <= &d;
  _23 = _2 != 0B;
  _24 = _23 & _22;
  if (_24 != 0)
    goto <bb 6>; [100.00%]
  else
    goto <bb 5>; [0.00%]

  <bb 4> [local count: 850510901]:
  k = _2;
  _3 = _2 <= &d;
  _1 = _2 != 0B;
  _15 = _1 & _3;
  if (_15 != 0)
    goto <bb 6>; [100.00%]
  else
    goto <bb 5>; [0.00%]

  <bb 5> [count: 0]:
  __builtin_unreachable ();

  <bb 6> [local count: 955630225]:
  # h.4_25 = PHI <h.4_5(4), h.4_20(3)>
  _4 = h.4_25 + -1;
  h = _4;
  h.4_5 = h;
  if (h.4_5 != 0)
    goto <bb 4>; [89.00%]


It seems we're now doing this based on the exported global range table
since we correctly first arrive at

Optimizing block #3

Optimizing statement k = _2; 
LKUP STMT k = _2 with .MEM_11
LKUP STMT _2 = k with .MEM_11
LKUP STMT _2 = k with .MEM_21 
2>>> STMT _2 = k with .MEM_21
Optimizing statement _22 = _2 <= &d; 
LKUP STMT _22 = _2 le_expr &d
2>>> STMT _22 = _2 le_expr &d
LKUP STMT _2 ge_expr &d
Optimizing statement _23 = _2 != 0B;
LKUP STMT _23 = _2 ne_expr 0B
2>>> STMT _23 = _2 ne_expr 0B
Optimizing statement _24 = _23 & _22;
LKUP STMT _24 = _23 bit_and_expr _22
2>>> STMT _24 = _23 bit_and_expr _22
Optimizing statement if (_24 != 0)

Visiting conditional with predicate: if (_24 != 0)

With known ranges
        _24: [irange] _Bool VARYING

Predicate evaluates to: DON'T KNOW

but then we register global ranges from the __builtin_unreachable () CFG:

  # RANGE [irange] _Bool [1, 1]
  _24 = _23 & _22;

and CFG cleanup scheduled by DOM does

static bool
cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
{
...
        case GIMPLE_COND:
          {
            gimple_match_op res_op;
            if (gimple_simplify (stmt, &res_op, NULL, no_follow_ssa_edges,
                                 no_follow_ssa_edges)
                && res_op.code == INTEGER_CST)
              val = res_op.ops[0];

which now picks this up and elides the branch.

For some reason the "dead" stmts

  <bb 2> [local count: 118111600]:
  # PT = nonlocal null 
  _2 = j (); 
  i = _2;
  k = _2;
  # RANGE [irange] _Bool [1, 1]
  _22 = _2 <= &d; 
  # RANGE [irange] _Bool [1, 1]
  _23 = _2 != 0B;
  # RANGE [irange] _Bool [1, 1]
  _24 = _23 & _22;

allow us to optimize

  k = _2;
  # PT = nonlocal escaped null
  k.5_6 = k;
  _16 = k.5_6 == &g;
  _17 = k.5_6 != 0B;
  _18 = _17 | _16;
  if (_18 != 0)

via

Optimizing statement _16 = k.5_6 == &g;
  Replaced 'k.5_6' with variable '_2'
LKUP STMT _16 = _2 eq_expr &g
2>>> STMT _16 = _2 eq_expr &g
Optimizing statement _17 = k.5_6 != 0B;
  Replaced 'k.5_6' with variable '_2'
LKUP STMT _17 = _2 ne_expr 0B
FIND: _23
  Replaced redundant expr '_2 != 0B' with '_23'
==== ASGN _17 = _23
Optimizing statement _18 = _17 | _16;
  Replaced '_17' with variable '_23'
  Folded to: _18 = _16 | _23;
LKUP STMT _18 = _16 bit_ior_expr _23
2>>> STMT _18 = _16 bit_ior_expr _23
Optimizing statement if (_18 != 0)
  Replaced '_18' with constant '1'

so it's kind of a missed optimization in the first DOM that elides the
stmts and the inability of ranger to capture the relations in the global
ranges.

Reply via email to