Re: Compile error when not using -ftree-ter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Andrew Haley <aph at redhat dot com> wrote:
> On 08/18/2010 05:06 PM, Job Noorman wrote:
> > On Tuesday 17 August 2010 22:53:10 you wrote:
> >> Job Noorman <jobnoorman@xxxxxxxxx> writes:
> >>> When I use the "r" constraint, it indeed works and GCC emits the
> >>> following
> >>>
> >>> code:
> >>>     movl $_ZN3Foo6foobarEv, %eax
> >>>     push %eax;
> >>>
> >>> What I find strange about this is that GCC has converted
> >>> "(plain_foobar_t)&Foo::foobar" in a constant value ($_ZN3Foo6foobarEv)
> >>> without using optimizations. So why can't it do the same when using the
> >>> "i" constraint?
> >>
> >> It can, as you can see, but when not optimizing it won't do it reliably
> >> before it determines asm constraints.
> >>
> >> In other words, there is no simple answer to your question, it's just
> >> happenstance of how the compiler is written.  It's not a bug, because
> >> the compiler only promises to reduce an address to match the "i"
> >> constraint when optimizing.
> 
> >> ... it's just happenstance of how the compiler is written."
> > 
> > No offense but I think that's a non-argument. You could use that to reject 
> > any bug report.
> > 
> >> It's not a bug, because the compiler only promises to reduce an address 
to
> >> match the "i" constraint when optimizing.
> > 
> > Where does it promise that? If that's true, why does something like this 
> > always work?:
> > 
> >     typedef return_type function(args);
> >     function func;
> > 
> >     int main()
> >     {
> >         asm("push %0" : : "i"((function*)&func));
> >     }
> > 
> 
> Pretty obviously, replacing "movl $_ZN3Foo6foobarEv, %eax; push %rax"
> with "push $_ZN3Foo6foobarEv" is an optimization.  It's resonable to
> say that gcc only does this optimization if you ask for it.  gcc does
> a few constant folding operations anyway, so sometimes this may work,
> but I wouldn't rely on it.
> 
> > I'm still convinced there is some kind of bug here and I think it has 
> > something to do with how GCC handles its PMF to function pointer 
conversion 
> > extension internally.
> 
> And nothing that a gcc developer says will convince you otherwise?
> 
> If I were you, I'd use
> 
>     void test()
>     {
>         asm("push %0;"
>             :
>             : "g"((plain_foobar_t)&Foo::foobar));
>     }
> 
> Andrew.

Hi Andrew,

> 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.

> 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".

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 might be convinced that this is not a bug.

Job


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux