GMP test fails with -flto

Richard Biener richard.guenther at gmail.com
Wed Jul 3 08:45:24 UTC 2019


On Wed, Jul 3, 2019 at 9:49 AM Vincent Lefevre <vincent at vinc17.net> wrote:
>
> On 2019-07-02 12:41:15 +0200, Torbjorn Granlund wrote:
> > Richard Biener <richard.guenther at gmail.com> writes:
> >
> >   On Mon, Jul 1, 2019 at 11:13 PM Torbjörn Granlund <tg at gmplib.org> wrote:
> >   >
> >   > Vincent Lefevre <vincent at vinc17.net> writes:
> >   >
> >   >   Yes, with LTO, the object file does not contain the structure as is.
> >   >   Thus the detection from "od -b conftest.$OBJEXT" does not work.
> >   >
> >   > That could be solved by generating a final executable, right?
> >   >
> >   Yes.
>
> I would say that this may not work due to optimization (even if the
> structure is in a different file than main(), as LTO could optimize
> anyway). If the structure is declared as volatile, I think that
> this will always prevent related optimization, but I'm not sure.
> Generating a library should always work, IMHO.
>
> > Does the patch below make sense?
> >
> > The main funcion is needed as we create an executable, its references to
> > foo are needed, else LTO will remove foo altogether.
> >
> > *** /tmp/extdiff.MsIr0g/gmp-main.3300fbb5d615/acinclude.m4    Mon Jun 17 00:11:50 2019
> > --- /home/tege/prec/gmp-main/acinclude.m4     Tue Jul  2 12:37:53 2019
> > ***************
> > *** 3307,3313 ****
> >     -123456789.0,
> >     { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' },
> > ! };]
> >   EOF
> > ! gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&AC_FD_CC 2>&1"
> >   if AC_TRY_EVAL(gmp_compile); then
> >   cat >conftest.awk <<\EOF
> > --- 3307,3320 ----
> >     -123456789.0,
> >     { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' },
> > ! };
> > ! int main(){
> > !   int i;
> > !   for (i = 0; i < 8; i++) {
> > !     printf ("%d %d %f\n", foo.before[i] + foo.after[i], foo.x);
> > !   }
>
> Here, after loop enrolling, the compiler could see that the arguments
> are known and generate a fixed puts(). This kind of optimization must
> not be done with a structure declared as volatile. But I think that
> data in the structure could be rearranged (what matters is that when
> run, the program will still do memory accesses and the behavior will
> be the same); that's rather unlikely, though.

Could happen though but making the structure object volatile might help
(the compiler could still see you don't use threads and it's regular data
and nothing can happen and thus ignore even that...).  The only way
to avoid it would be to do sth like

   for (i = 0; i < 8; i++)
     if (argv[1][2*i])
       foo.before[i] = foo.after[i] = ((char *)&foo.x)[i] = argv[1][2*i+1];

thus conditionally(! otherwise the compiler might optimize away the
initializer...) overwrite it from program input.  There's also the
possibility of the compiler altering the structure layout...

So yes, building a shared object with the data exported is probably
more future-proof ;)

OTOH not all targets support shared objects...

Let the perfect not be the enemy of the good here.

Richard.

>
> --
> Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


More information about the gmp-bugs mailing list