https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68991
--- Comment #8 from H.J. Lu <hjl.tools at gmail dot com> --- Another testcase: [hjl@gnu-tools-1 pr68991]$ cat add.cc typedef unsigned int size_type; #define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_INT__) #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \ ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1)) namespace std { template<size_type _Nw> struct _Base_bitset { typedef unsigned int _WordT; _WordT _M_w[_Nw]; _WordT& _M_hiword() { return _M_w[_Nw - 1]; } void _M_do_and(const _Base_bitset<_Nw>& __x) { for (size_type __i = 0; __i < _Nw; __i++) _M_w[__i] += __x._M_w[__i]; } void _M_do_flip() { for (size_type __i = 0; __i < _Nw; __i++) _M_w[__i] = ~_M_w[__i]; } bool _M_is_equal(const _Base_bitset<_Nw>& __x) const { for (size_type __i = 0; __i < _Nw; ++__i) if (_M_w[__i] != __x._M_w[__i]) return false; return true; } bool _M_is_any() const { for (size_type __i = 0; __i < _Nw; __i++) if (_M_w[__i] != static_cast<_WordT>(0)) return true; return false; } }; template<size_type _Extrabits> struct _Sanitize { typedef unsigned int _WordT; static void _S_do_sanitize(_WordT& __val) { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); } }; template<size_type _Nb> class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { private: typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; typedef unsigned int _WordT; void _M_do_sanitize() { typedef _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD> __sanitize_type; __sanitize_type::_S_do_sanitize(this->_M_hiword()); } public: class reference { friend class bitset; _WordT* _M_wp; size_type _M_bpos; public: reference& flip() { *_M_wp ^= _Base::_S_maskbit(_M_bpos); return *this; } }; bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) { this->_M_do_and(__rhs); return *this; } bitset<_Nb>& flip() { this->_M_do_flip(); this->_M_do_sanitize(); return *this; } bitset<_Nb> operator~() const { return bitset<_Nb>(*this).flip(); } bool operator==(const bitset<_Nb>& __rhs) const { return this->_M_is_equal(__rhs); } bool any() const { return this->_M_is_any(); } }; template<size_type _Nb> inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { bitset<_Nb> __result(__x); __result &= __y; return __result; } } template<typename T> class ArrayRef { public: typedef const T *iterator; private: const T *Data; size_type Length; public: iterator begin() const { return Data; } iterator end() const { return Data + Length; } }; const unsigned MAX_SUBTARGET_FEATURES = 128; class FeatureBitset : public std::bitset<MAX_SUBTARGET_FEATURES> { }; struct SubtargetFeatureKV { FeatureBitset Value; FeatureBitset Implies; }; struct SubtargetInfoKV { const void *Value; }; class SubtargetFeatures { public: FeatureBitset ToggleFeature(FeatureBitset Bits, const SubtargetFeatureKV *, ArrayRef<SubtargetFeatureKV> FeatureTable); }; static void ClearImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV *FeatureEntry, ArrayRef<SubtargetFeatureKV> FeatureTable) { for (auto &FE : FeatureTable) { if ((FE.Implies & FeatureEntry->Value).any()) { Bits &= ~FE.Value; ClearImpliedBits(Bits, &FE, FeatureTable); } } } FeatureBitset SubtargetFeatures::ToggleFeature(FeatureBitset Bits, const SubtargetFeatureKV *FeatureEntry, ArrayRef<SubtargetFeatureKV> FeatureTable) { if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) { Bits &= ~FeatureEntry->Value; ClearImpliedBits(Bits, FeatureEntry, FeatureTable); } return Bits; } [hjl@gnu-tools-1 pr68991]$ /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -m64 -O3 -fno-exceptions -fno-rtti -da -S -o add.s add.cc [hjl@gnu-tools-1 pr68991]$ LRA turns (insn 17 15 109 2 (set (reg:V4SI 122 [ vect__19.94 ]) (plus:V4SI (mem/c:V4SI (plus:DI (reg/f:DI 20 frame) (const_int -32 [0xffffffffffffffe0])) [6 MEM[(const struct bitset &)&Bits]+0 S16 A32]) (subreg:V4SI (reg:V16QI 121) 0))) add.cc:24 2960 {*addv4si3} (expr_list:REG_DEAD (reg:V16QI 121) (expr_list:REG_EQUIV (mem/c:V4SI (plus:DI (reg/f:DI 20 frame) (const_int -16 [0xfffffffffffffff0])) [3 MEM[(unsigned int *)&__result]+0 S16 A128]) (nil)))) into (insn 17 15 109 2 (set (reg:V4SI 21 xmm0 [orig:122 vect__19.94 ] [122]) (plus:V4SI (reg:V4SI 21 xmm0 [121]) (mem/c:V4SI (reg/f:DI 7 sp) [6 MEM[(const struct bitset &)&Bits]+0 S16 A32]))) add.cc:24 2960 {*addv4si3} (expr_list:REG_EQUIV (mem/c:V4SI (plus:DI (reg/f:DI 20 frame) (const_int -16 [0xfffffffffffffff0])) [3 MEM[(unsigned int *)&__result]+0 S16 A128]) (nil)))