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

--- Comment #4 from d.dorau at avm dot de ---
(In reply to Eric Botcazou from comment #3)

> AFAICS there is only one "addiu s0,s0,0" executed after the "lui s0,0x0" in
> this basic block.  Doesn't the problem occur for the call in the following
> basic block instead?

You are right. I truncated the disassembly too early.
Please let me correct myself.

    if((subtype == 8) && !BUFFER_IS_FF(data->addr1))
  30:   14c20016        bne     a2,v0,8c <foo+0x8c>
  34:   a7a00018        sh      zero,24(sp)
  38:   90a20000        lbu     v0,0(a1)
  3c:   240300ff        li      v1,255
  40:   14430010        bne     v0,v1,84 <foo+0x84>
  44:   3c100000        lui     s0,0x0
                        44: R_MIPS_HI16 memcmp_
  48:   90a30001        lbu     v1,1(a1)
  4c:   14620015        bne     v1,v0,a4 <foo+0xa4>
  50:   26100000        addiu   s0,s0,0
                        50: R_MIPS_LO16 memcmp_
  54:   90a20002        lbu     v0,2(a1)
  58:   14430012        bne     v0,v1,a4 <foo+0xa4>
  5c:   26100000        addiu   s0,s0,0
                        5c: R_MIPS_LO16 memcmp_
  60:   90a30003        lbu     v1,3(a1)
  64:   1462000f        bne     v1,v0,a4 <foo+0xa4>
  68:   26100000        addiu   s0,s0,0
                        68: R_MIPS_LO16 memcmp_
  6c:   90a20004        lbu     v0,4(a1)
  70:   14430004        bne     v0,v1,84 <foo+0x84>
  74:   00000000        nop
  78:   90a30005        lbu     v1,5(a1)
  7c:   10620003        beq     v1,v0,8c <foo+0x8c>
  80:   00000000        nop
  84:   10000007        b       a4 <foo+0xa4>
  88:   26100000        addiu   s0,s0,0
                        88: R_MIPS_LO16 memcmp_
    if(!memcmp_(data->addr2, nullbuf, BUF_LEN))
  8c:   3c100000        lui     s0,0x0
                        8c: R_MIPS_HI16 memcmp_
  90:   24060006        li      a2,6
  94:   27a50014        addiu   a1,sp,20
  98:   26100000        addiu   s0,s0,0
                        98: R_MIPS_LO16 memcmp_
  9c:   0200f809        jalr    s0
  a0:   24840006        addiu   a0,a0,6
    bar(dev, data, subtype);
    if(!memcmp_(&dev->b, &dev->a, 1))
  a4:   24060001        li      a2,1
  a8:   02202825        move    a1,s1
  ac:   0200f809        jalr    s0
  b0:   26240001        addiu   a0,s1,1


The two flows:

1) Buffer is all-FF:
   The flow reaches 7c, where it branches to 8c. Regarding s0 we get the
following
   instructions:

   44:  3c100000        lui     s0,0x0
   50:  26100000        addiu   s0,s0,0
   5c:  26100000        addiu   s0,s0,0
   68:  26100000        addiu   s0,s0,0
   8c:  3c100000        lui     s0,0x0
   98:  26100000        addiu   s0,s0,0
   9c:  0200f809        jalr    s0

   where each addui adds "R_MIPS_LO16 memcmp_" to s0. The lui instruction
   at 8c resets s0 so that the call at 9c is successful.

2) Last byte of buffer is non-FF
   The flow reaches 7c, but it does not branch here. Instead we branch to
   a4 at 84. We get

   44:  3c100000        lui     s0,0x0
   50:  26100000        addiu   s0,s0,0
   5c:  26100000        addiu   s0,s0,0
   68:  26100000        addiu   s0,s0,0
   88:  26100000        addiu   s0,s0,0
   ac:  0200f809        jalr    s0

   In this case we get 4 times "R_MIPS_LO16 memcmp_" to s0 which leads to
   a crash at ac.

Reply via email to