https://gcc.gnu.org/g:6d842965024cad9f6d3588d300c11c2c2e4a2dba

commit r17-1765-g6d842965024cad9f6d3588d300c11c2c2e4a2dba
Author: Richard Biener <[email protected]>
Date:   Fri Jun 19 11:45:46 2026 +0200

    tree-optimization/110743 - do not warn for bit sets/clears to uninit memory
    
    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.
    
            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.

Diff:
---
 gcc/testsuite/gcc.dg/uninit-pr110743.c | 22 ++++++++++++++++++++++
 gcc/tree-ssa-uninit.cc                 | 24 ++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/uninit-pr110743.c 
b/gcc/testsuite/gcc.dg/uninit-pr110743.c
new file mode 100644
index 000000000000..5a95f60cf9b0
--- /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 dbd187e21d7a..107ed21e10b8 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.  */

Reply via email to