This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM CLang v6.12: there is bug?

Good day!

I am use Keil uVision v5.28, CLang v6.12.

I noticed an interesting feature on the '-Os balanced' and '-O1' optimization levels.

My code

static void Write(SPI_TypeDef *spi, u16 addr, u32 data, u8 size)
{
  if(size > 0 && size < 5)
  {
    const u8 sht[] = {0, 8, 16, 24};
          u8 buf[] =
    {
      0x40,
      addr >> 11,
      addr >>  3,
      addr <<  5,
      data >> sht[size - 1 & 0x3],
      data >> sht[size - 2 & 0x3],
      data >> sht[size - 3 & 0x3],
      data
    }, *p = buf, i = 4 + size;
    while(i--)
    {
      spi->DR = *p++;
      while(~spi->SR & SPI_SR_RXNE);
      (void)spi->DR;
    }
  }
}

I am sending a flexible array to SPI.
This array stores a header with an address, transaction type and data (1, 2 or 4 bytes in Big-Endian format).

I get the following listing

0x08001394 F1A30C01  SUB      r12,r3,#0x01
0x08001398 FA5FFC8C  UXTB     r12,r12
0x0800139C F1BC0F03  CMP      r12,#0x03
0x080013A0 D844      BHI      0x0800142C
0x080013A2 B580      PUSH     {r7,lr}
0x080013A4 B082      SUB      sp,sp,#0x08
0x080013A6 F04F0C40  MOV      r12,#0x40
    76:       addr <<  5, 
    77:       data >> sht[size - 1 & 0x3], 
    78:       data >> sht[size - 2 & 0x3], 
0x080013AA EA4F1E41  LSL      lr,r1,#5
    72:     { 
    73:       0x40, 
    74:       addr >> 11, 
0x080013AE F88DC000  STRB     r12,[sp,#0x00]
0x080013B2 F88DE003  STRB     lr,[sp,#0x03]
    75:       addr >>  3, 
    76:       addr <<  5, 
    77:       data >> sht[size - 1 & 0x3], 
    78:       data >> sht[size - 2 & 0x3], 
0x080013B6 EA4F0ED1  LSR      lr,r1,#3
    74:       addr >> 11, 
    75:       addr >>  3, 
    76:       addr <<  5, 
    77:       data >> sht[size - 1 & 0x3], 
    78:       data >> sht[size - 2 & 0x3], 
0x080013BA 0AC9      LSRS     r1,r1,#11
    72:     { 
0x080013BC F88DE002  STRB     lr,[sp,#0x02]
0x080013C0 F88D1001  STRB     r1,[sp,#0x01]
    79:       data >> sht[size - 3 & 0x3], 
    80:       data 
    81:     }, *p = buf, i = 4 + size; 
    82:     while(i--) 
    83:     { 
0x080013C4 1C59      ADDS     r1,r3,#1
    77:       data >> sht[size - 1 & 0x3], 
    78:       data >> sht[size - 2 & 0x3], 
0x080013C6 F6427E00  MOVW     lr,#0x2F00
    72:     { 
    73:       0x40, 
    74:       addr >> 11, 
    75:       addr >>  3, 
    76:       addr <<  5, 
    77:       data >> sht[size - 1 & 0x3], 
    78:       data >> sht[size - 2 & 0x3], 
0x080013CA F88D2007  STRB     r2,[sp,#0x07]
    79:       data >> sht[size - 3 & 0x3], 
    80:       data 
    81:     }, *p = buf, i = 4 + size; 
    82:     while(i--) 
    83:     { 
0x080013CE F0010103  AND      r1,r1,#0x03
    77:       data >> sht[size - 1 & 0x3], 
0x080013D2 F6C00E00  MOVT     lr,#0x800
    79:       data >> sht[size - 3 & 0x3], 
0x080013D6 F81E1001  LDRB     r1,[lr,r1]
    79:       data >> sht[size - 3 & 0x3], 
0x080013DA FA22F101  LSR      r1,r2,r1
    72:     { 
    73:       0x40, 
    74:       addr >> 11, 
    75:       addr >>  3, 
    76:       addr <<  5, 
    77:       data >> sht[size - 1 & 0x3], 
0x080013DE F88D1006  STRB     r1,[sp,#0x06]
    78:       data >> sht[size - 2 & 0x3], 
    79:       data >> sht[size - 3 & 0x3], 
    80:       data 
    81:     }, *p = buf, i = 4 + size; 
    82:     while(i--) 
    83:     { 
0x080013E2 1C99      ADDS     r1,r3,#2
0x080013E4 F0010103  AND      r1,r1,#0x03
    78:       data >> sht[size - 2 & 0x3], 
0x080013E8 F81E1001  LDRB     r1,[lr,r1]
    78:       data >> sht[size - 2 & 0x3], 
0x080013EC FA22F101  LSR      r1,r2,r1
    72:     { 
    73:       0x40, 
    74:       addr >> 11, 
    75:       addr >>  3, 
    76:       addr <<  5, 
    77:       data >> sht[size - 1 & 0x3], 
    78:       data >> sht[size - 2 & 0x3], 
    79:       data >> sht[size - 3 & 0x3], 
    80:       data 
    81:     }, *p = buf, i = 4 + size; 
    82:     while(i--) 
    83:     { 
0x080013F0 F88D1005  STRB     r1,[sp,#0x05]
    77:       data >> sht[size - 1 & 0x3], 
0x080013F4 1CD9      ADDS     r1,r3,#3
0x080013F6 F0010303  AND      r3,r1,#0x03
    77:       data >> sht[size - 1 & 0x3], 
0x080013FA F81E3003  LDRB     r3,[lr,r3]
    77:       data >> sht[size - 1 & 0x3], 
0x080013FE 40DA      LSRS     r2,r2,r3
    72:     { 
0x08001400 F88D2004  STRB     r2,[sp,#0x04]
0x08001404 466A      MOV      r2,sp
0x08001406 B002      ADD      sp,sp,#0x08
0x08001408 E8BD4080  POP      {r7,lr}
    84:       spi->DR = *p++; 
0x0800140C FA5FF38C  UXTB     r3,r12
    84:       spi->DR = *p++; 
0x08001410 8183      STRH     r3,[r0,#0x0C]
0x08001412 BF00      NOP      
    85:       while(~spi->SR & SPI_SR_RXNE); 
0x08001414 8903      LDRH     r3,[r0,#0x08]
    85:       while(~spi->SR & SPI_SR_RXNE); 
0x08001416 07DB      LSLS     r3,r3,#31
0x08001418 D0FC      BEQ      0x08001414
    86:       (void)spi->DR; 
    87:     } 
    88:   } 
0x0800141A 8983      LDRH     r3,[r0,#0x0C]
    82:     while(i--) 
    83:     { 
    84:       spi->DR = *p++; 
    85:       while(~spi->SR & SPI_SR_RXNE); 
    86:       (void)spi->DR; 
    87:     } 
    88:   } 
0x0800141C 060B      LSLS     r3,r1,#24
    89: } 
    90:  
    91: void spi_InitSw1(void) 
0x0800141E BF08      IT       EQ
0x08001420 4770      BX       lr
0x08001422 3201      ADDS     r2,r2,#0x01
    82:     while(i--) 
    83:     { 
0x08001424 3901      SUBS     r1,r1,#0x01
    84:       spi->DR = *p++; 
    85:       while(~spi->SR & SPI_SR_RXNE); 
    86:       (void)spi->DR; 
    87:     } 
    88:   } 
0x08001426 F892C000  LDRB     r12,[r2,#0x00]
0x0800142A E7EF      B        0x0800140C

As you can see, 8 bytes are reserved for the array on the stack, and it is initialized. But before the loop, this array is freed from the stack! Any interruption will spoil the data in this array.

Why is this happening?

Parents Reply Children
No data