public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/32397]  New: wrong instruction order generated
@ 2007-06-19  0:31 rosenfeld at grumpf dot hope-2000 dot org
  2007-06-19  7:56 ` [Bug c/32397] " pinskia at gcc dot gnu dot org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: rosenfeld at grumpf dot hope-2000 dot org @ 2007-06-19  0:31 UTC (permalink / raw)
  To: gcc-bugs

this C code line 
{(((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw) =
(hx&0x800fffff)|(k<<20); return x;}
causes this assembler code to be generated:

bic     r3, ip, #2130706432
bic     r3, r3, #15728640
ldmia   sp, {r0-r1}
orr     r3, r3, r2, asl #20
str     r3, [r5, #0]
b       .L6

The ldmia instruction loads the value to be returned from memory before the
calculation is finished and the result is stored there. Rearranging the
instructions by hand in the resulting binary makes the program work.

gcc output:
Using built-in specs.
Target: arm-elf
Configured with: /usr/local/src/gcc-4.2.0/configure --target=arm-elf
--prefix=/usr/local --with-gnu-as --with-gnu-ld --disable-hosted-libstdcxx
--disable-__cxa_atexit --enable-languages=c,c++
Thread model: single
gcc version 4.2.0
 /usr/local/libexec/gcc/arm-elf/4.2.0/cc1 -E -quiet -v
-I/tmp/ecos/whz2292_install/include
-I/usr/local/share/ecos/packages/language/c/libm/current
-I/usr/local/share/ecos/packages/language/c/libm/current/src
-I/usr/local/share/ecos/packages/language/c/libm/current/tests -I.
-I/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/
-D__USES_INITFINI__ -MD src/double/portable-api/s_scalbn.tmp
/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c
-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef
-finline-limit=7000 -ffunction-sections -fdata-sections -fno-exceptions
-fworking-directory -O2 -fpch-preprocess -o s_scalbn.i
ignoring nonexistent directory
"/usr/local/lib/gcc/arm-elf/4.2.0/../../../../arm-elf/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /tmp/ecos/whz2292_install/include
 /usr/local/share/ecos/packages/language/c/libm/current
 /usr/local/share/ecos/packages/language/c/libm/current/src
 /usr/local/share/ecos/packages/language/c/libm/current/tests
 .

/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/
 /usr/local/lib/gcc/arm-elf/4.2.0/include
 /usr/local/lib/gcc/arm-elf/4.2.0/../../../../arm-elf/include
End of search list.
 /usr/local/libexec/gcc/arm-elf/4.2.0/cc1 -fpreprocessed s_scalbn.i -quiet
-dumpbase s_scalbn.c -mcpu=arm7tdmi -auxbase-strip
src/double/portable-api/language_c_libm_s_scalbn.o -g -O2 -Wall -Wpointer-arith
-Wstrict-prototypes -Winline -Wundef -version -finline-limit=7000
-ffunction-sections -fdata-sections -fno-exceptions -o s_scalbn.s
GNU C version 4.2.0 (arm-elf)
        compiled by GNU C version 4.1.2 20061021 prerelease (NetBSD nb3
20061125).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=65415
Compiler executable checksum: f21aa8a15d6feeb6af69912bd33e6003
 /usr/local/lib/gcc/arm-elf/4.2.0/../../../../arm-elf/bin/as -mcpu=arm7tdmi -o
src/double/portable-api/language_c_libm_s_scalbn.o s_scalbn.s

source file:
# 1
"/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c"
# 1 "/tmp/ecos/whz2292_build/language/c/libm/current//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1
"/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c"
# 56
"/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c"
# 1 "/tmp/ecos/whz2292_install/include/pkgconf/libm.h" 1
# 12 "/tmp/ecos/whz2292_install/include/pkgconf/libm.h"
# 1 "/tmp/ecos/whz2292_install/include/pkgconf/system.h" 1
# 13 "/tmp/ecos/whz2292_install/include/pkgconf/libm.h" 2
typedef enum {
    CYGNUM_LIBM_COMPAT_UNINIT= 0,
    CYGNUM_LIBM_COMPAT_POSIX = 1,
    CYGNUM_LIBM_COMPAT_IEEE = 2,
    CYGNUM_LIBM_COMPAT_XOPEN = 3,

    CYGNUM_LIBM_COMPAT_SVID = 4

} Cyg_libm_compat_t;
# 57
"/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c"
2
# 83
"/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c"
# 1
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
1
# 66
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
# 1 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" 1
# 58 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h"
# 1 "/tmp/ecos/whz2292_install/include/stddef.h" 1
# 64 "/tmp/ecos/whz2292_install/include/stddef.h"
# 1 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 1 3 4
# 152 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 3 4
typedef long int ptrdiff_t;
# 214 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 326 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 3 4
typedef int wchar_t;
# 65 "/tmp/ecos/whz2292_install/include/stddef.h" 2
# 59 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" 2
# 83 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h"
# 1 "/tmp/ecos/whz2292_install/include/cyg/hal/basetype.h" 1
# 84 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" 2
# 160 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h"
typedef int bool;
# 202 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h"
typedef unsigned char cyg_uint8 ;
typedef signed char cyg_int8 ;

typedef unsigned short cyg_uint16 ;
typedef signed short cyg_int16 ;

typedef unsigned int cyg_uint32 ;
typedef signed int cyg_int32 ;

typedef unsigned long long cyg_uint64 ;
typedef signed long long cyg_int64 ;

typedef int cyg_bool ;






typedef unsigned int cyg_ucount8 ;
typedef signed int cyg_count8 ;

typedef unsigned int cyg_ucount16 ;
typedef signed int cyg_count16 ;

typedef unsigned int cyg_ucount32 ;
typedef signed int cyg_count32 ;

typedef unsigned long long cyg_ucount64 ;
typedef signed long long cyg_count64 ;






typedef volatile unsigned char cyg_atomic;
typedef volatile unsigned char CYG_ATOMIC;




typedef cyg_uint32 CYG_WORD;
typedef cyg_uint8 CYG_BYTE;
typedef cyg_uint16 CYG_WORD16;
typedef cyg_uint32 CYG_WORD32;
typedef cyg_uint64 CYG_WORD64;

typedef cyg_uint32 CYG_ADDRESS;
typedef cyg_uint32 CYG_ADDRWORD;
# 67
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
2
# 1 "/tmp/ecos/whz2292_install/include/math.h" 1
# 69 "/tmp/ecos/whz2292_install/include/math.h"
# 1 "/tmp/ecos/whz2292_install/include/float.h" 1
# 65 "/tmp/ecos/whz2292_install/include/float.h"
# 1 "/usr/local/lib/gcc/arm-elf/4.2.0/include/float.h" 1 3 4
# 66 "/tmp/ecos/whz2292_install/include/float.h" 2
# 70 "/tmp/ecos/whz2292_install/include/math.h" 2

# 1 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h" 1
# 141 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h"
typedef union
{
    cyg_int32 asi32[2];

    cyg_int64 asi64;

    double value;

    struct
    {

        unsigned int fraction1:16;
        unsigned int fraction0: 4;
        unsigned int exponent :11;
        unsigned int sign : 1;
        unsigned int fraction3:16;
        unsigned int fraction2:16;
# 166 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h"
    } number;

    struct
    {

        unsigned int function1:16;
        unsigned int function0:3;
        unsigned int quiet:1;
        unsigned int exponent: 11;
        unsigned int sign : 1;
        unsigned int function3:16;
        unsigned int function2:16;
# 187 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h"
    } nan;

    struct
    {

        cyg_uint32 msw;
        cyg_uint32 lsw;




    } parts;

} Cyg_libm_ieee_double_shape_type;


typedef union
{
    cyg_int32 asi32;

    float value;

    struct
    {
        unsigned int fraction0: 7;
        unsigned int fraction1: 16;
        unsigned int exponent: 8;
        unsigned int sign : 1;
    } number;

    struct
    {
        unsigned int function1:16;
        unsigned int function0:6;
        unsigned int quiet:1;
        unsigned int exponent:8;
        unsigned int sign:1;
    } nan;

} Cyg_libm_ieee_float_shape_type;
# 72 "/tmp/ecos/whz2292_install/include/math.h" 2
# 102 "/tmp/ecos/whz2292_install/include/math.h"
struct exception {
    int type;
    char *name;
    double arg1;
    double arg2;
    double retval;
};






extern const Cyg_libm_ieee_double_shape_type cyg_libm_infinity;
# 135 "/tmp/ecos/whz2292_install/include/math.h"
extern Cyg_libm_compat_t cygvar_libm_compat_mode;






static inline Cyg_libm_compat_t
cyg_libm_get_compat_mode( void )
{
    return cygvar_libm_compat_mode;
}


static inline Cyg_libm_compat_t
cyg_libm_set_compat_mode( Cyg_libm_compat_t math_compat_mode)
{
    Cyg_libm_compat_t oldmode;

    oldmode = cygvar_libm_compat_mode;
    cygvar_libm_compat_mode = math_compat_mode;
    return oldmode;
}
# 173 "/tmp/ecos/whz2292_install/include/math.h"
extern int signgam;
# 182 "/tmp/ecos/whz2292_install/include/math.h"
extern double
acos( double );

extern double
asin( double );

extern double
atan( double );

extern double
atan2( double, double );


extern double
cos( double );

extern double
sin( double );

extern double
tan( double );



extern double
cosh( double );

extern double
sinh( double );

extern double
tanh( double );



extern double
exp( double );

extern double
frexp( double, int * );


extern double
ldexp( double, int );

extern double
log( double );

extern double
log10( double );

extern double
modf( double, double * );






extern double
pow( double, double );

extern double
sqrt( double );



extern double
ceil( double );

extern double
fabs( double );

extern double
floor( double );

extern double
fmod( double, double );





extern int
matherr( struct exception * );





extern double
acosh( double );

extern double
asinh( double );

extern double
atanh( double );



extern double
erf( double );


extern double
erfc( double );



extern double
lgamma( double );



extern double
lgamma_r( double, int * );



extern double
gamma( double );
# 312 "/tmp/ecos/whz2292_install/include/math.h"
extern double
gamma_r( double, int * );




extern double
j0( double );

extern double
j1( double );

extern double
jn( int, double );


extern double
y0( double );


extern double
y1( double );


extern double
yn( int, double );




extern double
scalbn( double, int );



extern double
scalb( double, double );
# 358 "/tmp/ecos/whz2292_install/include/math.h"
extern double
cbrt( double );

extern double
hypot( double, double );

extern int
isnan( double );

extern int
finite( double );

extern double
logb( double );



extern int
ilogb( double );


extern double
nextafter( double, double );




extern double
remainder( double, double );

extern double
significand( double );





extern double
copysign ( double, double );

extern double
rint( double );




extern double
expm1( double );


extern double
log1p( double );
# 68
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
2
# 1 "/tmp/ecos/whz2292_install/include/float.h" 1
# 69
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
2
# 85
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
typedef cyg_int32 __int32_t;
typedef cyg_uint32 __uint32_t;
typedef Cyg_libm_ieee_double_shape_type ieee_double_shape_type;
# 190
"/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h"
extern double
__ieee754_sqrt( double );

extern double
__ieee754_acos( double );

extern double
__ieee754_acosh( double );

extern double
__ieee754_log( double );

extern double
__ieee754_atanh( double );

extern double
__ieee754_asin( double );

extern double
__ieee754_atan2( double, double );

extern double
__ieee754_exp( double );

extern double
__ieee754_cosh( double );

extern double
__ieee754_fmod( double, double );

extern double
__ieee754_pow( double, double );

extern double
__ieee754_lgamma_r( double, int * );

extern double
__ieee754_gamma_r( double, int * );

extern double
__ieee754_lgamma( double );

extern double
__ieee754_gamma( double );

extern double
__ieee754_log10( double );

extern double
__ieee754_sinh( double );

extern double
__ieee754_hypot( double, double );

extern double
__ieee754_j0( double );

extern double
__ieee754_j1( double );

extern double
__ieee754_y0( double );

extern double
__ieee754_y1( double );

extern double
__ieee754_jn( int, double );

extern double
__ieee754_yn( int, double );

extern double
__ieee754_remainder( double, double );

extern int
__ieee754_rem_pio2( double, double * );


extern double
__ieee754_scalb( double, double );







extern double
__kernel_standard( double, double, int );

extern double
__kernel_sin( double, double, int );

extern double
__kernel_cos( double, double );

extern double
__kernel_tan( double, double, int );

extern int
__kernel_rem_pio2( double *, double *, int, int, int, const int * );
# 84
"/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c"
2

static const double
two54 = 1.80143985094819840000e+16,
twom54 = 5.55111512312578270212e-17,
huge = 1.0e+300,
tiny = 1.0e-300;

        double scalbn (double x, int n)
{
        int k,hx,lx;
        hx = (((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw);
        lx = (((Cyg_libm_ieee_double_shape_type *)&x)->parts.lsw);
        k = (hx&0x7ff00000)>>20;
        if (k==0) {
            if ((lx|(hx&0x7fffffff))==0) return x;
            x *= two54;
            hx = (((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw);
            k = ((hx&0x7ff00000)>>20) - 54;
            if (n< -50000) return tiny*x;
            }
        if (k==0x7ff) return x+x;
        k = k+n;
        if (k > 0x7fe) return huge*copysign(huge,x);
        if (k > 0)
            {(((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw) =
(hx&0x800fffff)|(k<<20); return x;}
        if (k <= -54) {
            if (n > 50000)
                return huge*copysign(huge,x);
            else return tiny*copysign(tiny,x);
        }
        k += 54;
        (((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw) =
(hx&0x800fffff)|(k<<20);
        return x*twom54;
}


-- 
           Summary: wrong instruction order generated
           Product: gcc
           Version: 4.2.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rosenfeld at grumpf dot hope-2000 dot org
 GCC build triplet: i386-unknown-netbsdelf4.0.
  GCC host triplet: i386-unknown-netbsdelf4.0.
GCC target triplet: arm-elf


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/32397] wrong instruction order generated
  2007-06-19  0:31 [Bug c/32397] New: wrong instruction order generated rosenfeld at grumpf dot hope-2000 dot org
@ 2007-06-19  7:56 ` pinskia at gcc dot gnu dot org
  2007-06-19 10:53 ` rosenfeld at grumpf dot hope-2000 dot org
  2007-06-19 11:27 ` rask at sygehus dot dk
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-06-19  7:56 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from pinskia at gcc dot gnu dot org  2007-06-19 07:56 -------
((Cyg_libm_ieee_double_shape_type *)&x)->part is ovbiously an aliasing
violation.

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


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/32397] wrong instruction order generated
  2007-06-19  0:31 [Bug c/32397] New: wrong instruction order generated rosenfeld at grumpf dot hope-2000 dot org
  2007-06-19  7:56 ` [Bug c/32397] " pinskia at gcc dot gnu dot org
@ 2007-06-19 10:53 ` rosenfeld at grumpf dot hope-2000 dot org
  2007-06-19 11:27 ` rask at sygehus dot dk
  2 siblings, 0 replies; 4+ messages in thread
From: rosenfeld at grumpf dot hope-2000 dot org @ 2007-06-19 10:53 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from rosenfeld at grumpf dot hope-2000 dot org  2007-06-19 10:52 -------
Subject: Re:  wrong instruction order generated

On Tue, Jun 19, 2007 at 07:56:01AM -0000, pinskia at gcc dot gnu dot org wrote:
> ------- Comment #1 from pinskia at gcc dot gnu dot org  2007-06-19 07:56 -------
> ((Cyg_libm_ieee_double_shape_type *)&x)->part is ovbiously an aliasing
> violation.

I doubt that. As you can see in the source file, x is a double and
Cyg_libm_ieee_double_shape_type is a union containing a double. 

To quote the standard,
 7 An object shall have its stored value accessed only by an lvalue
   expression that has one of the following types:
    a type compatible with the effective type of the object,
        [...]
    an aggregate or union type that includes one of the aforementioned
     types among its members (including, recursively, a member of a
     subaggregate or contained union) [...]

So as far as I understand this should be perfectly legal by the ISO C
standard.

Maybe I'm missing somthing here, I read everywhere that using a union
for this kind of thing is a gcc extension. I wonder, if there is no
standard way to manipulate doubles by treating them as ints or bitfields
or something like that, how is one supposed to write a floating point
emulator in ISO C?


-- 


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/32397] wrong instruction order generated
  2007-06-19  0:31 [Bug c/32397] New: wrong instruction order generated rosenfeld at grumpf dot hope-2000 dot org
  2007-06-19  7:56 ` [Bug c/32397] " pinskia at gcc dot gnu dot org
  2007-06-19 10:53 ` rosenfeld at grumpf dot hope-2000 dot org
@ 2007-06-19 11:27 ` rask at sygehus dot dk
  2 siblings, 0 replies; 4+ messages in thread
From: rask at sygehus dot dk @ 2007-06-19 11:27 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from rask at sygehus dot dk  2007-06-19 11:27 -------
You can use memcpy (&int, &float, min (sizeof (int), sizeof (float))) and vice
versa. I suppose you can also memcpy() into or out of a char array of the right
size.
If you were to use the GCC extension of using a union, it would look something
like this:

double x;
cyg_uint32 hx, lx;
Cyg_libm_ieee_double_shape_type tmp;

tmp.value = x;
hx = tmp.parts.msw
lx = tmp.parts.lsw


-- 


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-06-19 11:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-19  0:31 [Bug c/32397] New: wrong instruction order generated rosenfeld at grumpf dot hope-2000 dot org
2007-06-19  7:56 ` [Bug c/32397] " pinskia at gcc dot gnu dot org
2007-06-19 10:53 ` rosenfeld at grumpf dot hope-2000 dot org
2007-06-19 11:27 ` rask at sygehus dot dk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).