https://gcc.gnu.org/bugzilla/show_bug.cgi?id=27504
--- Comment #7 from Jeffrey A. Law <law at gcc dot gnu.org> ---
So an interesting little problem.
;; basic block 2, loop depth 0
;; pred: ENTRY
if (x_3(D) != 0)
goto <bb 3>; [50.00%]
else
goto <bb 4>; [50.00%]
;; succ: 3
;; 4
;; basic block 3, loop depth 0
;; pred: 2
_1 = x_3(D) & 85;
_5 = _1 != 0;
_6 = (int) _5;
;; succ: 4
;; basic block 4, loop depth 0
;; pred: 3
;; 2
# iftmp.0_2 = PHI <_6(3), x_3(D)(2)>
return iftmp.0_2;
DOM realizes the value for x_3 is 0 when we traverse the edge 2->4 resulting
in:
;; basic block 2, loop depth 0
;; pred: ENTRY
if (x_3(D) != 0)
goto <bb 3>; [50.00%]
else
goto <bb 4>; [50.00%]
;; succ: 3
;; 4
;; basic block 3, loop depth 0
;; pred: 2
_1 = x_3(D) & 85;
_5 = _1 != 0;
_6 = (int) _5;
;; succ: 4
;; basic block 4, loop depth 0
;; pred: 3
;; 2
# iftmp.0_2 = PHI <_6(3), 0(2)>
return iftmp.0_2;
Now what we want to do is prove that if we use the value 0 for x_3 on the other
path that resulting value for _6 would also be zero. Which it is.
_1 = x_3(D) & 85; // substiute 0 for x_3 and the result will be _1 = 0
_5 = 0 != 0; // And substitute the know value for _1. resulting in _5 =
0
_6 = (int) _5; // And substitute the known value for _5. _6 = 0;
So if we were to eliminate the branch (say by making it always false), So we
could make the conditional branch always false and simplify all that to:
_1 = x_3(D) & 85;
_5 = _1 != 0;
_6 = (int) _5;
iftmp.0_2 = _6
return iftmp.0_2;
And copy propagation would do its thing and simpify it a bit further.
This has notable similarities to what Daniel is currently poking at in DOM.
It's not that hard :-) Though it would take a different approach than how
Daniel is currently taking.