Hi!

The bb_uses and bb_defs bitmaps are never used if !*split_p, the comments
even describe why:
  /* For the new created basic block, there is no dataflow info at all.
     So skip the following dataflow update and check.  */
On the new bb in that case DF_LR_BB_INFO is NULL, so &(NULL->field) is
UB.
Fixed thusly, the NULL init added there just in case uninit can't figure it
out in some bootstrap mode.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-04-03  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/85167
        * shrink-wrap.c (move_insn_for_shrink_wrap): Don't set bb_uses and
        bb_defs if *split_p, instead preinitialize it to NULL.

        * gcc.dg/pr85167.c: New test.

--- gcc/shrink-wrap.c.jj        2018-02-10 00:21:18.284975396 +0100
+++ gcc/shrink-wrap.c   2018-04-03 13:06:54.183464995 +0200
@@ -157,7 +157,7 @@ move_insn_for_shrink_wrap (basic_block b
                           struct dead_debug_local *debug)
 {
   rtx set, src, dest;
-  bitmap live_out, live_in, bb_uses, bb_defs;
+  bitmap live_out, live_in, bb_uses = NULL, bb_defs = NULL;
   unsigned int i, dregno, end_dregno;
   unsigned int sregno = FIRST_PSEUDO_REGISTER;
   unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
@@ -330,8 +330,11 @@ move_insn_for_shrink_wrap (basic_block b
       /* Check whether BB uses DEST or clobbers DEST.  We need to add
         INSN to BB if so.  Either way, DEST is no longer live on entry,
         except for any part that overlaps SRC (next loop).  */
-      bb_uses = &DF_LR_BB_INFO (bb)->use;
-      bb_defs = &DF_LR_BB_INFO (bb)->def;
+      if (!*split_p)
+       {
+         bb_uses = &DF_LR_BB_INFO (bb)->use;
+         bb_defs = &DF_LR_BB_INFO (bb)->def;
+       }
       if (df_live)
        {
          for (i = dregno; i < end_dregno; i++)
--- gcc/testsuite/gcc.dg/pr85167.c.jj   2018-04-03 13:14:13.532523126 +0200
+++ gcc/testsuite/gcc.dg/pr85167.c      2018-04-03 13:08:36.883478590 +0200
@@ -0,0 +1,16 @@
+/* PR rtl-optimization/85167 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -w" } */
+
+struct A { long b; };
+int c, d, e;
+int bar (void);
+
+int
+foo (void)
+{
+  long g;
+  for (; g == c ? 0 : (e = 1); g = ((struct A *)g)->b)
+    if (bar ())
+      return d;
+}

        Jakub

Reply via email to