This is the first of 3-5 patches to address pr78496.
The goal of these patches is to catch jump threads earlier in the
pipeline to avoid undesirable behavior in PRE and more generally be able
to exploit the secondary opportunities exposed by jump threading.
One of the more serious issues I found while investigating 78496 was VRP
failing to find what should have been obvious jump threads. The
fundamental issue is VRP will simplify conditionals which are fed by a
typecast prior to jump threading. So something like this:
x = (typecast) y;
if (x == 42)
Can often be transformed into:
if (y == 42)
The problem is any ASSERT_EXPRS after the conditional will reference "x"
rather than "y". That in turn makes it impossible for VRP to use those
ASSERT_EXPRs to thread later jumps that use x == <whatever>
More concretely consider this gimple code:
;; basic block 5, loop depth 0, count 0, freq 10000, maybe hot
;; prev block 4, next block 12, flags: (NEW, REACHABLE, VISITED)
;; pred: 3 [50.0%] (TRUE_VALUE,EXECUTABLE)
;; 4 [100.0%] (FALLTHRU,EXECUTABLE)
# iftmp.0_2 = PHI <1(3), 0(4)>
in_loop_7 = (unsigned char) iftmp.0_2;
if (in_loop_7 != 0)
goto <bb 6>; [33.00%]
else
goto <bb 12>; [67.00%]
;; succ: 6 [33.0%] (TRUE_VALUE,EXECUTABLE)
;; 12 [67.0%] (FALSE_VALUE,EXECUTABLE)
;; basic block 12, loop depth 0, count 0, freq 6700, maybe hot
;; prev block 5, next block 6, flags: (NEW)
;; pred: 5 [67.0%] (FALSE_VALUE,EXECUTABLE)
in_loop_15 = ASSERT_EXPR <in_loop_7, in_loop_7 == 0>;
goto <bb 7>; [100.00%]
;; succ: 7 [100.0%] (FALLTHRU)
;; basic block 6, loop depth 0, count 0, freq 3300, maybe hot
;; prev block 12, next block 7, flags: (NEW, REACHABLE, VISITED)
;; pred: 5 [33.0%] (TRUE_VALUE,EXECUTABLE)
in_loop_14 = ASSERT_EXPR <in_loop_7, in_loop_7 != 0>;
simple_iv ();
;; succ: 7 [100.0%] (FALLTHRU,EXECUTABLE)
And later we have:
;; basic block 9, loop depth 0, count 0, freq 8476, maybe hot
;; prev block 8, next block 10, flags: (NEW, REACHABLE, VISITED)
;; pred: 7 [84.8%] (FALSE_VALUE,EXECUTABLE)
if (in_loop_7 == 0)
goto <bb 10>; [36.64%]
else
goto <bb 11>; [63.36%]
VRP knows it can replace the uses of in_loop_7 in the conditionals in
blocks 5 and 9 with iftmp.0_2 and happily does so *before* jump
threading (but well after ASSERT_EXPR insertion).
As a result VRP is unable to utilize the ASSERT_EXPRs in blocks 12 and 6
(which reference in_loop_7) to thread the jump at bb9 (which now
references iftmp.0_2).
The cases in pr78496 are slightly more complex, but boil down to the
same core issue -- simplifying the conditional too early.
Thankfully this is easy to fix. We just split the conditional
simplification into two steps so that the transformation noted above
occurs after jump threading (the other simplifications we want to occur
before jump threading).
This allows VRP1 to pick up 27 missed jump threads in the testcase from
78496. It could well be enough to address 78496, but since we don't
have a solid description of the desired end result I won't consider
78496 fixed quite yet as there's significant further improvements we can
make.
Bootstrapped and regression tested on x86_64-linux-gnu. Installing on
the trunk.
Jeff