[M3devel] redundant range checks?

Jay K jay.krell at cornell.edu
Thu Dec 6 09:26:33 CET 2012


m3-libs/m3core/src/fingerprint/Poly.i3

  Int32  = [-16_7fffffff-1 .. 16_7fffffff];
  T      = ARRAY [0..1] OF Int32;

m3-libs/m3core/src/fingerprint/Poly.m3


PROCEDURE Sum (READONLY p, q: T) : T =
  VAR r : T;
  BEGIN
    r[0] := Word.Xor (p[0], q[0]); line 48
    r[1] := Word.Xor (p[1], q[1]);
    RETURN r;
  END Sum;



                    -----LINE 48  -----
    load         v.5 0 Addr Addr
    load_indirect     0 Int.32 Int.64
    load         v.6 0 Addr Addr
    load_indirect     0 Int.32 Int.64
    xor         Word.64
...
 check_range     Int.64 -2147483648 2147483647 1


if((((INT64)(((UINT64)(((UINT64)(((INT64)(*((INT32*)(p_L_7))))))
^((UINT64)(((INT64)(*((INT32*)(q_L_8))))))))))
<((INT64)(M3_INT64(-2147483648))))

||

(((INT64)(M3_INT64(2147483647)))
<
((INT64)(((UINT64)(((UINT64)(((INT64)(*((INT32*)(p_L_7))))))^((UINT64)(((INT64)(*((INT32*)(q_L_8))))))))))))M_Poly_L_4_CRASH(1537);


Poly.mc.c:325: warning: comparison is always false due to limited range of data type



or, like:



typedef long long INT64;
typedef unsigned long long UINT64;
typedef int INT32;
#define MAXINT32 2147483647
#define MININT32 (-2147483648)
void ReportFault(void);


#define AssignINT64ToINT32(a, b) \
if (((INT64)(b)) < MININT32 || ((INT64)(b)) > MAXINT32) ReportFault(); \
  a = (INT32)(INT64)(b); \

INT32 Sum(INT32 p, INT32 q)
{
 INT32 r;
 AssignINT64ToINT32(r, ((UINT64)(INT64)*(INT32*)&p) ^ ((UINT64)(INT64)*(INT32*)&q));
 // or this
 AssignINT64ToINT32(r, ((UINT64)(INT64)p) ^ ((UINT64)(INT64)q));
 // or heck even this
 AssignINT64ToINT32(r, p ^ q);
 return r;
}


the operands get widened from 32bits to 64bits, operation done,
then range checked, and assigned back to 32bits.


The range check is redundant.
It is subtle. 32bit operands sign extended to 64bits will succeed the range check.
The upper bits will all be set or clear.
If you xor them, the upper bits will still be either all set or all clear, which succeeds the range check.


The C compiler notices it and warns.


I'd like to avoid warnings.


I think the frontend could catch this, easily enough.


Thoughts?

I'm just about in position to fix this in the C backend.
But it'd be cool if the frontend did some cheap analysis always.



 - Jay 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20121206/e144be71/attachment-0001.html>


More information about the M3devel mailing list