static char SccsId[] = "@(#)test3.c 1.2 12/19/95"; /* * Author: Christopher Glaeser cdg@nullstone.com * Nullstone Corporation http://www.nullstone.com */ /* * * Consider the following code fragment. * * if (aa == 2) aa = 0; * if (bb == 2) bb = 0; * if (aa != bb) ... * * To improve the performance of the SPEC eqntott benchmark, * some compilers move the compare of aa and bb before the * compares with the constants, as in: * * if (aa == bb) ... * if (aa == 2) aa = 0; * if (bb == 2) bb = 0; * if (aa != bb) ... * * While this transformation is legal in the eqntott benchmark, * some compilers apply this transformation to similar programs * in a way that is not correct. If the types of aa and bb are * changed to short and unsigned short respectively, and if aa * and bb are assigned the constant -1 instead of 0, the above * described transformation is not legal. The test program * below will fail if this incorrect transformation is performed. * */ #include #define SIZE 100 int size = SIZE; short s1[SIZE]; short s2[SIZE]; typedef struct Struct { short *p1; short *p2; struct Struct *next; long fill1; short fill2; short fill3; } Struct; Struct x; Struct y; Struct *px = &x; Struct *py = &y; volatile int i = 1; void init () { x.p1 = s1; y.p1 = s2; s1[0] = 2; s2[0] = 2; return; } int main() { if (i) init (); if (! cmppt (&px, &py)) { printf ("ERROR: The compiler generated incorrect code.\n"); exit (1); } else { printf ("Test passed.\n"); exit (0); } } int cmppt (a, b) Struct *a[], *b[]; { register int i; register short aa; register unsigned short bb; /* On the first iteration, aa and bb are equal to 2. Therefore, both are set to -1. However, aa is short, and bb is unsigned short. So, even though they are both set to the same value, they will not compare equal, and the loop will be exited on the first iteration. The return value should be 1 or -1 for K&R or ANSI. Some compilers will move the expression (aa != bb) before the expressions (aa == 2) and (bb == 2). This is not a correct transformation for this loop, and the test will fail if this transformation is performed. */ for (i = 0; i < size; i++) { aa = a[0]->p1[i]; bb = b[0]->p1[i]; if (aa == 2) aa = -1; if (bb == 2) bb = -1; if (aa != bb) if (aa < bb) return -1; else return 1; } /* We should not get here */ return 0; }