https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111026
--- Comment #2 from zhaiqiming at baidu dot com --- (In reply to zhaiqiming from comment #1) > ====== > > [summary] > > When I upgraded from gcc82 to gcc12, I found that linked_list_t::del > execution did not meet expectations. > Looking at .s , i noticed that the assembly statements corresponding to the > following two lines have disappeared. > > (node.*list_node).next->prev = (node.*list_node).prev; > (node.*list_node).prev->next = (node.*list_node).next; > > > ====== > > [environment-gcc12] > Reading specs from > /home/opt/compiler/gcc-12/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/specs > COLLECT_GCC=/home/opt/compiler/gcc-12/bin/gcc > COLLECT_LTO_WRAPPER=/home/opt/compiler/gcc-12/bin/../libexec/gcc/x86_64-pc- > linux-gnu/12.1.0/lto-wrapper > Target: x86_64-pc-linux-gnu > Configured with: ../configure --prefix=/opt/compiler/gcc-12 > --with-local-prefix=/opt/compiler/gcc-12 > --with-native-system-header-dir=/opt/compiler/gcc-12/include > --enable-languages=c,c++ --disable-libstdcxx-pch --disable-multilib > --with-default-libstdcxx-abi=gcc4-compatible --disable-bootstrap > --with-sysroot=/ --build=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu > --enable-gold --enable-lto > Thread model: posix > Supported LTO compression algorithms: zlib > gcc version 12.1.0 (GCC) > > [environment-gcc82] > Using built-in specs. > COLLECT_GCC=/home/opt/compiler/gcc-8.2/gcc-8.2/bin/gcc > COLLECT_LTO_WRAPPER=/home/opt/compiler/gcc-8.2/gcc-8.2/bin/../libexec/gcc/ > x86_64-pc-linux-gnu/8.2.0/lto-wrapper > Target: x86_64-pc-linux-gnu > Configured with: ../configure --prefix=/opt/compiler/gcc-8.2 > --with-local-prefix=/opt/compiler/gcc-8.2 > --with-native-system-header-dir=/opt/compiler/gcc-8.2/include > --enable-languages=c,c++ --disable-libstdcxx-pch --disable-multilib > --disable-bootstrap --with-default-libstdcxx-abi=gcc4-compatible > Thread model: posix > gcc version 8.2.0 (GCC) > > ====== > > [source code] > > > struct list_node_t > { > list_node_t *next; > list_node_t *prev; > }; > > template <typename T, list_node_t T::*inner_list_node> > class list_t > { > public: > list_t() { _head.next = _head.prev = &_head; } > bool is_empty() const { return _head.next == &_head; } > T* entry(list_node_t &node) const { return &node == &_head ? > NULL : > (T*)((char*)&node - (char*)_node_offset); } > > void add(T &node) > { > _head.next->prev = &(node.*inner_list_node); > (node.*inner_list_node).next = _head.next; > (node.*inner_list_node).prev = &_head; > _head.next = &(node.*inner_list_node); > } > > > static void del(T &node) > { > int slot_1 = 10000; > printf("slot_1 %d\n", slot_1); > (node.*inner_list_node).next->prev = > (node.*inner_list_node).prev; > (node.*inner_list_node).prev->next = > (node.*inner_list_node).next; > int slot_2 = 20000; > printf("slot_2 %d\n", slot_2); > } > > protected: > static list_node_t const * const _node_offset; > list_node_t _head; > }; > template <typename T, list_node_t T::*inner_list_node> > list_node_t const * const list_t<T, inner_list_node>::_node_offset = &(((T > *)0)->*inner_list_node); > > template <typename T, list_node_t T::*inner_list_node> > class safe_list_t: public list_t<T, inner_list_node> > { > public: > safe_list_t(): _alive(1),_num(0) > { > pthread_mutex_init(&_mutex, NULL); > pthread_cond_init(&_cond, NULL); > } > > ~safe_list_t() > { > pthread_cond_destroy(&_cond); > pthread_mutex_destroy(&_mutex); > } > > int len() > { > return _num; > } > > void put(T &node) > { > pthread_mutex_lock(&_mutex); > if (_alive) > { > this->add(node); > ++_num; > } > pthread_mutex_unlock(&_mutex); > pthread_cond_signal(&_cond); > } > > T* get() > { > T *ret; > pthread_mutex_lock(&_mutex); > while (_alive && list_t<T, inner_list_node>::is_empty()) > pthread_cond_wait(&_cond, &_mutex); > if (_alive) > { > ret = this->entry(*list_t<T, inner_list_node>::_head.prev); > this->del(*ret); > --_num; > } > else > { > ret = NULL; > } > pthread_mutex_unlock(&_mutex); > return ret; > } > > protected: > pthread_mutex_t _mutex; > pthread_cond_t _cond; > int _alive; > int _num; > }; > > template <class T> > class worker_t > { > public: > T *t; > list_node_t inner_task_list_node; > > public: > worker_t():t(NULL) > { > t = new T; > } > worker_t(T *tt):t(tt) > { > } > > ~worker_t() > { > delete t; > } > > private: > worker_t(const worker_t& rhs); > worker_t& operator=(const worker_t& rhs); > }; > > int main() { > safe_list_t<worker_t<size_t>, &worker_t<size_t>::inner_task_list_node> > _serialize_merge_scan_move_list; > > auto * worker_0 = new worker_t<size_t>; > *worker_0->t = 100; > _serialize_merge_scan_move_list.put(*worker_0); > > auto * worker_1 = new worker_t<size_t>; > *worker_1->t = 200; > _serialize_merge_scan_move_list.put(*worker_1); > > auto* temp_0 = _serialize_merge_scan_move_list.get(); > printf("temp_0->t = %zu\n", *temp_0->t); > delete temp_0; > > > auto* temp_1 = _serialize_merge_scan_move_list.get(); > printf("temp_1->t = %zu\n", *temp_1->t); > delete temp_1; > } > > > ===== > > [.s] > > [important parts - gcc82] > Shell command: /home/opt/compiler/gcc-8.2/gcc-8.2/bin/gcc -S > -ohello82-use.s -save-temps -std=c++11 -O2 -pipe -Wall -Wextra -W -fPIC > -Werror=return-local-addr -Werror=return-type test_main.cpp -lstdc++ > -lpthread -lssl -lcrypto -lrt -lz -ldl > > > .L8: > .cfi_restore_state > movq 8(%rbx), %r12 > cmpq %rbx, %r12 > je .L15 > movq > _ZN6list_tI8worker_tImEXadL_ZNS1_20inner_task_list_nodeEEEE12_node_offsetE@GO > TPCREL(%rip), %rax > movl $10000, %esi > leaq .LC0(%rip), %rdi > subq (%rax), %r12 > xorl %eax, %eax > call printf@PLT > movq 8(%r12), %rdx > movq 16(%r12), %rax > movl $20000, %esi > leaq .LC1(%rip), %rdi > movq %rax, 8(%rdx) > movq %rdx, (%rax) > xorl %eax, %eax > call printf@PLT > subl $1, 108(%rbx) > movq %rbp, %rdi > call pthread_mutex_unlock@PLT > movq %r12, %rax > popq %rbx > .cfi_remember_state > .cfi_def_cfa_offset 24 > popq %rbp > .cfi_def_cfa_offset 16 > popq %r12 > .cfi_def_cfa_offset 8 > ret > > > [important parts - gcc12] > Shell command: /home/opt/compiler/gcc-12/bin/gcc -S -ohello12-use.s > -save-temps -std=c++11 -O2 -pipe -Wall -Wextra -W -fPIC > -Werror=return-local-addr -Werror=return-type test_main.cpp -lstdc++ > -lpthread -lssl -lcrypto -lrt -lz -ldl > > > .L11: > movl $10000, %esi > leaq .LC0(%rip), %rdi > xorl %eax, %eax > call printf@PLT > movl $20000, %esi > leaq .LC1(%rip), %rdi > xorl %eax, %eax > call printf@PLT > subl $1, 108(%rbx) > movq %rbp, %rdi > call pthread_mutex_unlock@PLT > movq %r12, %rax > popq %rbx > .cfi_remember_state > .cfi_def_cfa_offset 24 > popq %rbp > .cfi_def_cfa_offset 16 > popq %r12 > .cfi_def_cfa_offset 8 > ret > .p2align 4,,10 > .p2align 3 linked_list_t::del => list_t::del