Re: Compile error when not using -ftree-ter

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

 



On 08/19/2010 11:33 AM, Job Noorman wrote:
> 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.
> 
> Hi Andrew,

Hi,

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

It's not syntactically invalid, it's semantically invalid.  It's
always semantically invalid.

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

Hmm, this seems to generalize "i" to symbolic constants, but not to
expressions that yield addresses.

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

This is a fundamental part of language definition: a translator is not
required to do anything in particular with a program that has
undefined behaviour.  One of the options a translator has is to do
what the user expected.

Sometimes an operand that is not a constant may work with the "i"
constraint.  This is because a pass in gcc propagated a constant
through an expression.  gcc is allowed to do this.  However, gcc is
not required to do this.

Finally, does the "g" constraint really not work for you with a recent
gcc?

Andrew.


[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