This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: An x86 -fpic and -fomit-frame-pointer bug
- To: manfred at s-direktnet dot de, Manfred dot Hollstein at ks dot sel dot alcatel dot de
- Subject: Re: An x86 -fpic and -fomit-frame-pointer bug
- From: hjl at lucon dot org (H.J. Lu)
- Date: Sat, 20 Jun 1998 14:52:59 -0700 (PDT)
- Cc: john at feith dot com, law at cygnus dot com, egcs-bugs at cygnus dot com
>
> On Mon, 15 June 1998, 23:14:14, hjl@lucon.org wrote:
>
> > Hi,
> >
> > Here is a test case for an x86 -fpic and -fomit-frame-pointer bug.
> > cexp.cc is miscompiled by -fpic and -fomit-frame-pointer. Basically
> > ebx saved on the stack is overriden by
> >
> > fstpl (%esp)
> >
> > Later,
> >
> > popl %ebx
> >
> > put some garbage in ebx. Without -fpic or -fomit-frame-pointer, cexp.s
> > is compiled fine.
> >
> > BTW, egcs 1.0.3 is ok. The last working egcs 1.1 is 971215 and 971225
> > has the same bug.
>
> H.J., your example is incomplete; the file "cexp.h" is missing!
>
It shows you are the only one who ever tried my testcase :-). Here
is the complete testcase.
--
H.J. Lu (hjl@gnu.org)
---
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1998-06-20 14:51 PDT by <hjl@ocean>.
# Source directory was `/home/hjl/bugs/gcc/pic.1'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 773 -rw-r--r-- Makefile
# 220 -rw-r--r-- main.cc
# 1226 -rw-r--r-- cexp.cc
# 794 -rw-r--r-- cexp.h
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh00732; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
$echo 'x -' extracting 'Makefile' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
CC=gcc -B/home/work/gnu/bin/egcs/gcc/
#CC=gcc -B/home/work/build/bin/egcs/bad/
#CC=gcc -B/home/work/misc/gnu/bin/egcs/gcc/
EXCEPTIONS=-fno-exceptions
CFLAGS=-fomit-frame-pointer -O9 -fpic $(EXCEPTIONS) # -dra
CFLAGS=-fomit-frame-pointer -O3 -fpic $(EXCEPTIONS) # -dra
#CFLAGS=-fno-omit-frame-pointer -O9 -fpic $(EXCEPTIONS) -dra
LDLIBS=-lstdc++
X
PROGS=main
SRCS=$(PROGS:=.cc) cexp.cc
ASMS=$(PROGS:=.s) cexp.s
X
all: $(PROGS)
X for f in $(PROGS); do echo "Running: $$f"; $$f; \
X if [ $$? != 0 ]; then echo Failed; fi; done
X
asm: $(ASMS)
X
cexp.s: cexp.cc
X $(CC) -S $(CFLAGS) $<
X
main.s: main.cc
X $(CC) -S -O2 $(EXCEPTIONS) $<
X
main: asm
X $(CC) -o $@ $(ASMS) $(LDLIBS)
X
clean:
X $(RM) -f *.s *.cc.* *.c.* $(PROGS) *.o core a.out
X
shar:
X shar Makefile $(SRCS) cexp.h > shar.out
SHAR_EOF
$shar_touch -am 0620145198 'Makefile' &&
chmod 0644 'Makefile' ||
$echo 'restore of' 'Makefile' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'Makefile:' 'MD5 check failed'
0ad509246ccbdd251761b7164964a7e2 Makefile
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
test 773 -eq "$shar_count" ||
$echo 'Makefile:' 'original size' '773,' 'current size' "$shar_count!"
fi
fi
# ============= main.cc ==============
if test -f 'main.cc' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'main.cc' '(file already exists)'
else
$echo 'x -' extracting 'main.cc' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'main.cc' &&
#include <iostream.h>
#include "cexp.h"
X
int
foo (ccr x)
{
X cout << x.real () << ", " << x.imag () << endl;
X return (x.real () == 1.0) + (x.imag () == 1.0);
}
X
int
main ()
{
X c a (2.0, 3.0);
X return foo (exp (a));
}
SHAR_EOF
$shar_touch -am 0616120298 'main.cc' &&
chmod 0644 'main.cc' ||
$echo 'restore of' 'main.cc' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'main.cc:' 'MD5 check failed'
c91c0090b83b48a4d95d05ba3c5b20c1 main.cc
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'main.cc'`"
test 220 -eq "$shar_count" ||
$echo 'main.cc:' 'original size' '220,' 'current size' "$shar_count!"
fi
fi
# ============= cexp.cc ==============
if test -f 'cexp.cc' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'cexp.cc' '(file already exists)'
else
$echo 'x -' extracting 'cexp.cc' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'cexp.cc' &&
#include "cexp.h"
X
__inline double exp (double __x);
__inline double
exp (double __x)
{
X register double __value, __exponent;
#if 1
#if 1
X __asm __volatile__
X ("fldl2e # e^x = 2^(x * log2(e))\n\t"
X "fmul %%st(1) # x * log2(e)\n\t"
X "fstl %%st(1)\n\t"
X "frndint # int(x * log2(e))\n\t"
X "fxch\n\t"
X "fsub %%st(1) # fract(x * log2(e))\n\t"
X "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t"
X : "=t" (__value), "=u" (__exponent) : "0" (__x));
#endif
X __value += 1.0;
X __asm __volatile__
X ("fscale"
X : "=t" (__value) : "0" (__value), "u" (__exponent));
X
X return __value;
#else
X return __x;
#endif
}
__inline double sin (double __x);
__inline double
sin (double __x)
{
#if 1
X register double __value;
X __asm __volatile__
X ("fsin"
X : "=t" (__value) : "0" (__x));
X return __value;
#else
X return __x;
#endif
}
__inline double cos (double __x);
__inline double
cos (double __x)
{
#if 0
X register double __value;
X __asm __volatile__
X ("fcos"
X : "=t" (__value): "0" (__x));
X return __value;
#else
X return __x;
#endif
}
template <class FLOAT> complex<FLOAT>
exp (const complex<FLOAT>& x)
{
X return polar (FLOAT (exp (x.real ())), x.imag ());
}
template c exp (ccr);
SHAR_EOF
$shar_touch -am 0616080098 'cexp.cc' &&
chmod 0644 'cexp.cc' ||
$echo 'restore of' 'cexp.cc' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'cexp.cc:' 'MD5 check failed'
81db6a2f2b1c1e9ee30583e912787461 cexp.cc
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'cexp.cc'`"
test 1226 -eq "$shar_count" ||
$echo 'cexp.cc:' 'original size' '1226,' 'current size' "$shar_count!"
fi
fi
# ============= cexp.h ==============
if test -f 'cexp.h' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'cexp.h' '(file already exists)'
else
$echo 'x -' extracting 'cexp.h' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'cexp.h' &&
#ifndef _CEXP_H
#define _CEXP_H
X
#if 0
#define __inline
#define inline
#endif
X
template <class _FLT>
class complex
{
public:
X complex (_FLT r = 0, _FLT i = 0): re (r), im (i) { }
X _FLT real () const { return re; }
X _FLT imag () const { return im; }
X _FLT re, im;
};
template <class _FLT> inline complex<_FLT>
polar (_FLT r, _FLT t) __attribute__ ((const));
template <class _FLT> inline complex<_FLT>
polar (_FLT r, _FLT t)
{
X return complex<_FLT> (r * cos (t), r * sin (t));
}
class complex<double>
{
public:
X complex (double r = 0, double i = 0): re (r), im (i) { }
X double real () const { return re; }
X double imag () const { return im; }
X double re, im;
};
template <class FLOAT> complex<FLOAT> exp (const complex<FLOAT>& x);
typedef complex<double> c;
typedef const c& ccr;
#endif
SHAR_EOF
$shar_touch -am 0616094098 'cexp.h' &&
chmod 0644 'cexp.h' ||
$echo 'restore of' 'cexp.h' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'cexp.h:' 'MD5 check failed'
86ff5f95ec14fe34f3db3463d8393d66 cexp.h
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'cexp.h'`"
test 794 -eq "$shar_count" ||
$echo 'cexp.h:' 'original size' '794,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh00732
exit 0