Bug 24165 - asm volatile instructions incorrectly scheduled.?
Summary: asm volatile instructions incorrectly scheduled.?
Status: RESOLVED DUPLICATE of bug 17884
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 4.0.0
: P1 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-01 17:48 UTC by Björn Haase
Modified: 2006-08-14 20:49 UTC (History)
2 users (show)

See Also:
Host: present on i586-linux, x86_64-linux and i586 cygwin
Target: avr-*-*
Build: present on i586-linux, x86_64-linux and i586 cygwin
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Björn Haase 2005-10-01 17:48:54 UTC
This bug report refers to the discussion on 
 
[bug #14616] definition of sei() in interrupts.h is faulty 
<http://savannah.nongnu.org/bugs/?func=detailitem&item_id=14616> 
 
and the according discussion thread on [avr-libc-dev]  
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev/ 
 
 
The issue is the question if for the following test case gcc is allowed to 
schedule or not allowed to schedule an asm volatile instruction (the text of 
this comment continues after the test case). For clarity the actual asm 
instructions have been replaced by comments illustrating the meaning: 
 
 
/* Start of test case */ 
 
typedef unsigned char      uint8_t; 
typedef unsigned short int uint16_t; 
 
class class_with_volatile_data_structures 
{ 
  public: 
 
  void __attribute__ ((always_inline)) 
  wait_for_event (uint16_t event) 
   { 
     while (getval_protected () != event) 
       ; 
   }; 
 
  private: 
 
  uint16_t 
  getval_protected (void) 
  { 
    uint16_t result; 
 
    asm volatile ("/* disable irq in cpu status */" : : ); 
    result = class_local_data; 
    asm volatile ("/* enable irq */" : : ); 
 
    return result; 
  } 
 
  volatile uint16_t class_local_data; 
}; 
 
class_with_volatile_data_structures object; 
 
void 
wait_for_42 (void) 
{ 
  object.wait_for_event (42); 
} 
 
/* End of test case */ 
 
 
Compiler output reads for (buggy ?) avr-g++ (GCC) 4.0.0 
 
 
_Z11wait_for_42v: 
.L2: 
/* #APP */ 
        /* disable irq in cpu status */ 
        /* enable irq */ 
/* #NOAPP */ 
        lds r24,object 
        lds r25,(object)+1 
        sbiw r24,42 
        brne .L2 
        ret 
 
and for avr-g++ (GCC) 4.0.1 20050624 (prerelease) 
 
_Z11wait_for_42v: 
.L2: 
/* #APP */ 
        /* disable irq in cpu status */ 
/* #NOAPP */ 
        lds r24,object 
        lds r25,(object)+1 
/* #APP */ 
        /* enable irq */ 
/* #NOAPP */ 
        sbiw r24,42 
        brne .L2 
        ret 
 
. So for the more recent version the acess to the variable is protected and for 
the original first 4.0.0 release not. If  
 
    asm volatile ("/* disable irq in cpu status */" : : : "memory"); 
 
is used, the variable access was protected for both compiler versions. 
 
The important question for the avr-libc header files is now:  
 
According the specification, what is guaranteed by gcc concerning volatile asm 
statements? According to the spec 
 
>  The `volatile' keyword indicates that the instruction has important 
> side-effects.  GCC will not delete a volatile `asm' if it is reachable. 
> (The instruction can still be deleted if GCC can prove that 
> control-flow will never reach the location of the instruction.)  In 
> addition, GCC will not reschedule instructions across a volatile `asm' 
> instruction. 
 
, I'd like to assume that the "memory" clobbers should not be required.? 
 
Bjoern
Comment 1 Andrew Pinski 2005-10-01 18:06:42 UTC
Huh, so you are saying that 4.0.1 is fixed?

I don't understand why this is being reported as 4.0.1 has been released for a while now and 4.0.2 was 
just released too.
Comment 2 Björn Haase 2005-10-01 18:46:34 UTC
The question merely is to find out if this is a bug / a bug of the 
documentation or no bug at all.  
 
After the fix for PR22000 the actual issue I had stepped over originally is 
indeed fixed: The protection of volatile *variables* now indeed works. The 
question that is still open, however, is:  Is gcc generally allowed to schedule 
statements across asm volatile statements?  E.g. look at an hypothetical 
example where someone would, e.g. like to disable irqs for speed reasons. 
     
    asm volatile ("/* disable irq */" : : );                // 1 
    for (i=0; i < 1000; i++)                                // 2 
      { 
        a [i] *= 3; 
      } 
    asm volatile ("/* enable irq */" : : );                 // 3 
 
After reading the specs "In addition, GCC will not reschedule instructions 
across a volatile `asm' instruction.", I still think that we either  
 
1) still have a bug or 
2) have a documentation that "caused at least some people to understand it 
differently from than it was meant to be understood" (saying this in order to 
avoid the terminus documentation bug). 
 
In case that scheduling is meant to be allowed if no volatile variable access 
is concerned, we probably would need to change the present implementation of 
irq disabling in the avr-libc's header files. 
 
Bjoern 
Comment 3 Andrew Pinski 2005-10-01 19:48:12 UTC
The documention was changed for 4.0.0, see PR 17884.
And see http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01120.html


So this is a dup of bug 17884.

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