This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/51447] [4.7 Regression] global register variable definition incorrectly removed as dead code
- From: "matthijs at stdin dot nl" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 10 Sep 2013 07:45:29 +0000
- Subject: [Bug rtl-optimization/51447] [4.7 Regression] global register variable definition incorrectly removed as dead code
- Auto-submitted: auto-generated
- References: <bug-51447-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51447
Matthijs Kooijman <matthijs at stdin dot nl> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |matthijs at stdin dot nl
--- Comment #19 from Matthijs Kooijman <matthijs at stdin dot nl> ---
In case anyone else comes across here and wonders: This fix made it into 4.8,
but was not backported into 4.7.3.
Regarding the bug description that says "4.7 regression", I have also observed
this bug on avr-gcc 4.3.3, so it's not a regression introduced in 4.7.
I also noticed this bug on the AVR platform, using 4.7.2. Just in case it helps
(perhaps for others to find this bug when Googling for avr-gcc), here's the
testcase and bugreport I was preparing before I found this one.
//
// Under some circumstances, writes to a global register variable are
// optimized away, even though that changes behaviour. The below example
// illustrates this.
//
// When compiled as-is, the writes to the variable "global" are removed.
// However, when compiling with -DDO_CALL, which adds a function call to
// the main function, the writes are preserved. This leads me to believe
// that the optimizer sees that main() isn't calling any functions, so
// it must be safe to just remove the writes (even though documentation
// [1] says "Stores into this register are never deleted even if they
// appear to be dead, but references may be deleted or moved or
// simplified.")
//
// It seems that a second condition (in addition to no functions called)
// is that the main function does not return. If we add a return path,
// the writes show up again.
//
// However, removing these writes does not seem sane, since there is
// also an interrupt routine, which can access the variable, but the
// optimizer is apparently not aware that this is a possibility.
//
//
// Tested using:
// avr-gcc -mmcu=attiny13 register.c -S -o - -O
// avr-gcc -mmcu=attiny13 register.c -S -o - -O -DDO_CALL
// avr-gcc -mmcu=attiny13 register.c -S -o - -O -DDO_RETURN
//
// [1]: //
http://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars
#include "avr/io.h"
#include "avr/cpufunc.h"
// Define a global variable in a register
register char global asm("r16");
// Just a dummy function
void foo()
{
// Add some nops so this function doesn't get inlined
_NOP(); _NOP(); _NOP();
}
// Define an ISR that accesses the global. This doesn't actually seem to
// make a different, except that if this wasn't here, removing writes to
// the global would be acceptable
void ISR(INT0_vect)
{
PORTB = global;
}
void main()
{
global = 1;
while(1) {
#ifdef DO_CALL
foo();
#endif
#ifdef DO_RETURN
return;
#endif
}
}