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

Reply via email to