The following avoids diagnosing bit sets/clears that involve RMW
cycles to uninitialized memory. This is for example exposed by
__builtin_clear_padding lowering which suppresses diagnostics but
those can re-surface with vectorization.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
OK?
Thanks,
Richard.
PR tree-optimization/110743
* tree-ssa-uninit.cc (maybe_warn_operand): Suppress diagnostics
on RMW cycles setting/clearing bits.
* gcc.dg/uninit-pr110743.c: New testcase.
---
gcc/testsuite/gcc.dg/uninit-pr110743.c | 22 ++++++++++++++++++++++
gcc/tree-ssa-uninit.cc | 24 ++++++++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/uninit-pr110743.c
diff --git a/gcc/testsuite/gcc.dg/uninit-pr110743.c
b/gcc/testsuite/gcc.dg/uninit-pr110743.c
new file mode 100644
index 00000000000..5a95f60cf9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr110743.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+void foo (int *);
+
+void bar()
+{
+ int x, tem;
+ tem = x; /* { dg-bogus "used uninitialized" } */
+ tem = tem | 5;
+ x = tem;
+ foo (&x);
+}
+
+void baz()
+{
+ int x, tem;
+ tem = x; /* { dg-bogus "used uninitialized" } */
+ tem = tem & 5;
+ x = tem;
+ foo (&x);
+}
diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc
index dbd187e21d7..107ed21e10b 100644
--- a/gcc/tree-ssa-uninit.cc
+++ b/gcc/tree-ssa-uninit.cc
@@ -758,6 +758,30 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs,
tree rhs,
if (is_empty_type (rhstype))
return NULL_TREE;
+ /* Avoid diagnosing read-modify-write cycles that in the end only
+ sets a subset of bits to zero or one.
+ ??? Note that further reads will then appear (partly) initialized
+ and will not be diagnosed. */
+ gimple *use_stmt;
+ if (gimple_assign_load_p (stmt)
+ && TREE_CODE (lhs) == SSA_NAME
+ && single_imm_use (lhs, &luse_p, &use_stmt))
+ {
+ gassign *use_ass = dyn_cast <gassign *> (use_stmt);
+ for (int i = 0; i < 2; ++i)
+ if (use_ass
+ && (gimple_assign_rhs_code (use_ass) == BIT_AND_EXPR
+ || gimple_assign_rhs_code (use_ass) == BIT_IOR_EXPR)
+ && single_imm_use (gimple_assign_lhs (use_ass), &luse_p,
+ &use_stmt))
+ use_ass = dyn_cast <gassign *> (use_stmt);
+ if (use_ass
+ && gimple_vdef (use_ass)
+ && operand_equal_p (gimple_assign_rhs1 (stmt),
+ gimple_assign_lhs (use_ass)))
+ return NULL_TREE;
+ }
+
bool warned = false;
/* We didn't find any may-defs so on all paths either
reached function entry or a killing clobber. */
--
2.51.0