Skip to content

Commit eac23a5

Browse files
fhahnldionne
andauthored
[libc++] Add assumption for align of begin and end pointers 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 #101372 for a discussion of missed range check optimizations in hardened mode. Once #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]>
1 parent c281b12 commit eac23a5

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

libcxx/include/__flat_map/key_value_iterator.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
#include <__config>
1616
#include <__iterator/iterator_traits.h>
1717
#include <__memory/addressof.h>
18-
#include <__ranges/access.h>
1918
#include <__type_traits/conditional.h>
20-
#include <__type_traits/maybe_const.h>
2119
#include <__utility/move.h>
2220
#include <__utility/pair.h>
2321

@@ -41,9 +39,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4139
template <class _Owner, class _KeyContainer, class _MappedContainer, bool _Const>
4240
struct __key_value_iterator {
4341
private:
44-
using __key_iterator _LIBCPP_NODEBUG = ranges::iterator_t<const _KeyContainer>;
45-
using __mapped_iterator _LIBCPP_NODEBUG = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>;
46-
using __reference _LIBCPP_NODEBUG = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>;
42+
using __key_iterator _LIBCPP_NODEBUG = typename _KeyContainer::const_iterator;
43+
using __mapped_iterator _LIBCPP_NODEBUG =
44+
_If<_Const, typename _MappedContainer::const_iterator, typename _MappedContainer::iterator>;
45+
using __reference _LIBCPP_NODEBUG = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>;
4746

4847
struct __arrow_proxy {
4948
__reference __ref_;
@@ -71,8 +70,8 @@ struct __key_value_iterator {
7170
_LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default;
7271

7372
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
74-
requires _Const && convertible_to<ranges::iterator_t<_KeyContainer>, __key_iterator> &&
75-
convertible_to<ranges::iterator_t<_MappedContainer>, __mapped_iterator>
73+
requires _Const && convertible_to<typename _KeyContainer::iterator, __key_iterator> &&
74+
convertible_to<typename _MappedContainer::iterator, __mapped_iterator>
7675
: __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
7776

7877
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)

libcxx/include/__vector/vector.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <__type_traits/is_constructible.h>
5252
#include <__type_traits/is_nothrow_assignable.h>
5353
#include <__type_traits/is_nothrow_constructible.h>
54+
#include <__type_traits/is_pointer.h>
5455
#include <__type_traits/is_same.h>
5556
#include <__type_traits/is_trivially_relocatable.h>
5657
#include <__type_traits/type_identity.h>
@@ -341,13 +342,17 @@ class _LIBCPP_TEMPLATE_VIS vector {
341342
//
342343
// Iterators
343344
//
344-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __make_iter(this->__begin_); }
345+
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
346+
return __make_iter(__add_alignment_assumption(this->__begin_));
347+
}
345348
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
346-
return __make_iter(this->__begin_);
349+
return __make_iter(__add_alignment_assumption(this->__begin_));
350+
}
351+
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
352+
return __make_iter(__add_alignment_assumption(this->__end_));
347353
}
348-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __make_iter(this->__end_); }
349354
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
350-
return __make_iter(this->__end_);
355+
return __make_iter(__add_alignment_assumption(this->__end_));
351356
}
352357

353358
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
@@ -775,6 +780,17 @@ class _LIBCPP_TEMPLATE_VIS vector {
775780
}
776781

777782
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}
783+
784+
static _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __add_alignment_assumption(pointer __p) _NOEXCEPT {
785+
#ifndef _LIBCPP_CXX03_LANG
786+
if constexpr (is_pointer<pointer>::value) {
787+
if (!__libcpp_is_constant_evaluated()) {
788+
return static_cast<pointer>(__builtin_assume_aligned(__p, alignof(decltype(*__p))));
789+
}
790+
}
791+
#endif
792+
return __p;
793+
}
778794
};
779795

780796
#if _LIBCPP_STD_VER >= 17

0 commit comments

Comments
 (0)