[Bug c/29964] New: volatile problem in optimized functions

2006-11-23 Thread sb at anoto dot com
Using -Os and volatile results in functions, sometimes the optimizer 'forgets'
the volatile property of the function and makes it pure. This has a major
impact in some cases. Test case 1 gives buggy code where test case 2 & 3 works.
The command line to compile this was arm-elf-gcc -c test.c -Os

/* Test case 1 */

struct test_a { volatile int a; };

int func_a(void) __attribute__ ((noinline));
int func_a(void)
{
return ((struct test_a *)0)->a;
}

void a(void)
{
while(func_a() == 0);
}

/* Test case 2 */

struct test_b { volatile int a;};

int func_b(void) __attribute__ ((noinline));
int func_b(void)
{
volatile struct test_b *t= 0;
return t->a;
}

void b(void)
{
while(func_b() == 0);
}

/* Test case 3 */

struct test_c { volatile int a; };

int func_c(void) __attribute__ ((noinline));
int func_c(void)
{
return ((volatile struct test_c *)0)->a;
}

void c(void)
{
while(func_c() == 0);
}


The result from this is:


 :
   0:   e3a03000mov r3, #0  ; 0x0
   4:   e593ldr r0, [r3]
   8:   e12fff1ebx  lr

000c :
   c:   e52de004str lr, [sp, #-4]!
  10:   ebfebl  0 
  14:   e350cmp r0, #0  ; 0x0
  18:   0a03beq 14   <--- looping back to the cmp!?!
  1c:   e49df004ldr pc, [sp], #4

0020 :
  20:   e3a03000mov r3, #0  ; 0x0
  24:   e593ldr r0, [r3]
  28:   e12fff1ebx  lr

002c :
  2c:   e52de004str lr, [sp, #-4]!
  30:   ebfebl  20 
  34:   e350cmp r0, #0  ; 0x0
  38:   0a0abeq 30  <--- looping back to the functon
call
  3c:   e49df004ldr pc, [sp], #4

0040 :
  40:   e3a03000mov r3, #0  ; 0x0
  44:   e593ldr r0, [r3]
  48:   e12fff1ebx  lr

004c :
  4c:   e52de004str lr, [sp, #-4]!
  50:   ebfebl  40 
  54:   e350cmp r0, #0  ; 0x0
  58:   0a12beq 50  <--- looping back to the functon
call
  5c:   e49df004ldr pc, [sp], #4


-- 
   Summary: volatile problem in optimized functions
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sb at anoto dot com
 GCC build triplet: x86-pc-cygwin
  GCC host triplet: x86-pc-cygwin
GCC target triplet: arm-elf-gcc


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



[Bug c/29964] volatile problem in optimized functions

2006-11-23 Thread sb at anoto dot com


-- 

sb at anoto dot com changed:

   What|Removed |Added

 CC||sb at anoto dot com
   Severity|normal  |major
   Keywords||wrong-code


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



[Bug c/30553] New: Registers not spilled to the stack properly when accessing address of parameter in function call

2007-01-22 Thread sb at anoto dot com
To get the binary int of a double, it is common to cast the ptr to the double
to an int ptr and then access the data the pointer points to. However, if the
variable containing the double is a function call parameter and the parameter
is passed in registers and hasn't been spilled to the stack yet, the pointer
access will be accessing uninitialized stack space:

Example:

arm-elf-gcc -Os -mthumb

int myfunc(double x)
{
int a;
a = *(int *)&x;  // x isn't spilled to the stack before the * access is
done
return a+2;
}

int myfunc2(int x)
{
int a;
a = *(int *)&x; // gcc figures out that it doesn't have to go through
memory to do the access
return a+2;
}

extern void dummy(void);

int myfunc3(double x)
{
int a;
dummy(); // This function call forces gcc to spill x (r0 and r1) to
memory
a = *(int *)&x; 
return a+2;
}

The disassembly is:

 :
   0:   b082sub sp, #8
   2:   9800ldr r0, [sp, #0] ; reading from [sp, #0] where r0
should have been saved. Error!
   4:   b002add sp, #8
   6:   3002add r0, #2
   8:   4770bx  lr
...

000c :
   c:   3002add r0, #2 ; Doesn't have to go through the stack.
OK!
   e:   4770bx  lr

0010 :
  10:   b500push{lr}
  12:   b082sub sp, #8
  14:   9000str r0, [sp, #0] ; Aha! r0 is correctly spilled to
the stack to be able to make the function call below
  16:   9101str r1, [sp, #4]
  18:   fffef7ffbl  0 
  1c:   9800ldr r0, [sp, #0] ; Reading from the stack now gives
the correct result. OK!
  1e:   b002add sp, #8
  20:   3002add r0, #2
  22:   bd00pop {pc}

The problem appears for both thumb and normal arm code. I guess the same thing
can happen on any platform that passes the initial parameters in registers


-- 
   Summary: Registers not spilled to the stack properly when
accessing address of  parameter in function call
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sb at anoto dot com
 GCC build triplet: x86-pc-cygwin
  GCC host triplet: x86-pc-cygwin
GCC target triplet: arm-elf-gcc


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