[Bug tree-optimization/70020] New: Forward propagation leaves compile-time computable conditional in IL

law at redhat dot com gcc-bugzilla@gcc.gnu.org
Tue Mar 1 05:20:00 GMT 2016


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70020

            Bug ID: 70020
           Summary: Forward propagation leaves compile-time computable
                    conditional in IL
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at redhat dot com
                CC: law at gcc dot gnu.org, law at redhat dot com, su at cs dot ucdavis.edu
        Depends on: 70005
  Target Milestone: ---

+++ This bug was initially created as a clone of Bug #70005 +++

Given this code originally from BZ70005

-------------------------------------------------------


unsigned char a = 6;
int b, c;

static void
fn1 ()
{
  int i = a > 1 ? 1 : a, j = 6 & (c = a && (b = a));
  int d = 0, e = a, f = ~c, g = b || a;
  unsigned char h = ~a;
  if (a)
    f = j;
  if (h && g)
    d = a;
  i = -~(f * d * h) + c && (e || i) ^ f;
  if (i != 1) 
    __builtin_abort (); 
}

int
main ()
{
  fn1 ();
  return 0; 
}


---

At -O2 on x86-64 we have the following in the .dse3 dump:

;;   basic block 6, loop depth 0, count 0, freq 7300, maybe hot
;;    prev block 5, next block 7, flags: (NEW, REACHABLE)
;;    pred:       8 [100.0%]  (FALLTHRU,EXECUTABLE)
;;                5 (TRUE_VALUE,EXECUTABLE)
  # iftmp.2_35 = PHI <1(8), 0(5)>
  # e_58 = PHI <_5(8), 0(5)>
  # iftmp.0_67 = PHI <1(8), 0(5)>
  _23 = iftmp.2_35 + 1;
  if (_23 != 0)
    goto <bb 7>;
  else
    goto <bb 10>;

Which forwprop turns into:

;;   basic block 6, loop depth 0, count 0, freq 7300, maybe hot
;;    prev block 5, next block 7, flags: (NEW, REACHABLE)
;;    pred:       8 [100.0%]  (FALLTHRU,EXECUTABLE)
;;                5 (TRUE_VALUE,EXECUTABLE)
  # iftmp.2_35 = PHI <1(8), 0(5)>
  # e_58 = PHI <_5(8), 0(5)>
  # iftmp.0_67 = PHI <1(8), 0(5)>
  if (iftmp.2_35 != -1)
    goto <bb 7>;
  else
    goto <bb 10>;


The condition is obviously the compile-time constant true.  

Walking backwards to vrp2 we have:

  # iftmp.2_35 = PHI <1(10), 0(12)>

[ ... ]
;;   basic block 8, loop depth 0, count 0, freq 7300, maybe hot
;;   Invalid sum of incoming frequencies 4999, should be 7300
;;    prev block 7, next block 9, flags: (NEW, REACHABLE)
;;    pred:       7 [100.0%]  (FALLTHRU,EXECUTABLE)
;;                6 [50.0%]  (TRUE_VALUE,EXECUTABLE)
  # d_17 = PHI <0(7), e_58(6)>
  # iftmp.2_56 = PHI <iftmp.2_35(7), iftmp.2_35(6)>
  # e_59 = PHI <e_58(7), e_58(6)>
  # f_61 = PHI <0(7), 0(6)>
  # h_65 = PHI <0(7), h_52(6)>
  # iftmp.0_68 = PHI <iftmp.0_67(7), iftmp.0_67(6)>
  _19 = d_17 * f_61;
  _20 = (int) h_65;
  _21 = _19 * _20;
  _22 = _21 + 1;
  _23 = _22 + iftmp.2_56;
  if (_23 != 0)
    goto <bb 9>;
  else
    goto <bb 13>;

Unfortunately VRP doesn't catch that f_61 is [0, 0].  Most likely because there
was another path through bb8 which was eliminated by jump threading (which is a
subroutine that runs after VRP is complete).  phicopyprop comes along and
simplifies that mess into:

  # iftmp.2_35 = PHI <1(10), 0(12)>
[ ... ]
;;   basic block 8, loop depth 0, count 0, freq 7300, maybe hot
;;   Invalid sum of incoming frequencies 4999, should be 7300
;;    prev block 7, next block 9, flags: (NEW, REACHABLE)
;;    pred:       7 [100.0%]  (FALLTHRU,EXECUTABLE)
;;                6 [50.0%]  (TRUE_VALUE,EXECUTABLE)
  # d_17 = PHI <0(7), e_58(6)>
  # h_65 = PHI <0(7), h_52(6)>
  _20 = (int) h_65;
  _23 = iftmp.2_35 + 1;
  if (_23 != 0)
    goto <bb 9>;
  else
    goto <bb 13>;


Which is probably the first place we might have a reasonable chance at catching
this.  But forwprop is probably a better place because it's working with:

;;   basic block 6, loop depth 0, count 0, freq 7300, maybe hot
;;    prev block 5, next block 7, flags: (NEW, REACHABLE)
;;    pred:       8 [100.0%]  (FALLTHRU,EXECUTABLE)
;;                5 (TRUE_VALUE,EXECUTABLE)
  # iftmp.2_35 = PHI <1(8), 0(5)>
  # e_58 = PHI <_5(8), 0(5)>
  # iftmp.0_67 = PHI <1(8), 0(5)>
  if (iftmp.2_35 != -1)
    goto <bb 7>;
  else
    goto <bb 10>;


Anyway this probably isn't terribly important, but I didn't want it to get
lost.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70005
[Bug 70005] [6 Regression] wrong code at -O2 and -O3 on x86_64-linux-gnu


More information about the Gcc-bugs mailing list