First Last Prev Next    No search results available      Search page      Enter new bug
Bug#: 16554
Product:  
Component:  
Status: VERIFIED
Resolution: FIXED
Assigned To: Not yet assigned to anyone <unassigned@gcc.gnu.org>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: Paul R. Nash <paul_r_nash@hotmail.com>
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 16554 depends on: Show dependency tree
Show dependency graph
Bug 16554 blocks:

Additional Comments:





View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: Opened: 2004-07-14 23:24
Please be kind, this is my first ever gcc bug report... :-/

I built gcc-3.4.0 crossed for arm-linux with softfloat support, according to 
the configurations of crosstool-0.28-rc28, which means:

Reading specs from /usr/local/arm/3.4.0/lib/gcc/arm-linux/3.4.0/specs
Configured with: ../gcc-3.4.0/configure --target=arm-linux --host=i686-linux --
prefix=/usr/local/arm/3.4.0 --with-local-prefix=/usr/local/arm/3.4.0/arm-
linux --with-headers=/usr/local/arm/3.4.0/arm-linux/include --disable-nls --
enable-languages=c,c++ --enable-shared --with-cpu=xscale --with-tune=xscale --
enable-multilib --without-fp --with-float=soft --enable-long-long --enable-
c99 --enable-threads=posix --enable-__cxa_atexit --enable-symvers=gnu --enable-
clocale=gnu
Thread model: posix
gcc version 3.4.0


I'm attempting to build the compaq/OHH bootloader, and it is failing because 
of the following believed-erroneous situation:

In this example program, __start is any externally defined symbol, of at least 
void* or int type (those are the ones I tried).  If its address is taken 
directly in a comparison against zero, the compiler skips the load and compare 
altogether and emits the non-zero case.

With -O0, I can force this to work "right" by loading the address into a local 
var.  But with any optimizations, that gets turned into the first form 
and "optimized" away.

This worked correctly on 2.95.4.

Example program:

//
// Compile with: /usr/local/arm/3.4.0/bin/arm-linux-gcc -O0 -fPIC -g -fverbose-
asm -dp -Wa,-ahlms=a.cod -o a.o a.c
//
extern void* __start;

int fake_main(int x, int y)
{
    int a;

    if ((&__start) == 0)        // This comparison is not done at all
        a = 1;
    else
        a = 2;                  // This store is emitted directly

    {
        void** p = &__start;    // Force address load

        if (p == 0)             // Correct code (but only on -O0)
            a = 3;
        else
            a = 4;
    }
    return a;
}

The debugging options "-g -fverbose-asm -dp -Wa,ahlms=a.cod" of course don't 
affect the problem.

The -fPIC option does not affect the problem (but it's the way my code must be 
compiled).

Head of assembly output showing full option set:

  2              	@ GNU C version 3.4.0 (arm-linux)
   3              	@	compiled by GNU C version 3.3.2 20031022 (Red 
Hat Linux 3.3.2-1).
   4              	@ GGC heuristics: --param ggc-min-expand=47 --param 
ggc-min-heapsize=31938
   5              	@ options passed:  -D__ARM_ARCH_5TE__ -D__XSCALE__ -
D__PIC__ -D__pic__
   6              	@ -mcpu=xscale -msoft-float -auxbase-strip -g -O0 -
fPIC -fverbose-asm
   7              	@ options enabled:  -feliminate-unused-debug-types -
fpeephole
   8              	@ -ffunction-cse -fkeep-static-consts -freg-struct-
return -fgcse-lm
   9              	@ -fgcse-sm -fgcse-las -fsched-interblock -fsched-spec
  10              	@ -fsched-stalled-insns -fsched-stalled-insns-dep -
fbranch-count-reg -fPIC
  11              	@ -fcommon -fverbose-asm -fargument-alias -fzero-
initialized-in-bss -fident
  12              	@ -fmath-errno -ftrapping-math -mapcs-32 -malignment-
traps -msoft-float
  13              	@ -mcpu=xscale

Partial annotated assembler output showing instructions generated:

   5:a.c           ****     int a;
   6:a.c           **** 
   7:a.c           ****     if ((&__start) == 0)        // This comparison is 
not done at all
   8:a.c           ****         a = 1;
   9:a.c           ****     else
  10:a.c           ****         a = 2;                  // This store is 
emitted directly
  45              		.loc 1 10 0
  46 0020 0230A0E3 		mov	r3, #2	@ tmp70,	@ 20
	*arm_movsi_insn/1	[length = 4]
  47 0024 1C300BE5 		str	r3, [fp, #-28]	@ tmp70, a	@ 21
	*arm_movsi_insn/4	[length = 4]
  48              	.LBB2:
  11:a.c           **** 
  12:a.c           ****     {
  13:a.c           ****         void** p = &__start;    // Force address load
  49              		.loc 1 13 0

------- Comment #1 From Wolfgang Bangerth 2004-07-14 23:49 -------
What's wrong with gcc's behavior? You use an extern symbol, so not 
defining it at all would yield a linker error. But if you define it, 
the symbol has an address, and that address must be non-zero, a fact 
that gcc can use when it eliminated if-then clauses because it already 
knows the value of the if-expression. 
 
This is a duplicate of a good number of other PRs. 
 
W. 

------- Comment #2 From Paul R. Nash 2004-07-15 00:28 -------
Subject: Re:  compare on address of global variable always evals to non-zero

Well, that all depends on which symbol.  In this particular case, the symbol
is _start, as defined by an assembly stub that gets linked in -- this is a
bootloader, and it loads out of flash, so the symbols address is indeed zero
in most cases.

----- Original Message ----- 
From: "bangerth at dealii dot org" <gcc-bugzilla@gcc.gnu.org>
To: <paul_r_nash@hotmail.com>
Sent: Wednesday, July 14, 2004 4:49 PM
Subject: [Bug c/16554] compare on address of global variable always evals to
non-zero


>
> ------- Additional Comments From bangerth at dealii dot org  2004-07-14
23:49 -------
> What's wrong with gcc's behavior? You use an extern symbol, so not
> defining it at all would yield a linker error. But if you define it,
> the symbol has an address, and that address must be non-zero, a fact
> that gcc can use when it eliminated if-then clauses because it already
> knows the value of the if-expression.
>
> This is a duplicate of a good number of other PRs.
>
> W.
>
> -- 
>            What    |Removed                     |Added
> --------------------------------------------------------------------------
--
>              Status|UNCONFIRMED                 |RESOLVED
>          Resolution|                            |INVALID
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16554
>
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.
>

------- Comment #3 From Andrew Pinski 2004-07-15 00:34 -------
You want to mark the global variable as weak to change how gcc gets rid of the
if.

------- Comment #4 From Paul R. Nash 2004-07-15 00:48 -------
Ah -- magic.  That works out right.  Thanks!

First Last Prev Next    No search results available      Search page      Enter new bug