public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 15:35 Richard Kenner
  2003-02-13 15:57 ` Roger Sayle
  0 siblings, 1 reply; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 15:35 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    I completely disagree, and so do GCC's patch reviewers.  The behaviour
    of a program with optimization should always be the same as its behaviour
    without optimization.

Another example of where that's false:

We've said many times that a program that contains an expression of
the form

	i = i++;

need not produce the same results in different optimization levels.

You seem to be trying to divide the set of things that make a program
undefined into two sets: those that we must preserve over optimization
and those that we need not.  What criteria do you propose to use to choose,
for each example of undefined behavior, which of those cases we apply?

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-16 16:17 Robert Dewar
  2003-02-18  6:41 ` Segher Boessenkool
  0 siblings, 1 reply; 102+ messages in thread
From: Robert Dewar @ 2003-02-16 16:17 UTC (permalink / raw)
  To: dewar, segher; +Cc: bosch, gcc-patches, gcc, kenner

> Yes, but won't such a program always give a compile-time
> warning like "this branch will never be executed" or
> "unreachable code deleted"?  Can you give an example
> where the compiler will delete a branch but where it
> is not able to diagnose it did?


Actually it is often very difficult to track down actions in a complex
optimization circuit that is manipulating some intermediate form to give
clear diagnostics, because the sequence of logic that arrives at a decision
may be arbitrarily complex, and it may be difficult for instance o tell
if the code in question is a direct consequence of the original source
code, or some code generated by some other optimization. Certainly there
is no requirement for a compiler to give such warnings.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-14 15:26 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-14 15:26 UTC (permalink / raw)
  To: dewar, kenner; +Cc: gcc-patches, gcc

> I guess the question is what exactly "back propagate" mean in practice. I
> think most people agree that doing so *explicitly* is a bad idea and doesn't
> produce any optimizations of correct programs in practice.

It is in fact almost impossible to precisely define, but in the realm of
optimizers, you have code that makes logical deductions from a set of 
assumptions. For example, if you see 

  if a > 3 then
	

You create an implicit assertion that a is greater than 3 at the point of the
then statements. Subsequent actions assume this and e.g. remove a division
by zero check.

There is really no distinction between "forward" and "backward" propagation
at this level of logical operation. Many important optimizations, for example
removing dead code and dead assignments result from what you might informally
regard as "back propagation":

   x := 3;
   ... (x not mentioned)
   x := 4;

The information from the second assignment back propagates to the x := 3
point and causes it to be deleted.

If you introduce as an assumption that the optimizer can take into account that
certain behavior is undefined, then what informally we regard as "improper
back propagation" is hard to avoid. The meaning of two statements:

   s1;
   s2;

is represted semantically as the composition of two functions on states,
and if s2(s) yields undefined for all s, then most certainly s2(s1(s)) yields
undefined, and there goes the back propagation.

So it is indeed important to keep this under control. I actually think the
idea of using the Ada bounded error semantics for uninitialized variables
is exactly the right one. The Ada definition was carefully crafted with two
ideas in mind:

1. Don't cause any significant degradation of the code
2. Avoid nasty "back propagation" of undefined

And also of course, at the programmer's semantic level, we have a definition
of uninitialized behavior that corresponds intuitively to what the programmer
who does not know about weird optimizers would expect.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-14 14:58 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-14 14:58 UTC (permalink / raw)
  To: dewar; +Cc: gcc-patches, gcc

    However, once you allow an optimizer to back propagate the assumption
    that a program has a defined behavior, things may get surprising, and
    as you can see from my earlier message, there is a not too far fetched
    scenario in which a well meaning implementation could in fact end up
    deleting the system disk unintentionally as an indirect consequence of
    an uninitialized variable.

I guess the question is what exactly "back propagate" mean in practice. I
think most people agree that doing so *explicitly* is a bad idea and doesn't
produce any optimizations of correct programs in practice.

The issue is in something like my A * 2 / 2 example in C.  Technically
speaking, you can view optimizing this to A as doing that back-propagation,
but an alternate way to look at it is to redefine the arithmetic with
"undefined" as a value and allow the simplification to be valid if
certain well-defined behavior on that arithmetic is preserved.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-14 14:24 Robert Dewar
  2003-02-16  5:52 ` Segher Boessenkool
  0 siblings, 1 reply; 102+ messages in thread
From: Robert Dewar @ 2003-02-14 14:24 UTC (permalink / raw)
  To: bosch, kenner; +Cc: gcc-patches, gcc

> 
>     This is indeed the reason that Ada 95 introduced bounded errors,
>     where the language allows the implementation to pick any value
>     in the base range of the type or raise an exception.
> 
> I think that's intuitively what most of us mean by "undefined" in this
> discussion but you are quite right that it's good to formalize it better.

Yes, and that intuition is dangerously misleading, because it gives a false
sense of comfort. If I tell you that an uninitialized variable could cause
the system disk to be deleted, you will tend to react "yeah, yeah, we know
this language lawyer stuff, but in practice, no implementor is going to
do something that silly". However, once you allow an optimizer to back
propagate the assumption that a program has a defined behavior, things
may get surprising, and as you can see from my earlier message, there is
a not too far fetched scenario in which a well meaning implementation could
in fact end up deleting the system disk unintentionally as an indirect
consequence of an uninitialized variable.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-14 14:14 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-14 14:14 UTC (permalink / raw)
  To: bosch; +Cc: gcc-patches, gcc

    This is indeed the reason that Ada 95 introduced bounded errors,
    where the language allows the implementation to pick any value
    in the base range of the type or raise an exception.

I think that's intuitively what most of us mean by "undefined" in this
discussion but you are quite right that it's good to formalize it better.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-14  5:57 Robert Dewar
  2003-02-14  6:43 ` Chris Lattner
  2003-02-14 18:14 ` Joe Buck
  0 siblings, 2 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-14  5:57 UTC (permalink / raw)
  To: dewar, sabre; +Cc: gcc-patches, gcc

> That's not really true... a straight-forward way to "fix" this problem is
> to simply initialize all variables to, for example, zero.  In almost all
> cases, optimization would DCE this initialization anyway, so there is
> really very little cost.  The only major cases I can think of that the
> initialization would not be killed would be something like this:

Hmm, I am quite dubious about the claim that this would have zero overhead
in practice, but if true, then I agree, it should be done.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-14  4:48 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-14  4:48 UTC (permalink / raw)
  To: dewar, neil; +Cc: gcc-patches, gcc

> This thread is impossible two follow, what with not one but two
> arch-villains, Robert Dewar and Richard Kenner contributing to it.

Sorry I tried switching and something went wrong, and then other things
over took stuff. I will try again!

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 21:14 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 21:14 UTC (permalink / raw)
  To: kenner, roger; +Cc: gcc-patches, gcc

> The issue is GCC's internal representations, which shouldn't suffer
> from the same issue of poorly defined languages.  Hence, if CSE sees
> "x = i++; i = x" it had better understand exactly what "i = i++" means
> at the RTL-level.  One might hope that the interpretation of RTL and
> TREEs are independent of the source language and target architecture.

Most certainly the meaning should be specified and exact, but also it can
most certainly be non-deterministic with several possbile outcomes.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 21:01 Chris Lattner
  2003-02-14  8:17 ` Marcel Cox
  0 siblings, 1 reply; 102+ messages in thread
From: Chris Lattner @ 2003-02-13 21:01 UTC (permalink / raw)
  To: dewar; +Cc: gcc, gcc-patches


>> Are you really claiming that a program with an uninitialized variable
>> must be compiled in such a way that it produces the same result
>> independent of optimization?

> No one claims this, but it is useful to observe that the problem of
> uninitialized variables causing different results in unoptimized and
> optimized code is a severe one in practice that causes a lot of grief,
> especially in large systems where tracking down the difference can be a
> lot of work. However, in this case, the cure would be very expensive,
> and the gain from "optimizing" (which typically comes from putting stuff
> in registers) is so great as to be worth the pain.

That's not really true... a straight-forward way to "fix" this problem is
to simply initialize all variables to, for example, zero.  In almost all
cases, optimization would DCE this initialization anyway, so there is
really very little cost.  The only major cases I can think of that the
initialization would not be killed would be something like this:

int X;

if (predicate) {
...
  X = 6;
}

...

if (predicate) {
  = X;
}

In this case, X is always initialized before being used, but it's unlikely
an optimizer would know that, and thus it would have to insert an
initialization for X on the first !predicate path...

Despite the small cost, this could be a real help to some people...

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 20:41 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 20:41 UTC (permalink / raw)
  To: kenner, roger; +Cc: gcc-patches, gcc

> Are you really claiming that a program with an uninitialized variable
> must be compiled in such a way that it produces the same result independent
> of optimization?

No one claims this, but it is useful to observe that the problem of uninitialized
variables causing different results in unoptimized and optimized code is a severe
one in practice that causes a lot of grief, especially in large systems where
tracking down the difference can be a lot of work. However, in this case, the
cure would be very expensive, and the gain from "optimizing" (which typically
comes from putting stuff in registers) is so great as to be worth the pain.

But we really should note in this discussion that any case in which optimization
changes results is potentailly a degradation of the usability of the compiler.
You have to be careful, on a case-by-case basis, that the gains from the
corresponding optimization are worth the pain.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 20:35 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 20:35 UTC (permalink / raw)
  To: dewar, fjh; +Cc: gcc-patches, gcc, roger, rth

> > Certainly for + and -, Java can get what it wants
> 
> Including gdb support?
> If Java maps signed types to unsigned, how is gdb going to know about it?

As someone pointed out you can certainly do conversions, and that is annoying
but will preserve gdb semantics.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 20:14 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 20:14 UTC (permalink / raw)
  To: dewar, fjh; +Cc: gcc-patches, gcc, roger, rth

> Including gdb support?
> If Java maps signed types to unsigned, how is gdb going to know about it?

Indeed the debugging information should represent these as signed, and it is
indeed problematic that gdb debugging information in gcc is tied so closely
to the types used for code generation purposes (we have bumped our noses
on this in Ada many times). I think this just goes again to show that the
issue of operation semantics should not depend on the type alone, but rather
on the operation, as was previously suggested in this thread.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:59 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:59 UTC (permalink / raw)
  To: dewar, jbuck; +Cc: gcc-patches, gcc, kenner, roger

>  One of the
> possibilities is to generate a two's complement addition.  Another
> is to generate a trapping addition.

OK, so you are using "two's complement addition" to imply wrapping. That's
potentially confusing terminology, I would suggest that we always say wrapping
when we mean it.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:42 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:42 UTC (permalink / raw)
  To: aph, dewar; +Cc: gcc

> and clearly this is in incorrect in many cases, for example int->long
> conversion and indeed anything that involves integer operands of
> different sizes.

Sorry for confusing things, but yes, of course the interpretation of values
is as signed values where it matters, but for addition, subtraction and
multiplication it does not, and the proper way of representing these in the
tree to get tyhe right results is to use unsigned oeprations.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:31 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:31 UTC (permalink / raw)
  To: dewar, fjh; +Cc: aph, gcc

> There are operations other than plus and minus.

Yes, in particular division needs special casing, but overflow is not an issue
there for single length division, or at least not so much of an issue.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:22 Robert Dewar
  2003-02-13 19:47 ` Joe Buck
  0 siblings, 1 reply; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:22 UTC (permalink / raw)
  To: jbuck, roger; +Cc: gcc-patches, gcc, kenner

> But undefined overflow is a superset of two's complement semantics

I don't understand the terminology here. Are you using "two's comlement" to
imply unsigned wrap around, i.e. throw away carry and ignore overflow. If so,
that's a bit confusing, since it presupposes the conclusion. The issue with
twos complement signed arithmetic is preciesely what happens on overflow (that's
the only thing that distinguishes it from unsigned).

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:19 Robert Dewar
  2003-02-13 19:56 ` Fergus Henderson
  0 siblings, 1 reply; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:19 UTC (permalink / raw)
  To: roger, rth; +Cc: gcc-patches, gcc

> This is why we should have proper annotations on the tree nodes
> so that Java can get the results that they need.

Certainly for + and -, Java can get what it wants

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:10 Robert Dewar
  2003-02-14  8:00 ` Fergus Henderson
  0 siblings, 1 reply; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:10 UTC (permalink / raw)
  To: fjh, jbuck; +Cc: gcc-patches, gcc, kenner, roger

> Suppose we denote the three variants of "+" as follows:
> 
>       +undef          undefined behaviour on overflow
>       +wrap           wraps on overflow
>       +trap           traps on overflow

I still don't see how +wrap differs from an unsigned addition, so it seems
simply confusing to have it around explicitly.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:08 Robert Dewar
  2003-02-13 19:23 ` Fergus Henderson
  2003-02-13 19:32 ` Andrew Haley
  0 siblings, 2 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 19:08 UTC (permalink / raw)
  To: aph, dewar; +Cc: gcc

> What do you mean by this, exactly?  Java is defied as having signed
> two's complement arithmetic.

At the implementation level, the difference between signed and unsigned
arithmetic (for operations like plus and minus) is in whether overflow
is an issue or not (look for example at the MIPS). The issue of "2-s complement"
just has to do with how you interpret a bit pattern (i.e. whether all 1's is
a big number of minus one). If you have wrap around semantics, then, regardless
of how you choose to interpret the bit patterns, the appropriate run-time
representation of add/subtract operations is to do unsigned adds with no 
carry around (and no signed overflow detection).

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 19:03 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 19:03 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    There are more bugs in this area, than I can hope to address.

But you have pointed out correctly that it does need to be addressed
at some point.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:58 Robert Dewar
  2003-02-13 19:04 ` Andrew Haley
  2003-02-13 20:55 ` Neil Booth
  0 siblings, 2 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 18:58 UTC (permalink / raw)
  To: aph, roger; +Cc: gcc-patches, gcc, rth

> Java requires strict 32-bit two's complement arithmetic for its ints,
> and PLUS_EXPR isn't guaranteed to do that.  We could, of course,
> generate something like
> 
>    uint((ulong)a + (ulong)b)
> 
> which would be well defined. 

it seems clear that Java should be using unsigned arithmetic for all operations,
since that is the way Java is defined.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:54 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 18:54 UTC (permalink / raw)
  To: fjh, roger; +Cc: gcc-patches, gcc, kenner

> The fact that the behaviour of overflow is undefined in C, C++ and Ada
> does not mean that "overflow cannot occur".  Quite clearly overflows do
> occur, and the optimizers are paralyzed by the semantics in this event.

Since this quote is being repeated many times, it is perhaps worth
emphasizing that overflow *is* defined in Ada, and indeed the most
important thing that Ada needs from gcc is efficient code for arithmetic
operations that trap on overflow :-)

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:53 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 18:53 UTC (permalink / raw)
  To: kenner, roger; +Cc: gcc-patches, gcc

> So what?  There's no requirement that erroneous programs produce the
> same result in different versions of GCC.


There is also no requirement that the compile speed not be multiplied by
100 in the next version of GCC. The standard is not the only source of
criteria for a usable compiler, and a compiler that takes too much advantage
of undefined behavior may be a menace even if it is conforming.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:50 Robert Dewar
  0 siblings, 0 replies; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 18:50 UTC (permalink / raw)
  To: kenner, roger; +Cc: gcc-patches, gcc

> The one I mentioned: (a*2)/2

Notice that in Ada this is handled at the language level without any notino
of undefinedness in the semantics (indeed in Ada, integer overflow is usually
very well defined to raise an exception).

However, the intermediate value a*2 will be computed in the base integer type,
and base integer types are unconstrained, which means that it is fine to have
out of range values temporarily if the result is "correct" mathematically.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:33 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 18:33 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    How?  Any new optimization that we introduce that takes advantage
    of the undefinedness will both produce different results from the
    current versions of GCC, 

So what?  There's no requirement that erroneous programs produce the
same result in different versions of GCC.

    and will break the Java front-end.

No, because *those* nodes would be marked as *not* being undefined on
overflow.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:29 Richard Kenner
  2003-02-13 18:56 ` Roger Sayle
  0 siblings, 1 reply; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 18:29 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    > Nope.  Lots of places in the optimizer assume that overflow signed
    > integers are undefined.  

    I'm prepared to drop this entire argument if you can find me just one

The one I mentioned: (a*2)/2.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:29 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 18:29 UTC (permalink / raw)
  To: Richard.Earnshaw; +Cc: gcc-patches, gcc

    I think there is major confusion here between "undefined" in the 
    language-lawyer concept and "ambiguous" about what our internal nodes mean.

    Yes, we want to take advantage of the former.  But we need to try and 
    avoid the latter.

Strongly agreed.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 18:21 Robert Dewar
  2003-02-13 22:04 ` Florian Weimer
  0 siblings, 1 reply; 102+ messages in thread
From: Robert Dewar @ 2003-02-13 18:21 UTC (permalink / raw)
  To: kenner, roger; +Cc: gcc-patches, gcc

I very much dislike the idea of the optimizer making assumptions based
on undefined semantics. It's a very dangerous path to tread. Consider
the following Ada 83 code (you can get equivalent Ada 95 programs, but
Ada 95 has restricted erroneous behavior as much as possible to minimize
this kind of concern). 

In Ada 83, referencing an undefined variable is erroneous

   put_line ("system disk reformat requested: enter pass word");
   declare
	Attempts : Natural; -- count of attempts at pass word entry

   begin
        loop
           Get (password);
           if password = masterpassword then
	 	erase_system_disk;
                exit;
	   else
	      Attempts := Attempts + 1;
              if Attempts > 4 then raise Hacker_Alert; end if;
	      put_line ("bad pass word, reenter");
	   end if;
	end loop;
   end;

Now the optimizer appears to be allowed to do the following.

If password /= masterpassword, then the program execution is errroneous.
That means the program can do anything it likes, e.g. call erase_system_disk.
Great, I can omit as useless the test password = masterpassword and still
provide a fully conformant as-if implementation.

It's really hard from a formal point of view to stop compilers doing this
sort of thing. 

In the case of overflow, sure, I know you can construct examples where the
optimizer is helped but:

a) I very much doubt that it helps significantly in real life
b) I am afraid of optimizers running amok as in the above example

A single program malfunctioning in an unboundedly curious manner which
is difficult to detect or fix balances against a lot of very minor speedups
and probably these days, the curious malfunction wins unless there is a
really big, demonstratable gain.


^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 17:54 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 17:54 UTC (permalink / raw)
  To: jbuck; +Cc: gcc-patches, gcc

    I doubt it; the reason is that the particular assumption that addition
    and multiplication follow the natural two's complement rules gives us
    an algebraic ring, which makes many transformations possible.  Any other
    assumption would introduce an irregularity that has to be tested for in
    each transformation.

I'm thinking of (A * 2) / 2.  This is A only if you are allowed to
assume that an overflow of the multiplication is undefined.

There are numerous cases in loop optimizations too.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 16:21 Richard Kenner
  2003-02-13 17:59 ` Roger Sayle
  0 siblings, 1 reply; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 16:21 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    At the GCC internal level there should be no such thing as undefined
    behaviour, this is a front-end concept.  

I disagree.  As I said, it's quite valuable to be able to know that we
don't care, for optimization purposes, if an overflow has or has
not occurred.

    As for trap on overflow, that is currently supported and honored in
    the middle-end, by flag_trapv and flag_non_call_exceptions.

I'm talking about *per expression*.

    You may have noticed that my original patch, was a simple
    documentation patch that just described what GCC currently does, and
    what is assumed at several points in the code.

Nope.  Lots of places in the optimizer assume that overflow signed
integers are undefined.  Your proposed documentation doesn't mention that.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 16:09 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 16:09 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    Ada for example, performs all its own real arithmetic because Ada
    specifies constraints on precision that aren't documented for GCC's
    tree-nodes.  

No, that's true only for constants.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 16:09 Richard Kenner
  2003-02-13 17:49 ` Joe Buck
  0 siblings, 1 reply; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 16:09 UTC (permalink / raw)
  To: jbuck; +Cc: gcc-patches, gcc

    In C, it is frequently the case that defining the overflow behavior of
    signed integer in this way makes more optimizations possible.  For one
    thing, it makes addition and multiplication associative.  Without such
    an assumption, you can't turn (a+b)+c into a+(b+c), because the overflows
    might be different.

True, but there are an equal number of simplification that can only be done
if you are allowed to assume that overflow is undefined.

Perhaps an approach might be to say that "we know what overflow
actually does for this operation, but if it occurs, it's undefined
semantics".  That's what we actually *implement* right now and would
give the best of both worlds.  Then there would be a bit that says that,
in this particular operation, the overflow is *not* undefined.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 15:58 Richard Kenner
  2003-02-13 16:10 ` Roger Sayle
  0 siblings, 1 reply; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 15:58 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    The issue is GCC's internal representations, which shouldn't suffer
    from the same issue of poorly defined languages.  Hence, if CSE sees
    "x = i++; i = x" it had better understand exactly what "i = i++" means
    at the RTL-level.  One might hope that the interpretation of RTL and
    TREEs are independent of the source language and target architecture.

I agree.  Which is why I'm in favor of adding flags to tree nodes that say
whether the operation:

(a) has undefined behavior
(b) has defined overflow behavior, documented for the tree node in question
(c) will trap on overflow.

Then each language sets the appropriate bit for each expression it
makes (possibly defaulting to those from the types) and we do our best
to honor them.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 15:52 Richard Kenner
  2003-02-13 16:03 ` Roger Sayle
  0 siblings, 1 reply; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 15:52 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    > Are you really claiming that a program with an uninitialized variable
    > must be compiled in such a way that it produces the same result
    > independent of optimization?

    You got me.  Naturally there are limits.  GCC can't claim that two runs
    of the same executable with an uninitialized variable produce the same
    result.

So then to rephrase the question I asked in my last question, what are those
limits, where do we document them, and how do we decide what they are?

I'm more familiar with the Ada standard than that for C99 and C++ and
there are dozens of places where they describe things that are undefined.
Are you proposing that we look at each of those, choose (by what criteria?)
whether we guarantee that a program that has that particular undefined 
behavior is preserved over optimization, and document our choice somewhere?
And that we do the same for C, C++, Fortran and Java?

If not, precisely *what* are you proposing: I don't understand.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 15:45 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 15:45 UTC (permalink / raw)
  To: gdr; +Cc: gcc-patches, gcc

    I believe this generalization is drifting away from the initial
    specific topic.

Sure, but for what I consider a good reason: if we're going to treat
*certain* undefined behavior differently than others we need to:

(1) Be explicit that we are doing that; and
(2) Precisely characterize which behaviors are in each set.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 15:33 Richard Kenner
  2003-02-13 15:36 ` Gabriel Dos Reis
  2003-02-13 15:45 ` Roger Sayle
  0 siblings, 2 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 15:33 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    I completely disagree, and so do GCC's patch reviewers.  The behaviour
    of a program with optimization should always be the same as its behaviour
    without optimization.

Only for correct programs.

Are you really claiming that a program with an uninitialized variable
must be compiled in such a way that it produces the same result independent
of optimization?

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re: [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 15:23 Richard Kenner
  0 siblings, 0 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 15:23 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    This is a common misunderstanding.  The c-tree.texi not only documents
    the tree nodes that are specific to C and C++, but also those that are
    shared amongst all the front-ends.  

That suggests to me that the file has the wrong name.

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 14:57 Richard Kenner
  2003-02-13 14:58 ` Gabriel Dos Reis
  2003-02-13 15:26 ` Roger Sayle
  0 siblings, 2 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 14:57 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    The fact that the behaviour of overflow is undefined in C, C++ and Ada
    does not mean that "overflow cannot occur".  Quite clearly overflows do
    occur, and the optimizers are paralyzed by the semantics in this event.

I think that's backwards.  If program in C, C++, or Ada generates an
overflow, that program is undefined.  That means the optimizer can do
anything it wants to the program, which, in turn, means that the optimizer
can assume that overflow *does not* occur, and that allows a lot more
optimizations.

    Any optimization that concerns overflow will assume a behaviour upon
    overflow.  If the behaviour assumed is anything other than the
    two's-complement overflow, then the optimization is "unsafe" and will
    produce different results to not performing the optimization, as the
    RTL will use two's-complement overflow at run-time.  

Only for erroneous programs, where it's perfectly acceptable to do that.

    I'm not opposed to either adding a bit to the tree structure, or
    introducing a new tree node for trapping arithmetic.  However the
    existing infrastructure is currently sufficient for all of GCC's
    front-ends and back-ends without modification.  Being pragmatic I
    can't see how adding a bit would help, if we never set or never test
    for it.

Well, obviously we have to test for it!

^ permalink raw reply	[flat|nested] 102+ messages in thread
* Re:  [PATCH] Document arithmetic overflow semantics
@ 2003-02-13 13:24 Richard Kenner
  2003-02-13 14:44 ` Roger Sayle
                   ` (2 more replies)
  0 siblings, 3 replies; 102+ messages in thread
From: Richard Kenner @ 2003-02-13 13:24 UTC (permalink / raw)
  To: roger; +Cc: gcc-patches, gcc

    + For integral types, negation is the same as subtraction from zero.
    + Because the range of two's-complement values in not symmetric, the
    + negation of the maximum negative integer results in the same maximum
    + negative number.

I *really* don't like defining the tree operations as having this overflow
behavior.    I have three major problems with it:

(1) It removes the potential of optimizations that assume such overflow cannot
    occur in languages where it is undefined (C, C++, and Ada).
(2) It represents an implementation difficulty and perhaps cost on machines
    where this behavior is not present (for example, where it traps).
(3) It does not allow representing trapping arithmetic in the three.

My suggestion is to use a bit in either the type (my preference) or the
operation to say whether overflow is defined or not.  There can be a bit in
the operation to require that it trap if it overflow.

^ permalink raw reply	[flat|nested] 102+ messages in thread

end of thread, other threads:[~2003-02-18 18:10 UTC | newest]

Thread overview: 102+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-13 15:35 [PATCH] Document arithmetic overflow semantics Richard Kenner
2003-02-13 15:57 ` Roger Sayle
  -- strict thread matches above, loose matches on Subject: below --
2003-02-16 16:17 Robert Dewar
2003-02-18  6:41 ` Segher Boessenkool
2003-02-18  6:49   ` Fergus Henderson
2003-02-18 18:13   ` Joe Buck
2003-02-14 15:26 Robert Dewar
2003-02-14 14:58 Richard Kenner
2003-02-14 14:24 Robert Dewar
2003-02-16  5:52 ` Segher Boessenkool
2003-02-14 14:14 Richard Kenner
2003-02-14  5:57 Robert Dewar
2003-02-14  6:43 ` Chris Lattner
2003-02-14 18:14 ` Joe Buck
2003-02-14  4:48 Robert Dewar
2003-02-13 21:14 Robert Dewar
2003-02-13 21:01 Chris Lattner
2003-02-14  8:17 ` Marcel Cox
2003-02-14 18:23   ` Joe Buck
2003-02-14 18:51     ` Nathan Sidwell
2003-02-13 20:41 Robert Dewar
2003-02-13 20:35 Robert Dewar
2003-02-13 20:14 Robert Dewar
2003-02-13 19:59 Robert Dewar
2003-02-13 19:42 Robert Dewar
2003-02-13 19:31 Robert Dewar
2003-02-13 19:22 Robert Dewar
2003-02-13 19:47 ` Joe Buck
2003-02-13 19:19 Robert Dewar
2003-02-13 19:56 ` Fergus Henderson
2003-02-13 19:10 Robert Dewar
2003-02-14  8:00 ` Fergus Henderson
2003-02-14  8:44   ` Fergus Henderson
2003-02-14 17:29     ` Michael S. Zick
2003-02-13 19:08 Robert Dewar
2003-02-13 19:23 ` Fergus Henderson
2003-02-13 19:32 ` Andrew Haley
2003-02-13 19:03 Richard Kenner
2003-02-13 18:58 Robert Dewar
2003-02-13 19:04 ` Andrew Haley
2003-02-13 20:55 ` Neil Booth
2003-02-13 21:10   ` Gabriel Dos Reis
2003-02-14  4:45     ` Phil Edwards
2003-02-14  8:46     ` Diego Novillo
2003-02-13 18:54 Robert Dewar
2003-02-13 18:53 Robert Dewar
2003-02-13 18:50 Robert Dewar
2003-02-13 18:33 Richard Kenner
2003-02-13 18:29 Richard Kenner
2003-02-13 18:56 ` Roger Sayle
2003-02-13 19:07   ` Joe Buck
2003-02-13 18:29 Richard Kenner
2003-02-13 18:21 Robert Dewar
2003-02-13 22:04 ` Florian Weimer
2003-02-13 23:03   ` Joseph S. Myers
2003-02-15 20:52     ` Mark Hahn
2003-02-15 21:15       ` Neil Booth
2003-02-13 17:54 Richard Kenner
2003-02-13 16:21 Richard Kenner
2003-02-13 17:59 ` Roger Sayle
2003-02-13 16:09 Richard Kenner
2003-02-13 16:09 Richard Kenner
2003-02-13 17:49 ` Joe Buck
2003-02-13 15:58 Richard Kenner
2003-02-13 16:10 ` Roger Sayle
2003-02-13 17:05   ` Joseph S. Myers
2003-02-13 18:05   ` Richard Henderson
2003-02-13 18:15     ` Richard Earnshaw
2003-02-13 19:03       ` Richard Henderson
2003-02-13 18:25     ` Roger Sayle
2003-02-13 18:44       ` Andrew Haley
2003-02-13 19:06       ` Richard Henderson
2003-02-13 15:52 Richard Kenner
2003-02-13 16:03 ` Roger Sayle
2003-02-13 15:45 Richard Kenner
2003-02-13 15:33 Richard Kenner
2003-02-13 15:36 ` Gabriel Dos Reis
2003-02-13 15:45 ` Roger Sayle
2003-02-13 15:23 Richard Kenner
2003-02-13 14:57 Richard Kenner
2003-02-13 14:58 ` Gabriel Dos Reis
2003-02-13 15:26 ` Roger Sayle
2003-02-13 16:42   ` Joseph S. Myers
2003-02-13 17:58   ` Richard Henderson
2003-02-13 18:16     ` Roger Sayle
2003-02-13 19:46   ` Erik Trulsson
2003-02-13 13:24 Richard Kenner
2003-02-13 14:44 ` Roger Sayle
2003-02-13 18:39   ` Fergus Henderson
2003-02-13 19:05     ` Joe Buck
2003-02-14 13:52       ` Richard Earnshaw
2003-02-13 22:37     ` Richard Henderson
2003-02-13 22:54       ` Roger Sayle
2003-02-13 22:56       ` David Carlton
2003-02-14  0:11     ` Nathan Sidwell
2003-02-14  7:20       ` Fergus Henderson
2003-02-14 13:58         ` Geert Bosch
2003-02-14 18:59           ` Joseph S. Myers
2003-02-14 19:37         ` Joseph S. Myers
2003-02-13 16:04 ` Joe Buck
2003-02-13 16:22   ` Richard Earnshaw
2003-02-13 21:47 ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).