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

Denis Vlasenko <vda.linux at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |vda.linux at googlemail dot com

--- Comment #1 from Denis Vlasenko <vda.linux at googlemail dot com> ---
Simplified a bit:
- spinlock_t is not essential
- mempool_t is not essential
- snic_log_q_error_err_status variable is not necessary
- __attribute__ ((__aligned__)) can be dropped too
- struct vnic_wq can be folded
OTOH:
- struct vnic_wq_ctrl wrapping of int variable is necessary
- wq_lock[1] unused member is necessary (makes gcc "know for sure" that wq[1]
is 1-element array)
- each of -O2 -fno-reorder-blocks -fsanitize-coverage=trace-pc are necessary


extern unsigned int ioread32(void *);
struct vnic_wq_ctrl {
    unsigned int error_status;
};
struct snic {
    unsigned int wq_count;
    struct vnic_wq_ctrl *wq[1];
    int wq_lock[1];
};
void snic_log_q_error(struct snic *snic)
{
    unsigned int i;
    for (i = 0; i < snic->wq_count; i++)
        ioread32(&snic->wq[i]->error_status);
}


<snic_log_q_error>:
   0:   53                      push   %rbx
   1:   48 89 fb                mov    %rdi,%rbx
   4:   e8 00 00 00 00          callq  __sanitizer_cov_trace_pc
   9:   8b 03                   mov    (%rbx),%eax
   b:   85 c0                   test   %eax,%eax  # snic->wq_count==0?
   d:   75 09                   jne    18
   f:   5b                      pop    %rbx # yes, 0
  10:   e9 00 00 00 00          jmpq   __sanitizer_cov_trace_pc #tail call
  15:   0f 1f 00                nopl   (%rax)

  18:   e8 00 00 00 00          callq  __sanitizer_cov_trace_pc
  1d:   48 8b 7b 08             mov    0x8(%rbx),%rdi
  21:   e8 00 00 00 00          callq  ioread32
  26:   83 3b 01                cmpl   $0x1,(%rbx) # snic->wq_count<=1?
  29:   76 e4                   jbe    f
  2b:   e8 00 00 00 00          callq  __sanitizer_cov_trace_pc


Looks like gcc thinks that the loop can execute only zero or one time
(or else we run off wq[1]). So when it iterated once:

  21:   e8 00 00 00 00          callq  ioread32

it checks that snic->wq_count <= 1

  26:   83 3b 01                cmpl   $0x1,(%rbx)
  29:   76 e4                   jbe    f

and if not, we are in "impossible" land and just stop codegen.
-fsanitize-coverage=trace-pc generator twitches one last time:

  2b:   e8 00 00 00 00          callq  __sanitizer_cov_trace_pc
<end>

Reply via email to