Optimization bug?

2015-09-19 Thread Sören Brinkmann
Hi,

I recently came across some bug in my program that I could narrow down
to the snipped below (also attached with a Makefile).

  extern unsigned int _vector_table;

  int main(void)
  {
unsigned int *vector_base = &_vector_table;

if (vector_base == 0) {
return 1;
} else {
return 2;
}
  }

The code generated for this function is (I tested a couple of different
compilers and architectures (4.7, 4.9 and 5.2)):
   :
 0: b8 02 00 00 00  mov$0x2,%eax
 5: c3  retq   

If my understanding is correct, this is a legal optimization under the
assumption that no object may reside at address 0, resulting in the
optimized out if branch.
Though, my understanding is that the switch
'-fno-delete-null-pointer-checks' would remove that assumption allowing
such code to be compiled "correctly" (I'm on an embedded system and code
at 0 is actually important).

Could somebody tell me what the correct way for implementing something
like that would be? Or whether this is actually a gcc issue?

Thanks,
Sören
extern unsigned int _vector_table;

int main(void)
{
	unsigned int *vector_base = &_vector_table;

	if (vector_base == 0) {
		return 1;
	} else {
		return 2;
	}
}
CC ?= gcc
OBJDUMP = objdump
CFLAGS = -Wall -fno-delete-null-pointer-checks -O2 
-fno-delete-null-pointer-checks

SRC = main.c

all: $(SRC:.c=.dump) $(SRC:.c=.s) $(SRC:.c=.o)

%.dump: %.o
$(OBJDUMP) -DS $< > $@

%.s: %.c
$(CC) $(CFLAGS) -S $< -o $@

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

.PHONY: clean
clean:
rm -rf *.o *.s *.dump


Re: Optimization bug?

2015-09-19 Thread pinskia


> On Sep 19, 2015, at 11:00 AM, Sören Brinkmann  
> wrote:
> 
> Hi,
> 
> I recently came across some bug in my program that I could narrow down
> to the snipped below (also attached with a Makefile).
> 
>  extern unsigned int _vector_table;

You need the attribute weak here if the location of _vector_table can be a null 
pointer. 

Thanks,
Andrew


> 
>  int main(void)
>  {
>  unsigned int *vector_base = &_vector_table;
> 
>  if (vector_base == 0) {
>  return 1;
>  } else {
>  return 2;
>  }
>  }
> 
> The code generated for this function is (I tested a couple of different
> compilers and architectures (4.7, 4.9 and 5.2)):
>   :
> 0:b8 02 00 00 00   mov$0x2,%eax
> 5:c3   retq   
> 
> If my understanding is correct, this is a legal optimization under the
> assumption that no object may reside at address 0, resulting in the
> optimized out if branch.
> Though, my understanding is that the switch
> '-fno-delete-null-pointer-checks' would remove that assumption allowing
> such code to be compiled "correctly" (I'm on an embedded system and code
> at 0 is actually important).
> 
> Could somebody tell me what the correct way for implementing something
> like that would be? Or whether this is actually a gcc issue?
> 
>Thanks,
>Sören
> 
> 


Re: Optimization bug?

2015-09-19 Thread Sören Brinkmann
Hi Andrew,

On Sat, 2015-09-19 at 11:34AM -0700, pins...@gmail.com wrote:
> 
> 
> > On Sep 19, 2015, at 11:00 AM, Sören Brinkmann  
> > wrote:
> > 
> > Hi,
> > 
> > I recently came across some bug in my program that I could narrow down
> > to the snipped below (also attached with a Makefile).
> > 
> >  extern unsigned int _vector_table;
> 
> You need the attribute weak here if the location of _vector_table can be a 
> null pointer. 

Indeed, that fixes the problem. Would you have any additional background
why the 'weak' is required in this case? To me it sounded like the
'-fno-delete-null-pointer-checks' should be sufficient.

Thanks,
Sören

> 
> Thanks,
> Andrew
> 
> 
> > 
> >  int main(void)
> >  {
> >  unsigned int *vector_base = &_vector_table;
> > 
> >  if (vector_base == 0) {
> >  return 1;
> >  } else {
> >  return 2;
> >  }
> >  }
> > 
> > The code generated for this function is (I tested a couple of different
> > compilers and architectures (4.7, 4.9 and 5.2)):
> >   :
> > 0:b8 02 00 00 00   mov$0x2,%eax
> > 5:c3   retq   
> > 
> > If my understanding is correct, this is a legal optimization under the
> > assumption that no object may reside at address 0, resulting in the
> > optimized out if branch.
> > Though, my understanding is that the switch
> > '-fno-delete-null-pointer-checks' would remove that assumption allowing
> > such code to be compiled "correctly" (I'm on an embedded system and code
> > at 0 is actually important).
> > 
> > Could somebody tell me what the correct way for implementing something
> > like that would be? Or whether this is actually a gcc issue?
> > 
> >Thanks,
> >Sören
> > 
> > 


Re: Optimization bug?

2015-09-19 Thread Martin Sebor

On 09/19/2015 03:32 PM, Sören Brinkmann wrote:

Hi Andrew,

On Sat, 2015-09-19 at 11:34AM -0700, pins...@gmail.com wrote:




On Sep 19, 2015, at 11:00 AM, Sören Brinkmann  
wrote:

Hi,

I recently came across some bug in my program that I could narrow down
to the snipped below (also attached with a Makefile).

  extern unsigned int _vector_table;


You need the attribute weak here if the location of _vector_table can be a null 
pointer.


Indeed, that fixes the problem. Would you have any additional background
why the 'weak' is required in this case? To me it sounded like the
'-fno-delete-null-pointer-checks' should be sufficient.


-fno-delete-null-pointer-checks prevents GCC from removing tests
for null pointers after such pointers have been dereferenced. For
example, in the following function, GCC normally eliminates the
second if statement because the first statement lets it assume
that p is not null (otherwise dereferencing it would be undefined).

  int foo (int *p) {
if (*p == 0) return 0;
if (p == 0) return 1;
return 2;
  }

The option doesn't affect other assumptions such as that every
object and function in a program lives at a valid, non-null
address.

Martin


Re: Optimization bug?

2015-09-19 Thread Richard Biener
On September 20, 2015 1:40:12 AM GMT+02:00, Martin Sebor  
wrote:
>On 09/19/2015 03:32 PM, Sören Brinkmann wrote:
>> Hi Andrew,
>>
>> On Sat, 2015-09-19 at 11:34AM -0700, pins...@gmail.com wrote:
>>>
>>>
 On Sep 19, 2015, at 11:00 AM, Sören Brinkmann
> wrote:

 Hi,

 I recently came across some bug in my program that I could narrow
>down
 to the snipped below (also attached with a Makefile).

   extern unsigned int _vector_table;
>>>
>>> You need the attribute weak here if the location of _vector_table
>can be a null pointer.
>>
>> Indeed, that fixes the problem. Would you have any additional
>background
>> why the 'weak' is required in this case? To me it sounded like the
>> '-fno-delete-null-pointer-checks' should be sufficient.
>
>-fno-delete-null-pointer-checks prevents GCC from removing tests
>for null pointers after such pointers have been dereferenced. For
>example, in the following function, GCC normally eliminates the
>second if statement because the first statement lets it assume
>that p is not null (otherwise dereferencing it would be undefined).
>
>   int foo (int *p) {
> if (*p == 0) return 0;
> if (p == 0) return 1;
> return 2;
>   }
>
>The option doesn't affect other assumptions such as that every
>object and function in a program lives at a valid, non-null
>address.

Actually we abuse this flag for exactly this purpose so I think the testcase 
shows a bug.  Unless the particular target cannot have global vars at address 
zero.

Would you mind opening a bugreport?

Richard.

>
>Martin