[Bug tree-optimization/61818] New: unused code fails to be removed after dom1, thread updated

manjian2006 at gmail dot com gcc-bugzilla@gcc.gnu.org
Wed Jul 16 09:55:00 GMT 2014


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61818

            Bug ID: 61818
           Summary: unused code fails to be removed after dom1, thread
                    updated
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: manjian2006 at gmail dot com

I found the following code:
#include <stddef.h>
#define container_of(ptr, type, member) ({            \
    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) );})

struct Node
{
    Node* m_next;
    int m_val;
};

void setLast(Node* n, int val)
{
    Node** ppnode = &n;

    while (*ppnode) {
        ppnode = &(*ppnode)->m_next;
    }

    // This if statement should be removed    
    if (ppnode == &n)
        return;
    Node* n2 = container_of(ppnode, Node, m_next);
    n2->m_val = val;
}

generates wired assembly codes:
_Z7setLastP4Nodei:
.LFB0:
    .cfi_startproc
    testq    %rdi, %rdi
    movq    %rdi, -8(%rsp)
    jne    .L3
    jmp    .L9
    .p2align 4,,10
    .p2align 3
.L4:
    movq    %rax, %rdi
.L3:
    movq    (%rdi), %rax
    testq    %rax, %rax
    jne    .L4
=>    leaq    -8(%rsp), %rax
=>    cmpq    %rax, %rdi
=>    je    .L1
    movl    %esi, 8(%rdi)
.L1:
    rep ret
.L9:
    rep ret

note that the marked assembly codes should not even exist. The value stored in
-8(%rsp) remains not used.

After further debugging. I find
    .cfi_startproc
    testq    %rdi, %rdi
    movq    %rdi, -8(%rsp)
    jne    .L3
    jmp    .L9
is generated by "ch" pass (copy_loop_headers). That makes sense.

And that jump to the exist block is threaded in dom1 pass, and it makes sense
too.

But gimpl codes:
  # n2_9 = PHI <n2_5(4)>
  if (&nD.2229 == n2_9)
    goto <bb 7>;
  else
    goto <bb 6>;

remain to the end, and get "cleverly" optimized into the following form:
  if (&nD.2229 == n2_5)
    goto <bb 7>;
  else
    goto <bb 6>;

That does not make any sense.

GCC should have a pass to remove this code. 
Is that because currently pointer analysis is not flow-aware?



More information about the Gcc-bugs mailing list