[M3devel] integer overflow

Jay K jay.krell at cornell.edu
Tue Jan 12 20:46:21 CET 2010


I'm not against using "hardware traps", if they exist.
I'll have to do a bunch of research as to their existance.
 
 
 
I don't think one should be able to turn this on or off.
I think it should be static per type or interface/library.
 
 
Even so, if it is a runtime configuration, I realize
that the implementation, on a system
without hardware traps, with a processor-specific
flag would look *like*:
 
 
 check for overflow 
 if no overflow, continue on as usual
 if overflow, call out to a function
   that function:
      fetch the thread local
      depending on *that*, raise an exception or continue on 
 
 
I suspect I could easily quickly put in place a portable implementation, and..like *almost* everything else that isn't I/O bound (other than code size issue).
 
 
Hm. Actually another very good approach is probably to have the front end inline most of this logic, like everything except 64bit multiplication on 32bit platform. At first I though that'd be too bloating, but it's actually probably competitive. There is already inlining of the computation of the result, and merely passing three parameters won't be cheap.
 
 
That can also be highly portable, mimicing the algorithms I showed.
 
 
The front end can also do the optimization where overflow isn't necessarily checked for every single operation.
 
 
- Jay



________________________________
> Subject: Re: [M3devel] integer overflow
> From: hosking at cs.purdue.edu
> Date: Tue, 12 Jan 2010 14:30:00 -0500
> CC: m3devel at elegosoft.com
> To: jay.krell at cornell.edu
>
>
>
> On 12 Jan 2010, at 04:23, Jay K wrote:
>
> I propose that integer signed overflow always raise an immediate exception.
> Word.T should either raise an exception for unsigned overflow, or maybe no exceptions at all.
> For folks that want silent wraparound, maybe a separate interface like UnsafeInt.
>
> That is going to pose a performance issue (that many C programmers may baulk at!).
>
> I propose that FloatMode's integer features not be the way forward.
>
> Why not?
>
> There are two implementation strategies.
>
>
> - "check the carry flag"
> A processor-specific thing, but possibly something easy for the gcc backend to do.
> And very likely easy for the integrated backend.
> Probably very efficient.
>
> Yes, doable.
>
> - internally generate function calls for every arithmetic operation
> like how sets are implemented
>
> Very bad for performance. We should rely on the processor support for arithmetic traps or condition variables.
>
>
> Implementing most such functions is easy enough in portable C.
> Or maybe using Modula-3 and interface Word.
>
> Not the best way going forward...
>
> e.g.
> void add(int a, int b, int* c, int* overflow)
> {
> int d = (a + b);
> /* overflow if input signs are equal and output sign is different;
> if input signs are unequal, overflow is not possible
> positive + positive: expect positive, else overflow
> negative + negative: expect negative, else overflow
> positive + negative: overflow not possible */
> *overflow = ((a < 0) == (b < 0) && (d < 0) != (a < 0));
> *c = d;
> }
>
>
> void sub(int a, int b, int* c, int* overflow)
> {
> int d = (a - b);
> /* overflow if input signs are unequal and output sign is different than first input;
> if input signs are equal, overflow is not possible;
> positive - negative: expect positive, overflow if negative
> negative - positive: expect negative, overflow if positive
> positive - positive, negative - negative: overflow not possible */
> *overflow = ((a < 0) != (b < 0) && (d < 0) != (a < 0));
> *c = d;
> }
>
> #include
>
> void mult(int a, int b, int* c, int* overflow)
> {
> /* do operation in higher precision and check if it fits */
> int64 d = (a * (int64)b);
> *c = (int)d;
> *overflow = (d>= INT_MIN && d <= INT_MAX);
> }
>
> /* for interface Word */
> typedef unsigned uint;
>
> void addu(uint a, uint b, uint* c, int* overflow)
> {
> uint d = (a + b);
> /* overflow if output less than either input */
> *overflow = (d < a);
> *c = d;
> }
>
> void subu(uint a, uint b, uint* c, int* overflow)
> {
> uint d = (a - b);
> /* overflow if output greater than first input */
> *overflow = (d> a);
> *c = d;
> }
>
> void multu(uint a, uint b, uint* c, int* overflow)
> {
> /* operate at higher precision and see if it fits */
> uint64 d = (a * (uint64)b);
> *overflow = (d <= UINT_MAX);
> *c = (uint)d;
> }
>
> void multLU(uint64 a, uint64 b, uint64* c, int* overflow)
> {
> /* break it down into smaller operations, not shown, but not difficult */
> }
>
>
> Yes I know this is inefficient, but such is a possible price of portable safety.
>
>
> A hybrid is probably possible if the gcc backend support must be processor specific and we gradually provide the implementations.
>
> FloatMode seems a perfectly reasonable way forward doesn't it? It allows both trap-based and (with compiler support) checked condition code implementations.
>
>
>
> - Jay
>
>
>
>
>
> 		 	   		  


More information about the M3devel mailing list