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
>

Reply via email to