On Mon, Oct 6, 2025 at 8:41 AM Andrew Pinski <[email protected]> wrote: > > SRA likes to create VCE<bool>(a) when it comes to bool. This confuses > a few different passes including jump threading and uninitialization > warning. This removes the VCE in one case where it will help and when it > is known not to have any undefined behavior since the ranges of a is known > to be 0/1. > > This implements similar was done for PR 80635 but without VRP's help; ccp > provides enough on the range/non-zeroness to implement this in match. > > This will fix many of the std::optional reported warnings at -O1 too. > pr80635-[34].C are the same as pr80635-[12].C but compiled at -O1 rather > than just -O2.
Ping? Yes this is different from https://gcc.gnu.org/pipermail/gcc-patches/2025-September/694386.html . The difference is the range check here would not cause any information to be lost as the range of the inner name is already known to be `[0,1]`. So it should be safer and more to what we want. Plus VRP already does this exact transformation (with the range info); that was added with r11-7383-g3cf52b87ff693. We should do it in match-and-simplify and not just VRP. After ccp, the range of the variable is already set to `[0,1]` so transforming afterwards is a good idea. Thanks, Andrew > > PR tree-optimization/105749 > PR tree-optimization/80635 > > gcc/ChangeLog: > > * match.pd (`VCE<bool>(zero_one_valued_p) ==\!= 0`): New pattern. > > gcc/testsuite/ChangeLog: > > * g++.dg/warn/pr80635-3.C: New test. > * g++.dg/warn/pr80635-4.C: New test. > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/match.pd | 11 +++++++ > gcc/testsuite/g++.dg/warn/pr80635-3.C | 46 +++++++++++++++++++++++++++ > gcc/testsuite/g++.dg/warn/pr80635-4.C | 31 ++++++++++++++++++ > 3 files changed, 88 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/warn/pr80635-3.C > create mode 100644 gcc/testsuite/g++.dg/warn/pr80635-4.C > > diff --git a/gcc/match.pd b/gcc/match.pd > index 10a2c5e72d6..8f575e0c5a0 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -2405,6 +2405,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > || TYPE_PRECISION (type) > 1) > && wi::leu_p (tree_nonzero_bits (@1), 1)))) > > +/* VCE<bool>(zero_one) ==/!= false -> zero_one ==/!= 0. > + This is done as SRA likes to create VCE for boolean accesses > + and it helps code gneration and uninitialized variable warnings. */ > +(for neeq (ne eq) > + (simplify > + (neeq (view_convert@0 zero_one_valued_p@1) integer_zerop) > + (if (TREE_CODE (TREE_TYPE (@0)) == BOOLEAN_TYPE > + && TYPE_PRECISION (TREE_TYPE (@0)) == 1 > + && TYPE_UNSIGNED (TREE_TYPE (@0))) > + (neeq @1 { build_zero_cst (TREE_TYPE (@1)); } )))) > + > /* Transform { 0 or 1 } * { 0 or 1 } into { 0 or 1 } & { 0 or 1 }. */ > (simplify > (mult zero_one_valued_p@0 zero_one_valued_p@1) > diff --git a/gcc/testsuite/g++.dg/warn/pr80635-3.C > b/gcc/testsuite/g++.dg/warn/pr80635-3.C > new file mode 100644 > index 00000000000..09fd6ee3392 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/pr80635-3.C > @@ -0,0 +1,46 @@ > +// PR tree-optimization/80635 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O1 -Wmaybe-uninitialized" } > + > +using size_t = decltype (sizeof (1)); > +inline void *operator new (size_t, void *p) { return p; } > +template<typename T> > +struct optional > +{ > + optional () : m_dummy (), live (false) {} > + void emplace () { new (&m_item) T (); live = true; } > + ~optional () { if (live) m_item.~T (); } > + > + union > + { > + struct {} m_dummy; > + T m_item; > + }; > + bool live; > +}; > + > +extern int get (); > +extern void set (int); > + > +struct A > +{ > + A () : m (get ()) {} > + ~A () { set (m); } // { dg-bogus "may be used uninitialized in this > function" } > + > + int m; > +}; > + > +struct B > +{ > + B (); > + ~B (); > +}; > + > +void func () > +{ > + optional<A> maybe_a; > + optional<B> maybe_b; > + > + maybe_a.emplace (); > + maybe_b.emplace (); > +} > diff --git a/gcc/testsuite/g++.dg/warn/pr80635-4.C > b/gcc/testsuite/g++.dg/warn/pr80635-4.C > new file mode 100644 > index 00000000000..7b3bf8876e0 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/pr80635-4.C > @@ -0,0 +1,31 @@ > +// PR tree-optimization/80635 > +// { dg-do compile { target c++17 } } > +// { dg-options "-O1 -Wmaybe-uninitialized" } > + > +#include <optional> > + > +extern int get (); > +extern void set (int); > + > +struct A > +{ > + A () : m (get ()) {} > + ~A () { set (m); } // { dg-bogus "may be used uninitialized in this > function" } > + > + int m; > +}; > + > +struct B > +{ > + B (); > + ~B (); > +}; > + > +void func () > +{ > + std::optional<A> maybe_a; > + std::optional<B> maybe_b; > + > + maybe_a.emplace (); > + maybe_b.emplace (); > +} > -- > 2.43.0 >
