On Fri, 19 Jun 2026, Andrea Pinski wrote: > On Fri, Jun 19, 2026 at 4:12 AM Richard Biener <[email protected]> wrote: > > > > 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; > > + } > > Hmm, is there a way to combine this with the BIT_INSERT_EXPR loop > since both are basically trying to prevent the same thing? It is > handled closer to the top of the function.
I considered that but while it is conceptually similar (RMW) it's structured differently enough to make the result less readable. Richard. > Thanks, > Andrea > > > + > > 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 > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
