The following replaces the simplistic gimple_uses_undefined_value_p
with the conservative mark_ssa_maybe_undefs approach as already
used by LIM and IVOPTs.  This is to avoid exposing an unconditional
uninitialized read on a path from entry by if-combine.

Boostrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/110228
        * tree-ssa-ifcombine.cc (pass_tree_ifcombine::execute):
        Mark SSA may-undefs.
        (bb_no_side_effects_p): Check stmt uses for undefs.

        * gcc.dg/torture/pr110228.c: New testcase.
        * gcc.dg/uninit-pr101912.c: Un-XFAIL.
---
 gcc/testsuite/gcc.dg/torture/pr110228.c | 34 +++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/uninit-pr101912.c  |  2 +-
 gcc/tree-ssa-ifcombine.cc               |  8 +++++-
 3 files changed, 42 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr110228.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr110228.c 
b/gcc/testsuite/gcc.dg/torture/pr110228.c
new file mode 100644
index 00000000000..add9f17b421
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110228.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target x86_64-*-* i?86-*-* } } */
+/* { dg-require-effective-target lp64 } */
+
+unsigned a[4] = {1,1,1,1};
+unsigned tt1 = 0;
+
+__attribute__((noipa))
+static void bug(unsigned * p, unsigned *t, int n, int t2)
+{
+  for(int i = 0; i < n; i++)
+    {
+      _Bool LookupFlags ;
+      unsigned v = t[i];
+      unsigned tt = tt1;
+      if (v == 0)
+       LookupFlags = 0;
+      else if (v == 1)
+       LookupFlags = 1;
+      if (LookupFlags) {
+         tt|=3u;
+         LookupFlags = 0;
+      }
+      asm("movq $-1, %q1":"+a"(LookupFlags));
+      *p = tt;
+    }
+}
+
+int main()
+{
+  unsigned r = 42;
+  bug(&r,a, sizeof(a)/sizeof(a[0]), 1);
+  __builtin_printf("%u\n", r);
+  if (r != 3) __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.dg/uninit-pr101912.c 
b/gcc/testsuite/gcc.dg/uninit-pr101912.c
index 62cd2a0c73e..cb7d7516e91 100644
--- a/gcc/testsuite/gcc.dg/uninit-pr101912.c
+++ b/gcc/testsuite/gcc.dg/uninit-pr101912.c
@@ -11,7 +11,7 @@ tzloadbody (void)
   for (int i = 0; i < n; i++)
     {
       int corr = getint ();
-      if (corr < 1 || (corr == 1 && !(leapcnt == 0 || (prevcorr < corr ? corr 
== prevcorr + 1 : (corr == prevcorr || corr == prevcorr - 1))))) /* { dg-bogus 
"uninitialized" "pr101912" { xfail *-*-* } } */
+      if (corr < 1 || (corr == 1 && !(leapcnt == 0 || (prevcorr < corr ? corr 
== prevcorr + 1 : (corr == prevcorr || corr == prevcorr - 1))))) /* { dg-bogus 
"uninitialized" "pr101912" } */
        return -1;
 
       prevcorr = corr;
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 21a77ddecc7..58e19c1508e 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -128,7 +128,6 @@ bb_no_side_effects_p (basic_block bb)
       gassign *ass;
       enum tree_code rhs_code;
       if (gimple_has_side_effects (stmt)
-         || gimple_uses_undefined_value_p (stmt)
          || gimple_could_trap_p (stmt)
          || gimple_vuse (stmt)
          /* We need to rewrite stmts with undefined overflow to use
@@ -153,6 +152,12 @@ bb_no_side_effects_p (basic_block bb)
             should handle this.  */
          || is_gimple_call (stmt))
        return false;
+
+      ssa_op_iter it;
+      tree use;
+      FOR_EACH_SSA_TREE_OPERAND (use, stmt, it, SSA_OP_USE)
+       if (ssa_name_maybe_undef_p (use))
+         return false;
     }
 
   return true;
@@ -836,6 +841,7 @@ pass_tree_ifcombine::execute (function *fun)
 
   bbs = single_pred_before_succ_order ();
   calculate_dominance_info (CDI_DOMINATORS);
+  mark_ssa_maybe_undefs ();
 
   /* Search every basic block for COND_EXPR we may be able to optimize.
 
-- 
2.35.3

Reply via email to