Re: Type-punning

2007-06-22 Thread Sergei Organov
Chris Lattner <[EMAIL PROTECTED]> writes:

> On Jun 22, 2007, at 1:41 AM, Sergei Organov wrote:
>
>> Herman Geza <[EMAIL PROTECTED]> writes:
>>
>> [...]
>>
>>> What is the correct way to do this:
>>>
>>> void setNaN(float &v) {
>>> reinterpret_cast(v) = 0x7f81;
>>> }
>>>
>>> without a type-prunning warning?  I cannot use the union trick here
>>
>> Why? Won't the following work?
>>
>> void setNaN(float &v) {
>>   union { float f; int i; } t;
>>   t.i = 0x7f81;
>>   v = t.f;
>> }
>
> __builtin_nan isn't sufficient?

... and there a also

 -- Function: double nan (const char *TAGP)
 -- Function: float nanf (const char *TAGP)
 -- Function: long double nanl (const char *TAGP)
 The `nan' function returns a representation of NaN, provided that
 NaN is supported by the target platform.  `nan
 ("N-CHAR-SEQUENCE")' is equivalent to `strtod
 ("NAN(N-CHAR-SEQUENCE)")'.

 The argument TAGP is used in an unspecified manner.  On IEEE 754
 systems, there are many representations of NaN, and TAGP selects
 one.  On other systems it may do nothing.

in GNU libc, and the manual says they are C99 standard functions.

-- Sergei.



Re: Type-punning

2007-06-22 Thread Sergei Organov
Herman Geza <[EMAIL PROTECTED]> writes:

[...]

> What is the correct way to do this:
>
> void setNaN(float &v) {
>   reinterpret_cast(v) = 0x7f81;
> }
>
> without a type-prunning warning?  I cannot use the union trick here

Why? Won't the following work?

void setNaN(float &v) {
  union { float f; int i; } t;
  t.i = 0x7f81;
  v = t.f;
}

-- Sergei.



Re: How to supress a specific kind of ansi-aliasing rules?

2007-06-20 Thread Sergei Organov
"Bokhanko, Andrey S" <[EMAIL PROTECTED]> writes:

> Hi,
>
> As I learned from experience, gcc always assume independence between
> memory references in the following program:
>
> typedef struct {
>     int m1;
>     int m2;
> } S1;
>
> void foo(S1 *p1, S1 *p2) {
>     ... = p1->m1;
>     ... = p2->m2;
> }
>
> ...even if -fno-strict-aliasing (an option disabling ansi-aliasing
> rules) supplied.
>
> I wonder, is there a way to force gcc not to assume independence in
> the example shown above?

A dirty trick using volatile may work:

int foo(S1 *p1, S1 *p2) {
   ((S1 volatile*)p1)->m2 = 10;
   return ((S1 volatile*)p2)->m1;
}

However, provided that GCC guarantees (unlike C standard) that type
punning through unions will work, it seems that GCC should not assume
p1->m2 and p2->m1 never alias:

typedef struct {
  int pad;
  S1 s;
} X;

typedef union {
  S1 s;
  X  x;
} U;

U u;

If it is guaranteed that

int boo() {
  u.s.m2 = 10;
  return u.x.s.m1;
}

works, then

f(&u.s, &u.x.s);

where

int f(S1 *p1, S1 *p2) {
   p1->m2 = 10;
   return p2->m1;
}

should better work the same way, isn't it?

-- Sergei.



Re: Option ordering

2007-05-31 Thread Sergei Organov
"Manuel López-Ibáñez" <[EMAIL PROTECTED]> writes:

> On 30 May 2007 16:12:12 -0700, Ian Lance Taylor <[EMAIL PROTECTED]> wrote:
>> Joe Buck <[EMAIL PROTECTED]> writes:
>>
>> > How about: have -Wall still set warn_strict_overflow
>> > to 1, but to have -Wall -Wstrict-overflow *or* -Wstrict-overflow -Wall
>> > *or* just -Wstrict-overflow set it to 2?  The only change would be
>> > to prevent -Wall from *decreasing* the value.
>>
>> Sure, makes sense.
>>
>> But, consider:
> [snip]
>> If we want to fix this issue, it seems to me we should fix it
>> everywhere.
>
> I was going to submit a formal proposal about options handling (with
> patches). Since this was raised before I had time to think it through
> properly, it may have some flaws.
>
> Two kinds of options: group options (-Wall, -Wextra, -O1, -O2) and
> simple options (-fpeephole, -Waddress, -Wstrict-overflow).
>
> * Group options can only affect default values of simple options. So a
> group option will not change the settings of a explicit simple option
> no matter their order in the command-line. So, "-Wno-address -Wall" ==
> "-Wall -Wno-address"
>
> * Options are evaluated according to their order in the command-line.
> So, "-Wno-address -Waddress" will turn on -Waddress, while "-Waddress
> -Wno-address" will turn it off.
>
> Both rules combined mean that you can do: "-Wall -Wno-all" disabling
> "-Wall" warnings. However, if you do "-Waddress -Wall -Wno-all", you
> still get -Waddress. You will need an explicit -Wno-address to disable
> it.
>
> I think this corresponds to the principle of least surprise. Bad idea?

I like the idea. I'd also suggest that group options won't do anything
else but affecting [default values of] simple options. It means that one
will be able to substitute a set of simple options for a "group option"
without change in behavior (for example, this is not currently the case
for -O,-O1,-O2 options).

-- Sergei.



RFI: g++(classes): inconsistent error messages.

2007-05-30 Thread Sergei Organov
Hello,

The same programming error gives very different diagnostic using member
function and stand-alone function:

$ cat err1.cc
struct C {
  static void f(char const*& p);
};

void b(char* p) {
  C::f(const_cast(p));
}
$ cat err2.cc
extern void f(char const*& p);

void b(char* p) {
  f(const_cast(p));
}
$ g++ -c err1.cc
err1.cc: In function 'void b(char*)':
err1.cc:6: error: no matching function for call to 'C::f(const char*)'
err1.cc:2: note: candidates are: static void C::f(const char*&)
$ g++ -c err2.cc
err2.cc: In function 'void b(char*)':
err2.cc:4: error: invalid initialization of non-const reference of type 'const 
char*&' from a temporary of type 'const char*'
err2.cc:1: error: in passing argument 1 of 'void f(const char*&)'
$

I think the error message for member function is too difficult to
understand, whereas those for stand-alone function is crystal-clear.

$ g++ -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: [...]
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
$

-- Sergei.



RFI: g++(templates): confusing error messages.

2007-05-30 Thread Sergei Organov
Hello,

$ g++ -c err.cc
err.cc:7: error: prototype for 'void C::foo(const int&)' does not match 
any in class 'C'
err.cc:3: error: candidate is: void C::foo(const T&) [with T = int]
err.cc:7: error: template definition of non-template 'void C::foo(const 
int&)'
$

Note that substituting 'int' for 'T' in the only candidate (reported in
error line 2) gives exactly the prototype in error line 1. Yes, the
third error line gives a clue, but the natural way to read error
messages is top-to-bottom, and the first two lines are really
puzzling. It'd be much better if the first two lines of the error
messages were not output at all, I think.

$ cat err.cc
template 
struct C {
  void foo(T const&) {}
};

template 
void C::foo(int const&) {}

$ g++ -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: [...]
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
$

-- Sergei.


Re: Embedded arm-elf-gcc

2007-03-27 Thread Sergei Organov
[EMAIL PROTECTED] writes:
> Hi everybody,
>
> I'm currently working in a company, as embedded developper, which use gnu
> tools. I have a good experience about non gnu compiler tools and i need
> help because the most disavantage of gcc compiler is the almost unexistant
> support for developper.

Really?! My experience is quite opposite.

> I work on an embedded software for an ARM7TDMI target processor (Phillips
> LPC 2214) and i have to locate the software in the target. So here comes
> the link command file (arm.ln) with wich i am supposed to set the memory
> map. The thing is that i can't find any tutorial about link comand file so
> i don't know how to write it manually.
>
> If anybody knows something about link comand file or any book or web site
> reference i would apreciate it a lot.



-- Sergei.


Re: For those using emacs ...

2007-03-13 Thread Sergei Organov
Andrew Walrond <[EMAIL PROTECTED]> writes:
> On Tuesday 13 March 2007 14:32:38 Andrew Haley wrote:
>> ... a little tip.  Add this to your c-mode-hook:
>>
>>(set-variable 'show-trailing-whitespace t)
>>
>> And you'll see all the trailing whitespace.  On my system it appears
>> bright red.
>>
>
> Doesn't seem to work on xemacs :(

That's what I use in XEmacs:

(require 'cc-mode)
(require 'cc-fonts)

(if (find-face 'font-lock-trailing-spaces-face)
()
  (make-face 'font-lock-trailing-spaces-face)
  (add-spec-list-to-specifier (face-property 'font-lock-trailing-spaces-face 
'background) '((global (nil . "grey60") ((grayscale) . "gray80") ((color) . 
"gray"
  (add-spec-list-to-specifier (face-property 'font-lock-trailing-spaces-face 
'reverse) '((global ((tty) . t
  )

(setq
 my-add-keywords
 '(("\\([   ]+$\\)" (1 font-lock-trailing-spaces-face prepend

(setq
 c-font-lock-keywords-1
 (append
  c-font-lock-keywords-1
  my-add-keywords))

(setq
 c-font-lock-keywords-2
 (append
  c-font-lock-keywords-2
  my-add-keywords))

(setq
 c-font-lock-keywords-3
 (append
  c-font-lock-keywords-3
  my-add-keywords))

-- Sergei.


Re: What tells the coding style about whitespaces at end of lines or in *empty* lines ?

2007-03-01 Thread Sergei Organov
Kai Tietz <[EMAIL PROTECTED]> writes:

> Hi,
>
> I noticed while editing gcc files, that there are a lot of *useless* 
> whitespaces at the end of lines or within empty lines, which are getting 
> automatic removed by some *smarter* editors as I am common to use
> *sigh*.

Well, really smart editor (read "the editor") removes trailing
whitespaces only from the lines you've changed.

-- Sergei.



Re: What tells the coding style about whitespaces at end of lines or in *empty* lines ?

2007-03-01 Thread Sergei Organov
[EMAIL PROTECTED] (Richard Kenner) writes:

>> It also forbids embedded horizontal tabs for similar reasons (avoiding
>> junk difs).
>
> That would be a problem with GCC, due to emacs being so heavily used,
> but a similar convention *requiring* horizontal tabs would solve the
> issue in question.


Emacs could be configured either way:

(setq-default indent-tabs-mode nil)

-- Sergei.



Re: False ???noreturn??? function does return warnings

2007-02-07 Thread Sergei Organov
Jan Hubicka <[EMAIL PROTECTED]> writes:
[...]
>> static inline void __attribute__((noreturn)) BUG(void)
>> {
>>  __asm__ __volatile__("trap");
>>  __builtin_unreached();
>
> This is bit dificult to do in general since it introduces new kind of
> control flow construct.  It would be better to express such functions
> explicitely to GCC.

How about

static inline void __attribute__((noreturn)) BUG(void)
{
__asm__ __volatile__ __noreturn__("trap");
}

then ;)

-- Sergei.



Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:

> Sergei Organov writes:
>  > Andrew Haley <[EMAIL PROTECTED]> writes:
>  > > Sergei Organov writes:
>  > >
>  > >  > If we come back to strict aliasing rules, then I will have to refer 
> once
>  > >  > again to already cited place in the standard that says that I'm
>  > >  > permitted to access an object not only through a compatible type, but
>  > >  > also through a structure containing a field of compatible type (and
>  > >  > there is no indication that those field should be the first one in the
>  > >  > structure):
>  > >  > 
>  > >  >An object shall have its stored value accessed only by an lvalue
>  > >  >expression that has one of the following types:
>  > >  >  
>  > >  >   - a type compatible with the effective type of the object,
>  > >  >   [...]
>  > >  >   - an aggregate or union type that includes one of the 
> aforementioned
>  > >  > types among its members (including, recursively, a member of a
>  > >  > subaggregate or contained union)
>  > >  > 
>  > >  > Or are you saying that I don't violate strict aliasing rules, but
>  > >  > instead some other rule from the standard? If so, then how to explain
>  > >  > that GCC stops to "miscompile" the code when I add 
> -fno-strict-aliasing
>  > >  > option?
>  > >
>  > > That's what it's for.  -fno-strict-aliasing exists to support such
>  > > broken code.
>  > 
>  > Could you please give direct answer to the following question:
>  > 
>  > Does the code in question violate strict aliasing rules?
>
> Yes.
>
>  > >  > Not that I insist on sane results of compilation of broken code,
>  > >  > but it seems that GCC thinks it's violation of strict aliasing
>  > >  > rules.
>  > >
>  > > 6.3.2.3 makes it quite clear that this:
>  > >
>  > >H0 h0 = *(H0*)&f;
>  > >
>  > > produces undefined behaviour.
>  > 
>  > What it has to do with strict aliasing rules?
>
> The strict aliasing rues, are, in part, defined by Section 6.3.2.3.

Really? Is it your interpretation, or is it written in the standard
somewhere?

>
>  > Anyway, the only undefined behavior in this section I've found is:
>  > 
>  > "7. A pointer to an object or incomplete type may be converted to a
>  > pointer to a different object or incomplete type. If the resulting
>  > pointer is not correctly aligned(57) for the pointed-to type, the
>  > behavior is undefined."
>  > 
>  > Let's suppose that in my example the alignment requirements for 'float'
>  > and 'H0' types are the same. Then the cited item (7) allows me to
>  > convert float* to/from H0* without invoking of undefined behavior.
>
> This is the relevant language, in whole:
>
> "A pointer to an object or incomplete type may be converted to a
> pointer to a different object or incomplete type. If the resulting
> pointer is not correctly aligned 57) for the pointed-to type, the
> behavior is undefined. Otherwise, when converted back again, the
> result shall compare equal to the original pointer."
>
> Note that you do not have permission to do anything with the converted
> pointer _except_ convert it back to the original pointer; everything
> else is undefined.  You certainly may not use the converted pointer to
> create an lvalue.

Uh, in my reading the above citation says absolutely nothing about what
happens if I *access* something with converted pointer.

Suppose for a moment that your reading is correct. Why the entire
section about strict aliasing is there in the standard then? Just throw
it away and nothing changes. For example, accessing, say, float with an
int* will still be undefined due to your reading of 6.3.2.3?

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:

> Sergei Organov writes:
>  > 
>  > BTW, I've tried once to raise similar aliasing question in
>  > comp.std.c++. The result was that somebody started to talk about
>  > validity of pointers conversions that IMHO has nothing to do with
>  > strict aliasing,
>
> It's the same issue.
>
>  > and the discussion died.
>
> It is relevant to comp.std.c++.  It is not relevant to this list.
> We're now way off-topic, so I'm leaving this discussion.

Well, is adhering of GCC to the C99 standard is indeed off-topic here?
If so, I'd leave the discussion as well. Where should I discuss it then?
Obviously not in comp.std.c++.

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Silvius Rus <[EMAIL PROTECTED]> writes:
[...]
> I am about to submit a patch that implements -Wstrict-aliasing in the
> backend based on flow-sensitive points-to information, which is
> computed by analyzing the entire source of each function.  It is not
> perfect (the problem is undecidable), but it improves in all three
> directions: it checks whether pointers get dereferenced, it detects
> cross-type aliasing in heap (and other multiple statements situations)
> and it works on both C and C++.

That will be really *great* improvement over the current situation when
those warnings are more annoying than helpful in most cases!

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Mike Stump <[EMAIL PROTECTED]> writes:

> On Jan 11, 2007, at 6:30 AM, Sergei Organov wrote:
>> So "h1.f" is not an object? If it is not, it brings us back to the
>> validity of my boo() function from the initial post, for which 2
>> persons
>> (3 including me) thought it's OK:
>
> Would be nice for you to raise the issue directly with the C standards
> committee...  Would be nice to see them improve the wording  in the
> tricky corners.

Actually, this particular issue (the boo() validity) is gone, I think,
as Andrew explained it quite clear, at least for me.

On the other hand, I have no doubts that "h1.f" is an object by
definition: 

"object: region of data storage in the execution environment, the
 contents of which can represent values"

BTW, I've tried once to raise similar aliasing question in
comp.std.c++. The result was that somebody started to talk about
validity of pointers conversions that IMHO has nothing to do with strict
aliasing, and the discussion died.

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:
> Sergei Organov writes:
>
>  > If we come back to strict aliasing rules, then I will have to refer once
>  > again to already cited place in the standard that says that I'm
>  > permitted to access an object not only through a compatible type, but
>  > also through a structure containing a field of compatible type (and
>  > there is no indication that those field should be the first one in the
>  > structure):
>  > 
>  >An object shall have its stored value accessed only by an lvalue
>  >expression that has one of the following types:
>  >  
>  >   - a type compatible with the effective type of the object,
>  >   [...]
>  >   - an aggregate or union type that includes one of the aforementioned
>  > types among its members (including, recursively, a member of a
>  > subaggregate or contained union)
>  > 
>  > Or are you saying that I don't violate strict aliasing rules, but
>  > instead some other rule from the standard? If so, then how to explain
>  > that GCC stops to "miscompile" the code when I add -fno-strict-aliasing
>  > option?
>
> That's what it's for.  -fno-strict-aliasing exists to support such
> broken code.

Could you please give direct answer to the following question:

Does the code in question violate strict aliasing rules?

>
>  > Not that I insist on sane results of compilation of broken code,
>  > but it seems that GCC thinks it's violation of strict aliasing
>  > rules.
>
> 6.3.2.3 makes it quite clear that this:
>
>H0 h0 = *(H0*)&f;
>
> produces undefined behaviour.

What it has to do with strict aliasing rules?

Anyway, the only undefined behavior in this section I've found is:

"7. A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned(57) for the pointed-to type, the
behavior is undefined."

Let's suppose that in my example the alignment requirements for 'float'
and 'H0' types are the same. Then the cited item (7) allows me to
convert float* to/from H0* without invoking of undefined behavior.

Did I miss anything?

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:
> Sergei Organov writes:
>  > Andrew Haley <[EMAIL PROTECTED]> writes:
>  > 
>  > > Sergei Organov writes:
>  > >  > Andrew Haley <[EMAIL PROTECTED]> writes:
>  > >  > 
>  > >  > > Sergei Organov writes:
>  > >  > >  > Ian Lance Taylor <[EMAIL PROTECTED]> writes:
>  > >  > >  > > Sergei Organov <[EMAIL PROTECTED]> writes:
>  > >  > >  > >
>  > >> >  > int float_as_int()
>  > >  > >  > {
>  > >  > >  >   h1.f = 1;
>  > >  > >  >   H0 h0 = *(H0*)&h1.f; // Should be OK? No, it is not?!
>  > >  > >
>  > >  > > I don't think this is OK.  Per C99, you can cast to the element type
>  > >  > > from the struct or vice versa, but you can't cast from one struct 
> type
>  > >  > > to another via the first element.
>  > >  > 
>  > >  > There is no word "casting" in the definition of the aliasing rules in
>  > >  > C99. It talks about accessing of object through an lvalue of 
> compatible
>  > >  > type. In this example I access stored value of object "h1.f"
>  > >
>  > > No, that's not what the code above does.  You're accessing an object
>  > > of type h1 through an lvalue of type h0.  Accessing h1.f would have
>  > > been perfectly OK, but that's not what the code above does.
>  > >
>  > > Look at it again:
>  > >
>  > >H0 h0 = *(H0*)&h1.f;
>  > >
>  > > The LHS of this assignment is of type h0.
>  > 
>  > Yes.
>  > 
>  > > The RHS is an object of effective type h1.  The fact that you're going
>  > > via a pointer cast to its first member is neither here nor there.
>  > 
>  > So "h1.f" is not an object?
>
> This is too silly for words.

Sorry, I don't understand the meaning of this phrase. I thought I have
accessed object "h1.f" of type float. Didn't I? Anyway, this is not that
essential for the discussion, provided accessing bare float variable is
not permitted in your opinion as well.

>  > If it is not, it brings us back to the validity of my boo()
>  > function from the initial post, for which 2 persons (3 including
>  > me) thought it's OK:
>  > 
>  > S s;
>  > int boo()
>  > {
>  >   s.i = 20;
>  >   // Accessing 's' of type 'S' through 'int'. Is it aliasing rules
>  >   // violation?  Maybe yes, but on the other hand this could be
>  >   // considered as accessing 's.i' of type 'int' through 'int' that
>  >   // should be OK from C99 standard POV?
>  >   *(int*)&s = 10;
>  >   return s.i;
>  > }
>  > 
>  > Do you think this one is OK then?
>
> Yes.  The standard says it's OK.

OK, I think I see your point here. Due to the fact that 'S', as
declared, has the first field of type 'int', the 'S' and 'int' types are
compatible, so I simply access stored value of the object 's' through a
compatible type 'int', right?

>  > Anyway, I can rewrite the float_as_int() so that it will access plain
>  > float f:
>  >
>  > typedef struct {
>  >   int i;
>  >   float f;
>  > } H0;
>  >
>  > float f;
>  > int float_as_int()
>  > {
>  >   f = 1;
>  >   H0 h0 = *(H0*)&f; // Should be OK? No, it is not?!
>
> No.  The types have to be compatible.  If f were of type h0, this
> would be OK.  But f is of type float, so it isn't.

I agree the types 'H0' and 'float' are not compatible types. But the
question is not about compatibility of types, -- the question is about
violation (or not) of strict aliasing rules.

If we come back to strict aliasing rules, then I will have to refer once
again to already cited place in the standard that says that I'm
permitted to access an object not only through a compatible type, but
also through a structure containing a field of compatible type (and
there is no indication that those field should be the first one in the
structure):

   An object shall have its stored value accessed only by an lvalue
   expression that has one of the following types:
 
  - a type compatible with the effective type of the object,
  [...]
  - an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union)

Or are you saying that I don't violate strict aliasing rules, but
instead some other rule from the standard? If so, then how to explain
that GCC stops to "miscompile" the code when I add -fno-strict-aliasing
option? Not that I insist on sane results of compilation of broken code,
but it seems that GCC thinks it's violation of strict aliasing rules.

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:

> Sergei Organov writes:
>  > Andrew Haley <[EMAIL PROTECTED]> writes:
>  > 
>  > > Sergei Organov writes:
>  > >  > Ian Lance Taylor <[EMAIL PROTECTED]> writes:
>  > >  > > Sergei Organov <[EMAIL PROTECTED]> writes:
>  > >  > >
>> >  > int float_as_int()
>  > >  > {
>  > >  >   h1.f = 1;
>  > >  >   H0 h0 = *(H0*)&h1.f; // Should be OK? No, it is not?!
>  > >
>  > > I don't think this is OK.  Per C99, you can cast to the element type
>  > > from the struct or vice versa, but you can't cast from one struct type
>  > > to another via the first element.
>  > 
>  > There is no word "casting" in the definition of the aliasing rules in
>  > C99. It talks about accessing of object through an lvalue of compatible
>  > type. In this example I access stored value of object "h1.f"
>
> No, that's not what the code above does.  You're accessing an object
> of type h1 through an lvalue of type h0.  Accessing h1.f would have
> been perfectly OK, but that's not what the code above does.
>
> Look at it again:
>
>H0 h0 = *(H0*)&h1.f;
>
> The LHS of this assignment is of type h0.

Yes.

> The RHS is an object of effective type h1.  The fact that you're going
> via a pointer cast to its first member is neither here nor there.

So "h1.f" is not an object? If it is not, it brings us back to the
validity of my boo() function from the initial post, for which 2 persons
(3 including me) thought it's OK:

S s;
int boo()
{
  s.i = 20;
  // Accessing 's' of type 'S' through 'int'. Is it aliasing rules
  // violation?  Maybe yes, but on the other hand this could be
  // considered as accessing 's.i' of type 'int' through 'int' that
  // should be OK from C99 standard POV?
  *(int*)&s = 10;
  return s.i;
}

Do you think this one is OK then?

Anyway, I can rewrite the float_as_int() so that it will access plain
float f:

float f;
int float_as_int()
{
  h1.f = 1;
  H0 h0 = *(H0*)&f; // Should be OK? No, it is not?!
  return h0.i;
}

Does it change anything in your reasoning?

-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:

> Sergei Organov writes:
>  > Ian Lance Taylor <[EMAIL PROTECTED]> writes:
>  > > Sergei Organov <[EMAIL PROTECTED]> writes:
>  > >
>  > 
>  > >> $ cat alias.c
>  > >> typedef struct { int i; } S;
>  > >> 
>  > >> int i;
>  > >> int foo()
>  > >> {
>  > >>   S const sc = { 10 };
>  > >>   i = 20;
>  > >>   // Accessing object 'i' of type 'int' through 'S' containing 'int'
>  > >>   // field.  Should be OK from C99 standard POV?
>  > >>   *(S*)&i = sc;
>  > >
>  > > C99 says that you can access an object via "an aggregate or union type
>  > > that includes one of the aforementioned [basically, compatible] types
>  > > among its members (including, recursively, a member of a subaggregate
>  > > or contained union)" (section 6.5, paragraph 7).  So on that basis
>  > > this looks OK to me.
>  > 
>  > Yes, it looked OK due to that rule to me too, until I just came up with
>  > the following example in which either I've finally violated some rule,
>  > or GCC miscompiles the code:
>  > 
>  > $cat alias3.c
>  > typedef struct {
>  >   int i;
>  >   float f;
>  > } H0;
>  > 
>  > typedef struct {
>  >   float f;
>  >   int i;
>  > } H1;
>  > 
>  > H1 h1 = { 0, 10 };
>  > 
>  > int float_as_int() __attribute__((noinline));
>  > int float_as_int()
>  > {
>  >   h1.f = 1;
>  >   H0 h0 = *(H0*)&h1.f; // Should be OK? No, it is not?!
>
> I don't think this is OK.  Per C99, you can cast to the element type
> from the struct or vice versa, but you can't cast from one struct type
> to another via the first element.

There is no word "casting" in the definition of the aliasing rules in
C99. It talks about accessing of object through an lvalue of compatible
type. In this example I access stored value of object "h1.f" of type
"float" through an lvalue of type "H0" that is an aggregate type that
includes "float" (a type compatible with the effective type of the
object) among its members. That IMHO should be OK from C99
aliasing rules POV.

> If this were possible, every struct type that started with an int
> would be in a single alias set.

How else should I interpret these C99 wordings (re-citing again):

  An object shall have its stored value accessed only by an lvalue
  expression that has one of the following types: {footnote 73}

 - a type compatible with the effective type of the object,
 [...]
 - an aggregate or union type that includes one of the aforementioned
   types among its members (including, recursively, a member of a
   subaggregate or contained union)


-- Sergei.


Re: Tricky(?) aliasing question.

2007-01-11 Thread Sergei Organov
Ian Lance Taylor <[EMAIL PROTECTED]> writes:
> Sergei Organov <[EMAIL PROTECTED]> writes:
>
>> Below are two example functions foo() and boo(), that I think both are
>> valid from the POV of strict aliasing rules. GCC 4.2 either warns about
>> both (with -Wstrict-aliasing=2) or doesn't warn about any (with
>> -Wstrict-aliasing), and generates the assembly as if the functions don't
>> violate the rules, i.e, both functions return 10.
>
> -Wstrict-aliasing=2 is documented to return false positives.  Actually
> both current versions of -Wstrict-aliasing are pretty bad.

Well, they are indeed bad, but on the other hand I fail to see how to
make them pretty without analyzing the entire source of a program, and
even then the "effective type of an object" could change at run-time :(
Overall, I tend to refrain from blaming gcc too much for weakness of
these warnings.

>> $ cat alias.c
>> typedef struct { int i; } S;
>> 
>> int i;
>> int foo()
>> {
>>   S const sc = { 10 };
>>   i = 20;
>>   // Accessing object 'i' of type 'int' through 'S' containing 'int'
>>   // field.  Should be OK from C99 standard POV?
>>   *(S*)&i = sc;
>
> C99 says that you can access an object via "an aggregate or union type
> that includes one of the aforementioned [basically, compatible] types
> among its members (including, recursively, a member of a subaggregate
> or contained union)" (section 6.5, paragraph 7).  So on that basis
> this looks OK to me.

Yes, it looked OK due to that rule to me too, until I just came up with
the following example in which either I've finally violated some rule,
or GCC miscompiles the code:

$cat alias3.c
typedef struct {
  int i;
  float f;
} H0;

typedef struct {
  float f;
  int i;
} H1;

H1 h1 = { 0, 10 };

int float_as_int() __attribute__((noinline));
int float_as_int()
{
  h1.f = 1;
  H0 h0 = *(H0*)&h1.f; // Should be OK? No, it is not?!
  return h0.i;
}

#include 
int main()
{
  printf("%#x\n", float_as_int());
  printf("%#x\n", float_as_int());
}
$ gcc-4.1 -W -Wstrict-aliasing -O3 alias3.c -o alias3
$ ./alias3
0
0x3f80
$

Any comments?

>
>> S s;
>> int boo()
>> {
>>   s.i = 20;
>>   // Accessing 's' of type 'S' through 'int'. Is it aliasing rules
>>   // violation?  Maybe yes, but on the other hand this could be
>>   // considered as accessing 's.i' of type 'int' through 'int' that
>>   // should be OK from C99 standard POV?
>>   *(int*)&s = 10;
>>   return s.i;
>> }
>
> I think this should also be OK.
>
> The main point is that you are accessing the object with the correct
> type (int).

Yes, I hoped it is so, my doubt was that C99 defines "effective type" of
an object to be "its declared type", and "declared type" of object 's'
is obviously 'S' in this example, but from the standard itself it was
not entirely clear for me that an address in memory could have multiple
effective types associated with it at the same time.

> The use of the struct wrapper does not change that.  If
> you used a struct for which the type of the field was not the same as
> the type of the variable, then this usage would be an aliasing
> violation.

These are good news. In fact this particular function arose from a
doubt if it's possible to achieve C++-alike inheritance in C99 and still
write aliasing-clean code when accessing "derived" object through a
pointer to its "base" type.

Now my next doubt will be if it's possible to implement free() in C99 as
there seems to be no way to "forget" the effective object type of a
dynamically allocated object. ;)

>
> It is possible that somebody else will disagree with me.

Hopefully not, and thank you very much for the answers.

-- Sergei.


Tricky(?) aliasing question.

2007-01-10 Thread Sergei Organov
Hello,

[I apologize for posting this question here, but I've tried to ask at
gcc-help, got no response, and don't actually know where else to ask]

Below are two example functions foo() and boo(), that I think both are
valid from the POV of strict aliasing rules. GCC 4.2 either warns about
both (with -Wstrict-aliasing=2) or doesn't warn about any (with
-Wstrict-aliasing), and generates the assembly as if the functions don't
violate the rules, i.e, both functions return 10.

I'm still in doubt, especially w.r.t. the boo() function. Could anybody
clarify the issue please (see comments in the functions for my own
thoughts)?

$ cat alias.c
typedef struct { int i; } S;

int i;
int foo()
{
  S const sc = { 10 };
  i = 20;
  // Accessing object 'i' of type 'int' through 'S' containing 'int'
  // field.  Should be OK from C99 standard POV?
  *(S*)&i = sc;
  return i;
}

S s;
int boo()
{
  s.i = 20;
  // Accessing 's' of type 'S' through 'int'. Is it aliasing rules
  // violation?  Maybe yes, but on the other hand this could be
  // considered as accessing 's.i' of type 'int' through 'int' that
  // should be OK from C99 standard POV?
  *(int*)&s = 10;
  return s.i;
}

$ gcc-4.2 -O3 -W -Wstrict-aliasing=2 -c alias.c -o alias.o
alias.c: In function 'foo':
alias.c:9: warning: dereferencing type-punned pointer might break 
strict-aliasing rules
alias.c: In function 'boo':
alias.c:19: warning: dereferencing type-punned pointer might break 
strict-aliasing rules

-- Sergei.




Re: 4.2 Project: "@file" support

2005-08-26 Thread Sergei Organov
Ian Lance Taylor  writes:

> Sergei Organov <[EMAIL PROTECTED]> writes:
> 
> > Laurent GUERBY <[EMAIL PROTECTED]> writes:
> > > If we add a library function to handle this we might want to
> > > add a GNU-style argument equivalent like
> > > 
> > > gcc --arguments-from-file=file
> > 
> > AFAIK gcc doesn't support any GNU-style arguments, isn't it?
> 
> Actually, it does, but they aren't widely documented.  For example,
> you can use --language instead of -x, etc.

My bad, -- confused by all that long options using single dash, sorry.

Anyway, my gcc docs only mention:

--target-help
--help
--version
--param NAME=VALUE

-- 
Sergei.



Re: 4.2 Project: "@file" support

2005-08-26 Thread Sergei Organov
Laurent GUERBY <[EMAIL PROTECTED]> writes:
> If we add a library function to handle this we might want to
> add a GNU-style argument equivalent like
> 
> gcc --arguments-from-file=file

AFAIK gcc doesn't support any GNU-style arguments, isn't it?

I'd consider

gcc @file
gcc -@ file
gcc -args-from-file file

-- 
Sergei.



[PATCH] Minor documentation fix.

2005-07-01 Thread Sergei Organov
Index: invoke.texi
===
RCS file: /cvsroot/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.637
diff -u -r1.637 invoke.texi
--- invoke.texi 15 Jun 2005 12:53:41 -  1.637
+++ invoke.texi 1 Jul 2005 14:52:13 -
@@ -5225,7 +5225,7 @@
 
 @item
 @emph{unit-at-a-time} mode removes unreferenced static variables
-and functions are removed.  This may result in undefined references
+and functions.  This may result in undefined references
 when an @code{asm} statement refers directly to variables or functions
 that are otherwise unused.  In that case either the variable/function
 shall be listed as an operand of the @code{asm} statement operand or,



Re: How to replace -O1 with corresponding -f's?

2005-06-24 Thread Sergei Organov
Andrew Pinski <[EMAIL PROTECTED]> writes:

> On Jun 20, 2005, at 11:28 AM, Sergei Organov wrote:
> 
> > Andrew Pinski <[EMAIL PROTECTED]> writes:
> >
> >> On Jun 20, 2005, at 10:54 AM, Sergei Organov wrote:
> >>
> >>> so SYMBOL_FLAG_SMALL (flags 0x6 vs 0x2) is somehow being missed when -O1
> 
> >>
> >>> is turned on. Seems to be something at tree-to-RTX conversion time.
> >>> Constant folding?
> >>
> >> No, it would mean that the target says that this is not a small data.
> >> Also try it with the following code and you will see there is no 
> >> difference:
> 
> >>
> >>  double osvf() { return 314314314; }
> >
> > There is no difference in the sense that here both -O0 and -O1 behave
> > roughly the same. So the problem is with detecting "smallness" for true
> > constants by the target, right?
> 
> I think the bug is in rs6000_elf_in_small_data_p but since I have not
> debuged it yet I don't know for sure.

No, the bug is not there as the function is never called for this
constant. The constant is generated in RTL and thus can't be passed
to this routine expecting tree.

The debugging shows that the constant in question first appears within
small_data_operand(op, mode) in the form:

op = (symbol_ref/u:SI (".LC0") [flags 0x2])
mode = DFmode

without the SYMBOL_FLAG_SMALL set resulting in returning 0 by the
routine.

We can naively try to add code at this point that checks
GET_MODE_SIZE(mode) and return 1 if the size is less than or equal to
the limit for sdata2 (=g_switch_value). However this attempt is not
satisfactory as later this same constant appears at the same place
as:

op = (symbol_ref/u:SI (".LC0") [flags 0x2])
mode = SImode(!)

Now, provided g_switch_value is set to 4 (it's default value is 8), we
would return 0 in the first case and 1 in the second case for the same
constant! The resulting assembly is weird.

The latter appearance of the constant with mode=SImode is due to call to
memory_address(DFMode, op) that calls force_reg(Pmode(=SImode), op)

#0  small_data_operand (op=0x401e2730, mode=SImode)
at ../../../gcc/gcc/config/rs6000/rs6000.c:2358
#1  0x08704fb0 in rs6000_emit_move (dest=0x401e2740, source=0x401e2730, 
mode=SImode) at ../../../gcc/gcc/config/rs6000/rs6000.c:3720
#2  0x0852cfb8 in gen_movsi (operand0=0x401e2740, operand1=0x401e2730)
at ../../../gcc/gcc/config/rs6000/rs6000.md:7410
#3  0x08430c3c in emit_move_insn_1 (x=0x401e2740, y=0x401e2730)
at ../../../gcc/gcc/expr.c:3086
#4  0x08431020 in emit_move_insn (x=0x401e2740, y=0x401e2730)
at ../../../gcc/gcc/expr.c:3164
#5  0x08410891 in force_reg (mode=SImode, x=0x401e2730)
at ../../../gcc/gcc/explow.c:607
#6  0x0841029b in memory_address (mode=DFmode, x=0x401e2730)
at ../../../gcc/gcc/explow.c:409


At this stage I gave up trying to solve this puzzle. Any ideas how to
fix that?

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-21 Thread Sergei Organov
Michael Meissner <[EMAIL PROTECTED]> writes:

> On Mon, Jun 20, 2005 at 07:57:17PM +0400, Sergei Organov wrote:
> > Andrew Pinski <[EMAIL PROTECTED]> writes:
> > 
> > > On Jun 20, 2005, at 11:28 AM, Sergei Organov wrote:
> > > 
> > > > Andrew Pinski <[EMAIL PROTECTED]> writes:
> > > >
> > > >> On Jun 20, 2005, at 10:54 AM, Sergei Organov wrote:
> > > >>
> > > >>> so SYMBOL_FLAG_SMALL (flags 0x6 vs 0x2) is somehow being missed when 
> > > >>> -O1
> > > 
> > > >>
> > > >>> is turned on. Seems to be something at tree-to-RTX conversion time.
> > > >>> Constant folding?
> > > >>
> > > >> No, it would mean that the target says that this is not a small data.
> > > >> Also try it with the following code and you will see there is no
> > > >> difference:
> > > 
> > > >>
> > > >>  double osvf() { return 314314314; }
> > > >
> > > > There is no difference in the sense that here both -O0 and -O1 behave
> > > > roughly the same. So the problem is with detecting "smallness" for true
> > > > constants by the target, right?
> > > 
> > > I think the bug is in rs6000_elf_in_small_data_p but since I have not
> > > debuged it yet I don't know for sure.
> > > 
> > > Could you file a bug?  This is a target bug.
> > 
> > Yeah, and I've reported it rather long ago against gcc-3.3 (PR 9571).
> > That time there were 3 problems reported in the PR of which only the
> > first one seems to be fixed (or are the rest just re-appeared in 4.0?).
> > 
> > I think PR 9571 is in fact regression with respect to 2.95.x despite the
> > [wrong] comments:
> > 
> > --- Additional Comment #5 From Franz Sirl  2003-06-17 15:31  [reply] 
> > ---
> > 
> > r0 is used as a pointer to sdata2, this is a bug, it should be r2. And
> > since only r2 is initialized in the ecrt*.o files, how can this work?
> > Besides that, even if you initialize r0 manually, it is practically
> > clobbered in about every function.
> 
> It's been a long time since I've hacked the PowerPC, but IIRC the instruction
> set, a base register of '0' does not mean r0, but instead it means use 0 as 
> the
> base address.  Every place that uses a base register should use the register
> class 'b' (BASE_REGS) instead of 'r' (GENERAL_REGS), which excludes r0 from
> being considered.
> 
> Under the 32-bit eABI calling sequence, you have three small data areas:
> 
> The small data area that r2 points to (.sdata/.sbss).
> 
> The small data area that r13 points to (.sdata2/.sbss2).
> 
> The small data area centered around location 0 (ie, small positive
> addresses, and the most negative addresses). I don't recall that we
> had special sections for this, since for many embedded apps, they
> couldn't allocate to those addresses.
> 
> For these relocations, you should use R_PPC_EMB_SDA21, which the
> linker will fill in both the offset and the appropriate base register
> into the instruction.

Exactly, and that's what gcc actually and correctly does. My comment in
the PR exactly matches what you've said above:

 --- Additional Comment #7 From Sergei Organov  2003-10-14 14:42  [reply] 
---

 > r0 is used as a pointer to sdata2, this is a bug, it should be r2.

 No, the %r0 you see is fake. In the object file it's a special
 relocatable symbol that is resolved to either 2 (r2) or 13 (r13) by the
 linker depending on actual output section the symbol refers to, so
 there is no bug here.


IMHO, the assembly output is just somewhat misleading mentioning %r0 in
the place in question, -- it better should be just 0 I think as
[EMAIL PROTECTED](0) would create less confusion than [EMAIL PROTECTED](%r0).

On the other hand, I must admit the PR with item 1 (wrong section
attribute) fixed is not a regression anymore. I apologize, but I've
compared gcc-3.x/4.x with *patched* version of gcc-2.95.x that I've
hacked to force it to put double/float constants into .sdata2 section.
Now I've applied my hack to gcc-4.1.0 and get similar results, though
the patch is indeed a hack and is not satisfactory.

I think there is a fundamental problem that compiler-generated symbols
referring to constants are generated too late, at RTL level, and thus
aren't handled by the small section logic working on the tree level. Any
thoughts?

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Andrew Pinski <[EMAIL PROTECTED]> writes:

> On Jun 20, 2005, at 11:28 AM, Sergei Organov wrote:
> 
> > Andrew Pinski <[EMAIL PROTECTED]> writes:
> >
> >> On Jun 20, 2005, at 10:54 AM, Sergei Organov wrote:
> >>
> >>> so SYMBOL_FLAG_SMALL (flags 0x6 vs 0x2) is somehow being missed when -O1
> 
> >>
> >>> is turned on. Seems to be something at tree-to-RTX conversion time.
> >>> Constant folding?
> >>
> >> No, it would mean that the target says that this is not a small data.
> >> Also try it with the following code and you will see there is no
> >> difference:
> 
> >>
> >>  double osvf() { return 314314314; }
> >
> > There is no difference in the sense that here both -O0 and -O1 behave
> > roughly the same. So the problem is with detecting "smallness" for true
> > constants by the target, right?
> 
> I think the bug is in rs6000_elf_in_small_data_p but since I have not
> debuged it yet I don't know for sure.

Well, provided that:

void
default_elf_select_rtx_section (enum machine_mode mode, rtx x,
unsigned HOST_WIDE_INT align)
{
  /* ??? Handle small data here somehow.  */
  ...
}

is still there at varasm.c:5330, I don't think it's a target bug :(

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Andrew Pinski <[EMAIL PROTECTED]> writes:

> On Jun 20, 2005, at 11:28 AM, Sergei Organov wrote:
> 
> > Andrew Pinski <[EMAIL PROTECTED]> writes:
> >
> >> On Jun 20, 2005, at 10:54 AM, Sergei Organov wrote:
> >>
> >>> so SYMBOL_FLAG_SMALL (flags 0x6 vs 0x2) is somehow being missed when -O1
> 
> >>
> >>> is turned on. Seems to be something at tree-to-RTX conversion time.
> >>> Constant folding?
> >>
> >> No, it would mean that the target says that this is not a small data.
> >> Also try it with the following code and you will see there is no
> >> difference:
> 
> >>
> >>  double osvf() { return 314314314; }
> >
> > There is no difference in the sense that here both -O0 and -O1 behave
> > roughly the same. So the problem is with detecting "smallness" for true
> > constants by the target, right?
> 
> I think the bug is in rs6000_elf_in_small_data_p but since I have not
> debuged it yet I don't know for sure.
> 
> Could you file a bug?  This is a target bug.

Yeah, and I've reported it rather long ago against gcc-3.3 (PR 9571).
That time there were 3 problems reported in the PR of which only the
first one seems to be fixed (or are the rest just re-appeared in 4.0?).

I think PR 9571 is in fact regression with respect to 2.95.x despite the
[wrong] comments:

--- Additional Comment #5 From Franz Sirl  2003-06-17 15:31  [reply] ---

r0 is used as a pointer to sdata2, this is a bug, it should be r2. And
since only r2 is initialized in the ecrt*.o files, how can this work?
Besides that, even if you initialize r0 manually, it is practically
clobbered in about every function.
 

--- Additional Comment #6 From Mark Mitchell  2003-07-20 00:52  [reply] 
---

Based on Franz's comments, this bug is not really a regression at all.
I've therefore removed the regression tags.

that I've tried to explain in my comment #7.

I don't think I need to file yet another PR in this situation, right?

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Andrew Pinski <[EMAIL PROTECTED]> writes:

> On Jun 20, 2005, at 10:54 AM, Sergei Organov wrote:
> 
> > so SYMBOL_FLAG_SMALL (flags 0x6 vs 0x2) is somehow being missed when -O1
> 
> > is turned on. Seems to be something at tree-to-RTX conversion time.
> > Constant folding?
> 
> No, it would mean that the target says that this is not a small data.
> Also try it with the following code and you will see there is no difference:
> 
>  double osvf() { return 314314314; }

There is no difference in the sense that here both -O0 and -O1 behave
roughly the same. So the problem is with detecting "smallness" for true
constants by the target, right?

But even then, if I fix that, there still will be a problem that for
given platform there doesn't seem to be a single reason to replace

double const osv = 314314314;
double osvf() { return osv; }

with

double const osv = 314314314;
double const .LC0 = 314314314;
double osvf() { return .LCO; }

where .LCO is compiler-generated symbol. And the latter does have
something to do with const folding, doesn't it?

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Andrew Pinski <[EMAIL PROTECTED]> writes:

> On Jun 20, 2005, at 9:38 AM, Sergei Organov wrote:
>
> > 2. The resulting assembly is different from what I get with -O1 and
> >doesn't contain the mis-optimization I'm trying to debug though it
> >doesn't seem to have anything to do with loops. For reference, the
> >code I'm trying to compile is:
> >
> > extern double const osv;
> > double const osv = 314314314;
> > double osvf() { return osv; }
>
> I don't see anything wrong with what it gives for -O0 and -O2.

Well, it's on PowerPC with its small constant data sections.

With -O1 I get:

.globl osv
.section.sdata2,"a",@progbits
.align 3
.type   osv, @object
.size   osv, 8
osv:
.long   1102232590
.long   1241513984
.section.rodata.cst8,"aM",@progbits,8
.align 3
.LC0:
.long   1102232590
.long   1241513984
.section".text"
.align 2
.globl osvf
.type   osvf, @function
osvf:
lis %r9,[EMAIL PROTECTED]  # tmp121,
lfd %f1,[EMAIL PROTECTED](%r9)  #, 
blr  #

With -O0 and a bunch of -f's from -O1 I get:

.globl osv
.section.sdata2,"a",@progbits
.align 3
.type   osv, @object
.size   osv, 8
osv:
.long   1102232590
.long   1241513984
.section".text"
.align 2
.globl osvf
.type   osvf, @function
osvf:
.LFB2:
lfd %f0,[EMAIL PROTECTED](%r0)   # osv, D.1144
fmr %f1,%f0  # , 
blr  #

While the ideal code would be:

...
osvf:
.LFB2:
lfd %f1,[EMAIL PROTECTED](%r0)   # osv, D.1144
blr  #

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Andrew Pinski <[EMAIL PROTECTED]> writes:

> On Jun 20, 2005, at 10:04 AM, Andrew Haley wrote:
> >> How one finds out what optimization pass misbehaves?
> >
> > Look at the dumps.  If you use the gcc option -da you'll get a full
> > set of RTL dump files.
>
> And -fdump-tree-all for the tree dumps.

The last const.c.t69.final_cleanup is exactly the same in both cases and
doesn't have any useful information anyway:


;; Function osvf (osvf)

osvf ()
{
:
  return 3.14314314e+8;

}

In fact, at the RTL level the difference is that non-optimized code


(insn 8 6 9 1 (set (reg:DF 118 [ D.1144 ])
(mem/u/i:DF (symbol_ref:SI ("osv") [flags 0x6] 
(nil))

(insn 9 8 10 1 (set (reg:DF 119 [  ])
(reg:DF 118 [ D.1144 ])) -1 (nil)
(nil))

gets replaced with "optimized" one:

(insn 10 9 11 1 (set (reg:SI 121)
(high:SI (symbol_ref/u:SI ("*.LC0") [flags 0x2]))) -1 (nil)
(nil))

(insn 11 10 12 1 (set (reg/f:SI 120)
(lo_sum:SI (reg:SI 121)
(symbol_ref/u:SI ("*.LC0") [flags 0x2]))) -1 (nil)
(expr_list:REG_EQUAL (symbol_ref/u:SI ("*.LC0") [flags 0x2])
(nil)))

(insn 12 11 13 1 (set (reg:DF 118 [  ])
(mem/u/i:DF (reg/f:SI 120) [0 S8 A64])) -1 (nil)
(expr_list:REG_EQUAL (const_double:DF 3.14314314e+8 [0x0.95e0725p+29])
(nil)))

so SYMBOL_FLAG_SMALL (flags 0x6 vs 0x2) is somehow being missed when -O1
is turned on. Seems to be something at tree-to-RTX conversion time.
Constant folding?

-- 
Sergei.



Re: How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Andrew Haley <[EMAIL PROTECTED]> writes:

> Sergei Organov writes:
>  > Hi,
>  > 
>  > Using gcc compiled from gcc-4_0-branch, in an attempt to see which
>  > particular optimization option makes my test case to be mis-optimized, I
>  > try to replace -O1 (which toggles on the problem) with corresponding set
>  > of -fxxx optimization options.
> 
> In general you can't do this.  You can turn some optimization passes
> off, though.

Sigh :(

> 
>  > How one finds out what optimization pass misbehaves?
> 
> Look at the dumps.  If you use the gcc option -da you'll get a full
> set of RTL dump files.

I'm afraid that it's one of the tree optimization passes as
const.cc.00.expand is already [mis]optimized the way I don't like.

-- 
Sergei.



How to replace -O1 with corresponding -f's?

2005-06-20 Thread Sergei Organov
Hi,

Using gcc compiled from gcc-4_0-branch, in an attempt to see which
particular optimization option makes my test case to be mis-optimized, I
try to replace -O1 (which toggles on the problem) with corresponding set
of -fxxx optimization options. I first compile my code like this:

gcc -v -save-temps -fverbose-asm -O1 -o const.o -c const.c

then merge the cc1 command that gcc invokes to compile the preprocessed
source (as gcc doesn't seem to pass some of -f forward to cc1) with the
entire list of options taken from resulting const.s file (found at the
line " # options enabled: ..." and further), and compile using this.

In the resulting const.s file there are 2 problems:

1. "options enabled" output almost matches those from the initial (-O1)
   invocation, but -floop-optimize is missing though it does exist in
   the "options passed" output.

2. The resulting assembly is different from what I get with -O1 and
   doesn't contain the mis-optimization I'm trying to debug though it
   doesn't seem to have anything to do with loops. For reference, the
   code I'm trying to compile is:

extern double const osv;
double const osv = 314314314;
double osvf() { return osv; }

Am I doing something stupid or what? How one finds out what optimization
pass misbehaves?

-- 
Sergei.



Re: PowerPC small data sections.

2005-06-20 Thread Sergei Organov
Mike Stump <[EMAIL PROTECTED]> writes:
> On Friday, June 17, 2005, at 07:13  AM, Sergei Organov wrote:
> > The first thing I'd like to get some advice on is which codebase do I
> > use, gcc-4_0-branch?
> 
> No, mainline.  If it doesn't work there, is won't work anyplace else.  :-(
> Once you get it working there, you can then ask for the patches, if safe
> enough, to go into the release branches.

OK, thanks.

-- 
Sergei.



PowerPC small data sections.

2005-06-17 Thread Sergei Organov
Hi,

The gcc-2.95.x seems to be the last GCC version that have usable support
for small data sections (.sdata & .sdata2) on PowerPC, see PRs 9571,
17337(resolved), and finally 21571.

As my embedded project heavily relies on the advantages of using small
data sections, it makes it impossible for me to switch to a newer gcc
version. Each time I try, the result is yet another PR. I'd like to
invest some of my time to investigate the problem in more details to try
to resolve the issue.

The first thing I'd like to get some advice on is which codebase do I
use, gcc-4_0-branch?

In addition, any comments, thoughts, and info about current status would
be greatly appreciated.

-- 
Sergei.