On 8/24/2026 7:03 AM, Aldy Hernandez wrote:
[Richi, per your suggestion...is this what you had in mind?]
DOM's jump threader duplicates a join block that merges comparisons
into a boolean that is immediately tested:
<bb 3>:
t_9 = a < b;
goto <bb 5>;
<bb 4>:
t_6 = c < d;
goto <bb 5>;
<bb 5>:
# t_1 = PHI <t_9(3), t_6(4)>
if (t_1 != 0)
Jeez. More stuff I don't remember adding. Presumably the goal here is
to duplicate the test from bb5 into bb3 and change it to test a < b and
a similar transformation in bb4 testing c < d which likely happens after
DOM was run. It probably opens up potential threading opportunities as
well.
Implement this optimization in the phiopt pass, without using the jump
threading machinery DOM's version uses. This was an optimization we
lost with the jump threader rewrite, which DOM ended up picking up.
Given the compile-time cost of DOM vs phiopt and the fact that we run
phiopt repeatedly through the pipeline, this seems like a very sensible
thing to do.
Measured over GCC's own sources plus LAPACK, the phiopt version takes
over ~94% of the joins DOM's special case caught: DOM registrations
for this optimization drop from 3536 to 196, with 1325 phiopt
replications; the remainder are cases that show up between phiopt and
DOM. Optimizations at loop boundaries (approx 700) are deliberately
left to the DOM threader, as replicating those would change loop
structure. I could loosen this restriction, but I've learned to fear
all things loop ;-).
I've left DOM's version in place, just in case we still want to allow
it for loop things, but I can just as easily drop it in a follow-up
patch.
If the goal is to remove DOM or at least significantly neuter it, then
we probably want to loosen the restriction in phiopt, though given my
lack of memory of this code I couldn't even start to suggest what
heuristics we might want or if there were meaningful testcases which
drove the desire for this optimization.
Tested on ppc64le Linux.
OK?
PR tree-optimization/126896
gcc/ChangeLog:
* tree-ssa-phiopt.cc: Include tree-ssa-threadedge.h.
(preserves_loop_structure_p): New.
(replicate_cond_into_pred): New.
(replicate_conds_over_phis): New.
(pass_phiopt::execute): Call replicate_conds_over_phis.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/phi_on_compare-1.c: Scan the phiopt2 dump.
* gcc.dg/tree-ssa/phi_on_compare-2.c: Scan the optimized dump.
* gcc.dg/tree-ssa/phi_on_compare-3.c: Likewise.
* gcc.dg/tree-ssa/dom-jump-threading-1.c: Disable phiopt.
* gcc.dg/tree-ssa/dom-jump-threading-2.c: Likewise.
* gcc.dg/tree-ssa/phi_on_compare-5.c: New test.
So just one question, why is this gated on !early? Everything looks
sensible to me.
Jeff