Skip to content

Commit

Permalink
Automerge: [libc++] Add assumption for align of begin and end pointer…
Browse files Browse the repository at this point in the history
…s of vector. (#108961)

Missing information about begin and end pointers of std::vector can lead
to missed optimizations in LLVM.

This patch adds alignment assumptions at the point where the begin and
end pointers are loaded. If the pointers would not have the same
alignment, end might never get hit when incrementing begin.

See llvm/llvm-project#101372 for a discussion
of missed range check optimizations in hardened mode.

Once llvm/llvm-project#108958 lands, the created
`llvm.assume` calls for the alignment should be folded into the `load`
instructions, resulting in no extra instructions after InstCombine.

Co-authored-by: Louis Dionne <[email protected]>
  • Loading branch information
2 people authored and github-actions[bot] committed Jan 16, 2025
2 parents 9335ce6 + eac23a5 commit d10d236
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
13 changes: 6 additions & 7 deletions libcxx/include/__flat_map/key_value_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__ranges/access.h>
#include <__type_traits/conditional.h>
#include <__type_traits/maybe_const.h>
#include <__utility/move.h>
#include <__utility/pair.h>

Expand All @@ -41,9 +39,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Owner, class _KeyContainer, class _MappedContainer, bool _Const>
struct __key_value_iterator {
private:
using __key_iterator _LIBCPP_NODEBUG = ranges::iterator_t<const _KeyContainer>;
using __mapped_iterator _LIBCPP_NODEBUG = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>;
using __reference _LIBCPP_NODEBUG = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>;
using __key_iterator _LIBCPP_NODEBUG = typename _KeyContainer::const_iterator;
using __mapped_iterator _LIBCPP_NODEBUG =
_If<_Const, typename _MappedContainer::const_iterator, typename _MappedContainer::iterator>;
using __reference _LIBCPP_NODEBUG = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>;

struct __arrow_proxy {
__reference __ref_;
Expand Down Expand Up @@ -71,8 +70,8 @@ struct __key_value_iterator {
_LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default;

_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
requires _Const && convertible_to<ranges::iterator_t<_KeyContainer>, __key_iterator> &&
convertible_to<ranges::iterator_t<_MappedContainer>, __mapped_iterator>
requires _Const && convertible_to<typename _KeyContainer::iterator, __key_iterator> &&
convertible_to<typename _MappedContainer::iterator, __mapped_iterator>
: __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}

_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
Expand Down
24 changes: 20 additions & 4 deletions libcxx/include/__vector/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_pointer.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/type_identity.h>
Expand Down Expand Up @@ -341,13 +342,17 @@ class _LIBCPP_TEMPLATE_VIS vector {
//
// Iterators
//
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __make_iter(this->__begin_); }
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
return __make_iter(__add_alignment_assumption(this->__begin_));
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
return __make_iter(this->__begin_);
return __make_iter(__add_alignment_assumption(this->__begin_));
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
return __make_iter(__add_alignment_assumption(this->__end_));
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __make_iter(this->__end_); }
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
return __make_iter(this->__end_);
return __make_iter(__add_alignment_assumption(this->__end_));
}

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
Expand Down Expand Up @@ -775,6 +780,17 @@ class _LIBCPP_TEMPLATE_VIS vector {
}

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}

static _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __add_alignment_assumption(pointer __p) _NOEXCEPT {
#ifndef _LIBCPP_CXX03_LANG
if constexpr (is_pointer<pointer>::value) {
if (!__libcpp_is_constant_evaluated()) {
return static_cast<pointer>(__builtin_assume_aligned(__p, alignof(decltype(*__p))));
}
}
#endif
return __p;
}
};

#if _LIBCPP_STD_VER >= 17
Expand Down

0 comments on commit d10d236

Please sign in to comment.