http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56476



             Bug #: 56476

           Summary: ARM volatile writes/str creates superfluous and

                    uncalled for read/ldr with -Os

    Classification: Unclassified

           Product: gcc

           Version: 4.7.1

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: c

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: j...@embeddedarm.com





Gcc 4.7.1 crosscompiler ARM EABI target, x86 Linux host.



In the below code, there are only writes to the "regs" volatile unsigned int *.



Yet, compiling with "-Os", "-O2", or "-O -ftree-vrp" yields code that will do

an uncalled for ldrne in the assembler output.  This is bad as this volatile

unsigned int * represents hardware registers where bus reads have side-effects

and reading a value and then writing the same value back to the same location

is not an equivalent operation to doing nothing at all.



Several gcc versions have been tested and all but some really old 3.3.4 gcc

toolchain exhibited this. (4.6.1 and a 4.4.4 were tested also and had the bug)



//Jesse Off







volatile unsigned int * regs;                                         



void test(void)                                                       

{                                                                     

    int i, x;                                                         



    regs[0x708 / 4] = 0xdeadbeef;                                     



    for (i = 0xbad; i >= 0; i--) {                                    

        if (i == 1)                                                   

            regs[0x708 / 4] = 0xbeefdead;                             

        for (x = 1; x >= 0; x--) {                                    

            regs[0x708 / 4] = 0xbadcab;                               

            regs[0x704 / 4] = x;                                      

        }                                                             

    }                                                                 

}                                                                     



/*                                                                    



BROKEN ASM!!!! (Compiled with -Os)                                         



00000000 <test>:                                                      

   0:   e59f3048        ldr     r3, [pc, #72]   ; 50 <test+0x50>      

   4:   e59f2048        ldr     r2, [pc, #72]   ; 54 <test+0x54>      

   8:   e5933000        ldr     r3, [r3]                              

   c:   e92d4010        push    {r4, lr}                              

  10:   e59f1040        ldr     r1, [pc, #64]   ; 58 <test+0x58>      

  14:   e5832708        str     r2, [r3, #1800] ; 0x708               

  18:   e59f203c        ldr     r2, [pc, #60]   ; 5c <test+0x5c>      

  1c:   e3a04001        mov     r4, #1                                

  20:   e3a0c000        mov     ip, #0                                

  24:   e3520001        cmp     r2, #1                                

  28:   15930708        ldrne   r0, [r3, #1800] ; 0x708               

                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- NOT SAFE!  



  2c:   059f002c        ldreq   r0, [pc, #44]   ; 60 <test+0x60>      

  30:   e2522001        subs    r2, r2, #1                            

  34:   e5830708        str     r0, [r3, #1800] ; 0x708               

  38:   e5831708        str     r1, [r3, #1800] ; 0x708               

  3c:   e5834704        str     r4, [r3, #1796] ; 0x704               

  40:   e5831708        str     r1, [r3, #1800] ; 0x708               

  44:   e583c704        str     ip, [r3, #1796] ; 0x704               

  48:   2afffff5        bcs     24 <test+0x24>                        

  4c:   e8bd8010        pop     {r4, pc}                              

  50:   00000000        .word   0x00000000                            

  54:   deadbeef        .word   0xdeadbeef                            

  58:   00badcab        .word   0x00badcab                            

  5c:   00000bad        .word   0x00000bad                            

  60:   beefdead        .word   0xbeefdead                            





RIGHT AND WORKING (Compiled with -O) (no superfluous ldr on a volatile)         



00000000 <test>:                                                      

   0:   e52d4004        push    {r4}            ; (str r4, [sp, #-4]!)

   4:   e59f304c        ldr     r3, [pc, #76]   ; 58 <test+0x58>      

   8:   e5933000        ldr     r3, [r3]                              

   c:   e59f2048        ldr     r2, [pc, #72]   ; 5c <test+0x5c>      

  10:   e5832708        str     r2, [r3, #1800] ; 0x708               

  14:   e59f2044        ldr     r2, [pc, #68]   ; 60 <test+0x60>      

  18:   e59f1044        ldr     r1, [pc, #68]   ; 64 <test+0x64>      

  1c:   e3a0c001        mov     ip, #1                                

  20:   e3a00000        mov     r0, #0                                

  24:   e59f403c        ldr     r4, [pc, #60]   ; 68 <test+0x68>      

  28:   ea000001        b       34 <test+0x34>                        

  2c:   e3520001        cmp     r2, #1                                

  30:   05834708        streq   r4, [r3, #1800] ; 0x708               

  34:   e5831708        str     r1, [r3, #1800] ; 0x708               

  38:   e583c704        str     ip, [r3, #1796] ; 0x704               

  3c:   e5831708        str     r1, [r3, #1800] ; 0x708               

  40:   e5830704        str     r0, [r3, #1796] ; 0x704               

  44:   e2422001        sub     r2, r2, #1                            

  48:   e3720001        cmn     r2, #1                                

  4c:   1afffff6        bne     2c <test+0x2c>                        

  50:   e8bd0010        pop     {r4}                                  

  54:   e12fff1e        bx      lr                                    

  58:   00000000        .word   0x00000000                            

  5c:   deadbeef        .word   0xdeadbeef                            

  60:   00000bad        .word   0x00000bad                            

  64:   00badcab        .word   0x00badcab                            

  68:   beefdead        .word   0xbeefdead                            



*/

Reply via email to