public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/56476] New: ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os
@ 2013-02-27 19:23 joff at embeddedarm dot com
  2013-02-27 19:42 ` [Bug tree-optimization/56476] " pinskia at gcc dot gnu.org
  2013-02-27 19:47 ` pinskia at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: joff at embeddedarm dot com @ 2013-02-27 19:23 UTC (permalink / raw)
  To: gcc-bugs


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: unassigned@gcc.gnu.org
        ReportedBy: joff@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                            

*/


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug tree-optimization/56476] ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os
  2013-02-27 19:23 [Bug c/56476] New: ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os joff at embeddedarm dot com
@ 2013-02-27 19:42 ` pinskia at gcc dot gnu.org
  2013-02-27 19:47 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-02-27 19:42 UTC (permalink / raw)
  To: gcc-bugs


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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
          Component|target                      |tree-optimization

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> 2013-02-27 19:41:43 UTC ---
The tree pass CSElim is doing this for some reason.  I think it forgot to check
for volatileness.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug tree-optimization/56476] ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os
  2013-02-27 19:23 [Bug c/56476] New: ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os joff at embeddedarm dot com
  2013-02-27 19:42 ` [Bug tree-optimization/56476] " pinskia at gcc dot gnu.org
@ 2013-02-27 19:47 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-02-27 19:47 UTC (permalink / raw)
  To: gcc-bugs


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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> 2013-02-27 19:46:16 UTC ---
Already fixed for 4.7.3 and above.

*** This bug has been marked as a duplicate of bug 56098 ***


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-02-27 19:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-27 19:23 [Bug c/56476] New: ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os joff at embeddedarm dot com
2013-02-27 19:42 ` [Bug tree-optimization/56476] " pinskia at gcc dot gnu.org
2013-02-27 19:47 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).