public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "joff at embeddedarm dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/56476] New: ARM volatile writes/str creates superfluous and uncalled for read/ldr with -Os
Date: Wed, 27 Feb 2013 19:23:00 -0000	[thread overview]
Message-ID: <bug-56476-4@http.gcc.gnu.org/bugzilla/> (raw)


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                            

*/


             reply	other threads:[~2013-02-27 19:23 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-27 19:23 joff at embeddedarm dot com [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-56476-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).