On Fri, Apr 4, 2025 at 3:37 PM Andrew Pinski <quic_apin...@quicinc.com> wrote:
>
> To help along cases where begin and end are passed on to another function
> and then uses std::distance on them. In the case of the testcases added,
> std::lexicographical_compare_three_way (for C++20). We now able to opimize
> `vector < known empty vector` to a constant where before we would need to load
> begin() and end() and do a comparison of them.
>
> Note for C++20+ at -O1 we still don't optimize it to a constant but that is
> due to not doing copy propagation for aggregates.
>
> Bootstrapped and tested on x86_64-linux-gnu.
>
>         PR libstdc++/111499
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/stl_vector.h (vector::begin(), vector::end(),
>         vector::cbegin(), vector::cend()):  Add __builtin_unreachable call to
>         announce that _M_finish is greater than or equal to _M_start.

Ignore this version of the patch, I submitted the wrong version of it.
the calls were supposed to be under `#ifdef __OPTIMIZE__` as suggested
in the bug report and that is what I tested too but I forgot to `git
commit --amend -a` on my git tree before submitting it.

Sorry about that,
Andrew

>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/tree-ssa/pr111499-1.C: New test.
>         * g++.dg/tree-ssa/pr111499.C: New test.
>
> Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
> ---
>  gcc/testsuite/g++.dg/tree-ssa/pr111499-1.C | 16 ++++++++++
>  gcc/testsuite/g++.dg/tree-ssa/pr111499.C   | 15 +++++++++
>  libstdc++-v3/include/bits/stl_vector.h     | 36 ++++++++++++++++++----
>  3 files changed, 61 insertions(+), 6 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr111499-1.C
>  create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr111499.C
>
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr111499-1.C 
> b/gcc/testsuite/g++.dg/tree-ssa/pr111499-1.C
> new file mode 100644
> index 00000000000..737f6673301
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/pr111499-1.C
> @@ -0,0 +1,16 @@
> +// { dg-do compile }
> +// { dg-options "-O1 -fdump-tree-optimized -Wextra -Wall" }
> +#include <vector>
> +
> +bool f(const std::vector<unsigned char> &v)
> +{
> +  std::vector<unsigned char> w;
> +  return v < w;
> +}
> +// This should compile to empty function; check that no size of
> +// vector is determined and there is no allocation
> +// For C++20+, at -O1 there is a missed optimization dealing with copy 
> propagation for aggregates
> +// { dg-final { scan-tree-dump-not "_M_start" "optimized" { xfail c++20 } } }
> +// { dg-final { scan-tree-dump-not "delete" "optimized" } }
> +// { dg-final { scan-tree-dump-not " = MEM" "optimized" } }
> +// { dg-final { scan-tree-dump "return 0" "optimized" { xfail c++20 } } }
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr111499.C 
> b/gcc/testsuite/g++.dg/tree-ssa/pr111499.C
> new file mode 100644
> index 00000000000..faa38299d4d
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/pr111499.C
> @@ -0,0 +1,15 @@
> +// { dg-do compile }
> +// { dg-options "-O2 -fdump-tree-optimized -Wextra -Wall" }
> +#include <vector>
> +
> +bool f(const std::vector<unsigned char> &v)
> +{
> +  std::vector<unsigned char> w;
> +  return v < w;
> +}
> +// This should compile to empty function; check that no size of
> +// vector is determined and there is no allocation
> +// { dg-final { scan-tree-dump-not "_M_start" "optimized" } }
> +// { dg-final { scan-tree-dump-not "delete" "optimized" } }
> +// { dg-final { scan-tree-dump-not " = MEM" "optimized" } }
> +// { dg-final { scan-tree-dump "return 0" "optimized" } }
> diff --git a/libstdc++-v3/include/bits/stl_vector.h 
> b/libstdc++-v3/include/bits/stl_vector.h
> index 458adc987da..aa72a5de709 100644
> --- a/libstdc++-v3/include/bits/stl_vector.h
> +++ b/libstdc++-v3/include/bits/stl_vector.h
> @@ -996,7 +996,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
>        iterator
>        begin() _GLIBCXX_NOEXCEPT
> -      { return iterator(this->_M_impl._M_start); }
> +      {
> +       if (this->_M_impl._M_start > this->_M_impl._M_finish)
> +         __builtin_unreachable();
> +       return iterator(this->_M_impl._M_start);
> +      }
>
>        /**
>         *  Returns a read-only (constant) iterator that points to the
> @@ -1006,7 +1010,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
>        const_iterator
>        begin() const _GLIBCXX_NOEXCEPT
> -      { return const_iterator(this->_M_impl._M_start); }
> +      {
> +       if (this->_M_impl._M_start > this->_M_impl._M_finish)
> +         __builtin_unreachable();
> +       return const_iterator(this->_M_impl._M_start);
> +      }
>
>        /**
>         *  Returns a read/write iterator that points one past the last
> @@ -1016,7 +1024,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
>        iterator
>        end() _GLIBCXX_NOEXCEPT
> -      { return iterator(this->_M_impl._M_finish); }
> +      {
> +       if (this->_M_impl._M_start > this->_M_impl._M_finish)
> +         __builtin_unreachable();
> +       return iterator(this->_M_impl._M_finish);
> +      }
>
>        /**
>         *  Returns a read-only (constant) iterator that points one past
> @@ -1026,7 +1038,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
>        const_iterator
>        end() const _GLIBCXX_NOEXCEPT
> -      { return const_iterator(this->_M_impl._M_finish); }
> +      {
> +       if (this->_M_impl._M_start > this->_M_impl._M_finish)
> +         __builtin_unreachable();
> +       return const_iterator(this->_M_impl._M_finish);
> +      }
>
>        /**
>         *  Returns a read/write reverse iterator that points to the
> @@ -1077,7 +1093,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
>        const_iterator
>        cbegin() const noexcept
> -      { return const_iterator(this->_M_impl._M_start); }
> +      {
> +       if (this->_M_impl._M_start > this->_M_impl._M_finish)
> +         __builtin_unreachable();
> +       return const_iterator(this->_M_impl._M_start);
> +      }
>
>        /**
>         *  Returns a read-only (constant) iterator that points one past
> @@ -1087,7 +1107,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
>        const_iterator
>        cend() const noexcept
> -      { return const_iterator(this->_M_impl._M_finish); }
> +      {
> +       if (this->_M_impl._M_start > this->_M_impl._M_finish)
> +         __builtin_unreachable();
> +       return const_iterator(this->_M_impl._M_finish);
> +      }
>
>        /**
>         *  Returns a read-only (constant) reverse iterator that points
> --
> 2.43.0
>

Reply via email to