In response to PR87105 I dusted off an old patch that adds an early
phiopt pass.  Recognizing we run phiopt twice with not many passes
in between early in post-IPA optimizations this patch moves the
first of said to the early pipeline.

The main motivation is to do things like MIN/MAX_EXPR early to
avoid jump threading mess up the CFG (the case with PR87105).
I realize theres early backward threading before the new early
phiopt pass but that doesn't seem to do anything useful there (yet).
I think it makes sense to push that later anyways.

Now, early phiopt is quite confused about predict stmts still
being present and turning conditional BBs into diamonds which it
cannot handle.  I've fixed at least stray such stmts in the BBs
that are interesting.  Note this may hide fallout which would otherwise
be visible in the testsuite (there's no flag to avoid
generating the predictors - they are emitted directly by the frontends,
maybe we could drop them with -fno[-guess]-branch-probabilities at
gimplification time?).

There's also an effect on ifcombine which, when preceeded by phiopt,
can miss cases because phiopt may value-replace some condition.

The patch contains adjustments to testcases where there's no harm done
in the end and leaves those FAILing where we would need to do sth.

In the end it's regular pass-ordering issues but our testsuite very
often ties our hands when re-ordering passes because of them.

One option would be to distinguish early from late phiopt and for
example avoid value-replacement - like just do MIN/MAX recognition
for the vectorizer.

Any comments?

Some detailed notes on the remaining FAILs below.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

>From e4f06ed39d12e7c17ff57aa17f17f54013d7869f Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguent...@suse.de>
Date: Tue, 28 Aug 2018 12:53:53 +0200
Subject: [PATCH] early-phiopt

FAIL: g++.dg/predict-loop-exit-2.C -std=gnu++98  scan-tree-dump-times profile_es
timate "loop exit heuristics:" 2

phiopt value-replaces the last "exit" test in

  <bb 4>:
  _5 = foo ();
  if (_5 != 0)
    goto <bb 7>;
  else
    goto <bb 5>;

  <bb 5>:
  g.0_7 = g;
  if (g.0_7 <= 9)
    goto <bb 7>;
  else
    goto <bb 6>;

  <bb 6>:

  <bb 7>:
  # iftmp.3_1 = PHI <1(5), 0(6), 1(4)>
  if (iftmp.3_1 != 0)
    goto <bb 3>;
  else
    goto <bb 8>;

  <bb 8>:
  return;

to look like

  <bb 5>:
  g.0_7 = g;
  _6 = g.0_7 <= 9;

  <bb 6>:
  # iftmp.3_1 = PHI <_6(5), 1(4)>
  if (iftmp.3_1 != 0)
    goto <bb 3>;

which confuses whatever the testcase was supposed to check (there is only
one loop exit).

FAIL: gcc.dg/tree-ssa/ssa-pre-32.c scan-tree-dump pre "# prephitmp_[0-9]+ = PHI 
<[xy]_[0-9]+\\\\(D\\\\)[^,]*, [xy]_[0-9]+\\\\(D\\\\)"

phiopt optimizes

   <bb 2> :
   if (b_5(D) != 0)
     goto <bb 4>; [INV]
   else
     goto <bb 3>; [INV]

   <bb 3> :

   <bb 4> :
   # iftmp.0_3 = PHI <4294967295(2), 0(3)>
   _1 = iftmp.0_3 & x_8(D);

to

   _9 = (unsigned int) b_5(D);
   _14 = -_9;
   _1 = x_8(D) & _14;

but in the sequence with two same conditions but opposite bits
nothing optimizes this further back to b_5(D) ? x_6(D) : y_7(D).

FAIL: gcc.dg/tree-ssa/ssa-ifcombine-7.c scan-tree-dump ifcombine " > "
FAIL: gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c scan-tree-dump optimized "&"
FAIL: gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c scan-tree-dump optimized "&"
FAIL: gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c scan-tree-dump-times optimized "&" 
2
  \|" 2

early phiopt value-replaces the inner condition which leaves ifcombine
with no work.

2018-08-28  Richard Biener  <rguent...@suse.de>

        * passes.def (pass_all_early_optimizations): Add phi-opt
        after dce.
        (pass_all_optimizations): Remove first phi-opt pass.
        * tree-ssa-phiopt.c (value_replacement): Ignore NOPs and predicts in
        addition to debug stmts.
        * tree-cfg.c (gimple_empty_block_p): Likewise.

        * g++.dg/tree-ssa/pr21463.C: Scan phiopt2 because this testcase
        relies on phiprop run before.
        * g++.dg/tree-ssa/pr30738.C: Likewise.
        * g++.dg/tree-ssa/pr57380.C: Likewise.
        * gcc.dg/tree-ssa/pr84859.c: Likewise.
        * gcc.dg/tree-ssa/vrp33.c: Disable phiopt.
        * gcc.dg/tree-ssa/pr68198.c: Likewise.
        * gcc.dg/tree-ssa/pr20701.c: Likewise.
        * gcc.dg/tree-ssa/pr21001.c: Likewise.
        * gcc.dg/tree-ssa/pr21563.c: Likewise.
        * gcc.dg/tree-ssa/pr37508.c: Likewise.
        * gcc.dg/tree-ssa/vrp19.c: Likewise.
        * gcc.dg/tree-ssa/vrp20.c: Likewise.
        * gcc.dg/tree-ssa/pr45397.c: Scan phiopt2 because phiopt1 is
        confused by copies in the IL left by EVRP.
        * gcc.dg/tree-ssa/phi-opt-12.c: Likewise, this time confused
        by predictors.
        * gcc.dg/tree-ssa/phi-opt-5.c: Likewise.
        * gcc.dg/pr24564.c: Likewise.
        * gcc.dg/uninit-15.c: Switch to testing other OK alternative.

diff --git a/gcc/passes.def b/gcc/passes.def
index 7f4b3479a35..401d1307125 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -88,6 +88,7 @@ along with GCC; see the file COPYING3.  If not see
          NEXT_PASS (pass_merge_phi);
           NEXT_PASS (pass_dse);
          NEXT_PASS (pass_cd_dce);
+         NEXT_PASS (pass_phiopt);
          NEXT_PASS (pass_early_ipa_sra);
          NEXT_PASS (pass_tail_recursion);
          NEXT_PASS (pass_convert_switch);
@@ -208,7 +209,6 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_copy_prop);
       NEXT_PASS (pass_tree_ifcombine);
       NEXT_PASS (pass_merge_phi);
-      NEXT_PASS (pass_phiopt);
       NEXT_PASS (pass_tail_recursion);
       NEXT_PASS (pass_ch);
       NEXT_PASS (pass_lower_complex);
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr21463.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr21463.C
index 0aed8482e6f..45d83415648 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr21463.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr21463.C
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-phiopt1" } */
+/* { dg-options "-O -fdump-tree-phiopt2" } */
 
 template<class T> static inline const T &ref_max(const T &a, const T &b)
 { return a<b ? b : a; }
@@ -15,5 +15,5 @@ template<class T> struct foo_t {
 
 template struct foo_t<int>;
 
-/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "phiopt1" } } */
-/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt2" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr30738.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr30738.C
index 84cfdd98cc1..1c989bde741 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr30738.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr30738.C
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-phiopt1" } */
+/* { dg-options "-O -fdump-tree-phiopt2" } */
 
 template <class T>
 static inline const T&
@@ -13,4 +13,4 @@ int test_min_ref (int x, int y)
   return min_ref (x, y);
 }
 
-/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt1" } } */
+/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt2" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr57380.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr57380.C
index fce6279eeb5..864129bfa69 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr57380.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr57380.C
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-phiopt1" } */
+/* { dg-options "-O2 -fdump-tree-phiopt2" } */
 /* { dg-add-options bind_pic_locally } */
 
 struct my_array {
@@ -18,4 +18,4 @@ int f(my_array a, my_array b) {
     return res;
 }
 
-/* { dg-final { scan-tree-dump "MAX_EXPR" "phiopt1" } } */
+/* { dg-final { scan-tree-dump "MAX_EXPR" "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/pr24574.c b/gcc/testsuite/gcc.dg/pr24574.c
index db0d8692a76..1e7bc7ac347 100644
--- a/gcc/testsuite/gcc.dg/pr24574.c
+++ b/gcc/testsuite/gcc.dg/pr24574.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-phiopt1" } */
+/* { dg-options "-O -fdump-tree-phiopt" } */
 
 int f0(int i)
 {
@@ -32,5 +32,7 @@ int f5(int i)
 }
 
 /* We should if-convert all functions to carry out the operation
-   unconditionally.  */
-/* { dg-final { scan-tree-dump-not "= PHI" "phiopt1" } } */
+   unconditionally.  phiopt1 is confused by some early return predictors.  */
+/* { dg-final { scan-tree-dump-not "= PHI" "phiopt1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "= PHI" 3 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "= PHI" "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-12.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-12.c
index f00d0fcc474..a5f76a2298f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-12.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-12.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-phiopt1" } */
+/* { dg-options "-O -fdump-tree-phiopt" } */
 
 int f(int a, int b, int c) {
   if (c > 5) return c;
@@ -19,4 +19,8 @@ unsigned m(unsigned a, unsigned b) {
     return a & b;
 }
 
-/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt1" } } */
+/* PREDICT_EXPRs cause some conditions to become diamonds which phiopt
+   doesn't handle.  */
+/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "goto" 9 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-5.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-5.c
index 31c0fc1f2fb..5a00f3ddf8c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-5.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -ffinite-math-only -fno-signed-zeros -fdump-tree-phiopt1" 
} */
+/* { dg-options "-O1 -ffinite-math-only -fno-signed-zeros -fdump-tree-phiopt" 
} */
 
 float repl1 (float varx)
 {
@@ -16,8 +16,11 @@ float repl1 (float varx)
    varx_4 = MIN_EXPR <1.0e+0, varx_2>;
    varx_5 = MAX_EXPR <varx_4, 0.0>;  */  
 
-/* { dg-final { scan-tree-dump "varx.*MIN_EXPR.*1\\.0" "phiopt1"} } */
-/* { dg-final { scan-tree-dump "varx.*MAX_EXPR.*0\\.0" "phiopt1"} } */
+/* phiopt1 confused by predictors.  */
+/* { dg-final { scan-tree-dump "varx.*MIN_EXPR.*1\\.0" "phiopt1" { xfail *-*-* 
} } } */
+/* { dg-final { scan-tree-dump "varx.*MAX_EXPR.*0\\.0" "phiopt1" { xfail *-*-* 
} } } */
+/* { dg-final { scan-tree-dump "varx.*MIN_EXPR.*1\\.0" "phiopt2"} } */
+/* { dg-final { scan-tree-dump "varx.*MAX_EXPR.*0\\.0" "phiopt2"} } */
 
 float repl2 (float vary)
 {
@@ -34,8 +37,11 @@ float repl2 (float vary)
    vary_4 = MAX_EXPR <0.0, vary_2>;
    vary_5 = MIN_EXPR <vary_4, 1.0e+0>;  */
 
-/* { dg-final { scan-tree-dump "vary.*MAX_EXPR.*0\\.0" "phiopt1"} } */
-/* { dg-final { scan-tree-dump "vary.*MIN_EXPR.*1\\.0" "phiopt1"} } */
+/* phiopt1 confused by predictors.  */
+/* { dg-final { scan-tree-dump "vary.*MAX_EXPR.*0\\.0" "phiopt1" { xfail *-*-* 
} } } */
+/* { dg-final { scan-tree-dump "vary.*MIN_EXPR.*1\\.0" "phiopt1" { xfail *-*-* 
} } } */
+/* { dg-final { scan-tree-dump "vary.*MAX_EXPR.*0\\.0" "phiopt2"} } */
+/* { dg-final { scan-tree-dump "vary.*MIN_EXPR.*1\\.0" "phiopt2"} } */
 
 float repl3 (float varz, float vara, float varb)
 {
@@ -54,5 +60,7 @@ float repl3 (float varz, float vara, float varb)
 <L1>:;
   vara_6 = MAX_EXPR <varb_5, varz_2>;  */
 
-/* { dg-final { scan-tree-dump "if .*varz" "phiopt1"} } */
-/* { dg-final { scan-tree-dump "vara.*MAX_EXPR" "phiopt1"} } */
+/* phiopt1 confused by predictors.  */
+/* { dg-final { scan-tree-dump "vara.*MAX_EXPR" "phiopt1" { xfail *-*-* } } } 
*/
+/* { dg-final { scan-tree-dump "if .*varz" "phiopt2"} } */
+/* { dg-final { scan-tree-dump "vara.*MAX_EXPR" "phiopt2"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
index 2f914589e32..ddbda4d3ea3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining 
-fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fno-ssa-phiopt 
-fdelete-null-pointer-checks" } */
 
 typedef struct {
   int code;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c
index 719360a015f..5dadf0949df 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c
@@ -5,7 +5,7 @@
    range information out of the conditional.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-dominator-opts -fno-tree-fre 
-fdisable-tree-evrp -fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fno-tree-fre -fno-ssa-phiopt 
-fdisable-tree-evrp -fdump-tree-vrp1-details" } */
 
 int
 foo (int a)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c
index 9c67a3acb46..80c13945738 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c
@@ -2,7 +2,7 @@
    Make sure VRP folds the second "if" statement.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp 
-fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp 
-fdump-tree-vrp1-details -fno-ssa-phiopt" } */
 
 int
 foo (int a)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr37508.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr37508.c
index 2ba09afe481..c2ebe6d1645 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr37508.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr37508.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1" } */
+/* { dg-options "-O2 -fno-tree-fre -fno-ssa-phiopt -fdump-tree-vrp1" } */
 
 struct foo1 {
   int i:1;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr45397.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr45397.c
index af75a75b1e2..8eacb518777 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr45397.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr45397.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-phiopt1 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-phiopt -fdump-tree-evrp" } */
 
 int foo_add (const unsigned char *tmp, int i, int val)
 {
@@ -18,7 +18,12 @@ int foo_mul (const unsigned char *tmp, int i, int val)
 
 /* All cases should end up using min/max for the saturated operations and
    have no control flow.  */
+/* EVRP leaves copies in the IL which confuses phiopt1 so we have
+   to rely on phiopt2 instead.  */
 /* { dg-final { scan-tree-dump-not " & 255;" "evrp" } } */
-/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt1" } } */
-/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt1" } } */
-/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt1" { xfail *-*-* } } 
} */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt1" { xfail *-*-* } } 
} */
+/* { dg-final { scan-tree-dump-not "if " "phiopt1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "if " "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
index 59d562e156c..475a7106358 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-details -fdisable-tree-ethread" } */
+/* { dg-options "-O2 -fdump-tree-thread1-details -fdisable-tree-ethread 
-fno-ssa-phiopt" } */
 
 extern void abort (void);
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c
index 577b561545d..a2c98866e6c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -Warray-bounds -fdump-tree-phiopt1" } */
+/* { dg-options "-O2 -Warray-bounds -fdump-tree-phiopt2" } */
 
 void
 h (const void *p, unsigned n)
@@ -19,4 +19,4 @@ h (const void *p, unsigned n)
     }
 }
 
-/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt1" } } */
+/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c
index 40373fde163..fbc6ef72bf7 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fwrapv -O1 -ftree-vrp -fdisable-tree-evrp -fdump-tree-vrp1" 
} */
+/* { dg-options "-fwrapv -O1 -ftree-vrp -fdisable-tree-evrp -fno-ssa-phiopt 
-fdump-tree-vrp1" } */
 
 #include <limits.h>
 extern void abort ();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c
index 4a3b0d73648..5827eae2d86 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fwrapv -O1 -fno-tree-fre -fdisable-tree-evrp -ftree-vrp 
-fdump-tree-vrp1" } */
+/* { dg-options "-fwrapv -O1 -fno-tree-fre -fno-ssa-phiopt -fdisable-tree-evrp 
-ftree-vrp -fdump-tree-vrp1" } */
 
 extern void abort ();
 extern void exit (int);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
index 75fefa49925..1eb12e559bc 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fno-ssa-phiopt -fno-tree-fre" } */
 
 /* This is from PR14052.  */
 
diff --git a/gcc/testsuite/gcc.dg/uninit-15.c b/gcc/testsuite/gcc.dg/uninit-15.c
index 6154f4b638a..abaa3ef3ec3 100644
--- a/gcc/testsuite/gcc.dg/uninit-15.c
+++ b/gcc/testsuite/gcc.dg/uninit-15.c
@@ -1,16 +1,16 @@
 /* PR tree-optimization/17506
    We issue an uninitialized variable warning at a wrong location at
    line 11, which is very confusing.  Make sure we print out a note to
-   make it less confusing.  (not xfailed alternative)
+   make it less confusing.  (xfailed alternative)
    But it is of course ok if we warn in bar about uninitialized use
-   of j.  (xfailed alternative)  */
+   of j.  (not xfailed alternative)  */
 /* { dg-do compile } */
 /* { dg-options "-O1 -Wuninitialized" } */
 
 inline int
 foo (int i)
 {
-  if (i) /* { dg-warning "used uninitialized in this function" } */
+  if (i) /* { dg-warning "used uninitialized in this function" "" { xfail 
*-*-* } } */
     return 1;
   return 0;
 }
@@ -20,7 +20,7 @@ void baz (void);
 void
 bar (void)
 {
-  int j; /* { dg-message "note: 'j' was declared here" } */
-  for (; foo (j); ++j)  /* { dg-warning "'j' is used uninitialized" "" { xfail 
*-*-* } } */
+  int j; /* { dg-message "note: 'j' was declared here" "" { xfail *-*-* } } */
+  for (; foo (j); ++j)  /* { dg-warning "'j' is used uninitialized" "" } */
     baz ();
 }
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index cf12cb1f391..938ad7d9a44 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6106,11 +6106,19 @@ gimple_empty_block_p (basic_block bb)
   gimple_stmt_iterator gsi = gsi_after_labels (bb);
   if (phi_nodes (bb))
     return false;
-  if (gsi_end_p (gsi))
-    return true;
-  if (is_gimple_debug (gsi_stmt (gsi)))
-    gsi_next_nondebug (&gsi);
-  return gsi_end_p (gsi);
+  while (!gsi_end_p (gsi))
+    {
+      gimple *stmt = gsi_stmt (gsi);
+      if (is_gimple_debug (stmt))
+       ;
+      else if (gimple_code (stmt) == GIMPLE_NOP
+              || gimple_code (stmt) == GIMPLE_PREDICT)
+       ;
+      else
+       return false;
+      gsi_next (&gsi);
+    }
+  return true;
 }
 
 
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 1667bad873b..bbefc21dc13 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -913,7 +913,9 @@ value_replacement (basic_block cond_bb, basic_block 
middle_bb,
       gsi_next_nondebug (&gsi);
       if (!is_gimple_assign (stmt))
        {
-         emtpy_or_with_defined_p = false;
+         if (gimple_code (stmt) != GIMPLE_PREDICT
+             && gimple_code (stmt) != GIMPLE_NOP)
+           emtpy_or_with_defined_p = false;
          continue;
        }
       /* Now try to adjust arg0 or arg1 according to the computation

Reply via email to