https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126212
Bug ID: 126212
Summary: ranger: missing optimization in propagation of a known
boolean on a threading path
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: aldyh at gcc dot gnu.org
CC: amacleod at redhat dot com
Target Milestone: ---
[Reproduce with -O2 -fdump-tree-dom-all.
For cfgloopmanip.ii, distilled from a stage1 bootstrap, the DOM tables
are resolving a conditional on a path which ranger cannot. I am
attaching a couple patches to reproduce this:
(a) instrumentation for DOM to ICE on DOM<->ranger differences
(b) a patch from Andrew fixing unrelated relations from PR125986.
(c) a temporary hack to silence some discrepancies due to changing IL.
With these we ICE while trying to unsuccesfully fold:
if (_1 == latch_271)
The threading candidate path is BB234->BB259.
On entry to BB234 to we can prove that the above conditional is false like
this:
BB2:
_2 = (_1 == latch_271)
...
... (BB2 dominates BB17)
...
BB17:
_22 = _2 & _21
if (_22 != 0)
blah
else
goto bb19
BB19:
// _22 == 0 is known on entry
...
... (BB19 dominates BB233)
...
BB233:
// The actual IL here is "if (add_irreducible_flag_291 != 0)". DOM has
// recorded this as redundant with _21 (_21 = add_irreducible_flag_291
// != 0), and ranger likewise derives _21 == [1,1] on the taken edge,
so
// this is equivalent to:
if (_21 != 0)
goto bb234
else
blah
BB234:
// _21 != 0 is known on entry
>From BB17 we have:
_22 = _2 & _21 =====> 0 = _2 & 1 =====> 0 = _2
and since _2 = (_1 == latch_271), we can solve the original conditional as
false:
if (_1 == latch_271) <==== false
I have instrumented DOM at the threading candidate and I can see that the root
ranger has:
root range_on_entry(bb234, _2 (_1 == latch_271)) = [irange] bool VARYING
root range_on_entry(bb234, _21 (add_irr != 0) ) = [irange] bool [1, 1]
root range_on_entry(bb234, _22 (_2 & _21) ) = [irange] bool [0, 0]
root range_on_entry(bb234, _1 ) = [prange] struct
basic_block_def * VARYING
root range_on_entry(bb234, latch_271 ) = [prange] struct
basic_block_def * VARYING
Since we know what _22 and _21 are, we should be able to solve for _2 easily:
_22 = _2 & _21
So this looks like a ranger problem, not a path ranger problem.