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

Reply via email to