Compile error when not using -ftree-ter

Job Noorman jobnoorman@gmail.com
Thu Aug 19 12:12:00 GMT 2010


On Thursday 19 August 2010 11:19:09 you wrote:
> On 08/19/2010 09:10 AM, Job Noorman wrote:
> > Andrew Haley <aph at redhat dot com> wrote:
> >> Pretty obviously, replacing "movl $_ZN3Foo6foobarEv, %eax; push %rax"
> >> with "push $_ZN3Foo6foobarEv" is an optimization.
> > 
> > Yes, it would be if GCC does it without my help (which, by the way, it
> > does not, no matter which optimizations used). However, since I'm
> > explicitly telling GCC to emit "push $_ZN3Foo6foobarEv", it is an
> > optimization from my side and should have nothing to do with any
> > optimizations from GCC's side.
> 
> "should" statement with missing "because": syntax error.  :-)
> 
> >> And nothing that a gcc developer says will convince you otherwise?
> > 
> > Nothing a GCC developer has already said has convinced me. Of course
> > I can be convinced.
> > 
> >> If I were you, I'd use
> >> 
> >>     void test()
> >>     {
> >>     
> >>         asm("push %0;"
> >>         
> >>             : "g"((plain_foobar_t)&Foo::foobar));
> >>     
> >>     }
> > 
> > That will output the exact same assembly code as when using the "r"
> > constraint. I really want to use the "i" constraint to skip the extra
> > "mov".
> 
> Works for me:
> 
> -O0:
> 
>        movl    $_ZN3Foo6foobarEv, %eax
> #APP
> # 13 "ttt.cc" 1
>         push %rax;
> # 0 "" 2
> #NO_APP
> 
> -O2:
> 
> #APP
> # 13 "ttt.cc" 1
>         push $_ZN3Foo6foobarEv;
> # 0 "" 2
> #NO_APP
> 
> > And, sorry if I sound like a broken record, I still think this should be
> > possible. Consider the following (which was pointed out to me in a
> > comment on
> > 
> > my bug report):
> >     void test()
> >     {
> >     
> >         asm("push %0;"
> >         
> >             : "i"((void*)(plain_foobar_t)&Foo::foobar));
> >     
> >     }
> > 
> > This always works! Now, if you could give me a good explanation of how it
> > could be that "(void*)expr" is accepted as a constant expression when
> > "expr" is not,
> 
> I already did, I think: some things get constant folded regardless of
> optimization level, but this is just luck.
> 
> > I might be convinced that this is not a bug.
> 
> But gcc doesn't support the "i" constraint with anything other than a
> real compile-time constant (in the sense of __builtin_constant_p) so
> it's not a bug.
> 
> Andrew.

Hi Andrew,

About your last statement: That would make sense to me. (Although I really 
don't like the fact that whether something would be accepted by the "i" 
constraint depends on optimization options. IMHO, whether something is 
syntactically valid should not depend on optimizations.)

But I see some evidence that your statement is not true. First of all, it's 
not what the documentation claims:

" 'i': An immediate integer operand (one with constant value) is allowed. This 
includes symbolic constants whose values will be known only at assembly time 
or later. "

Secondly, in practice a lot of expression are accepted which are not 
__builtin_constant_p. Here is an example program:

    #include <iostream>
    using namespace std;

    struct Foo {void foobar() {}};
    typedef void (*plain_foobar_t)(Foo*);
    void func() {}
    int var;

    int main()
    {
        cout << __builtin_constant_p((void*)(plain_foobar_t)(&Foo::foobar))
            << __builtin_constant_p(func)
            << __builtin_constant_p(&var) << endl;

        asm("" : : "i"((void*)(plain_foobar_t)(&Foo::foobar)),
                "i"(func),
                "i"(&var));
    }

This compiles without errors at -O0 but prints "000".

So, if your statement is true, don't you think there is something weird going 
on here?

Job



More information about the Gcc-help mailing list