1 
2 /* Test of origin tracking through floating point code and in the case
3    where there are large amounts of uninitialised data floating
4    around.  This program creates 3 matrices of 2300x2300 doubles,
5    makes one value in them undefined, does arithmetic, and tests the
6    result, which is then undefined.
7 
8    This also tests the secondary otag cache (ocacheL2), since the
9    amount of uninitialised data is somewhat over 43MB and it appears
10    that quite a lot of non-zero-otag lines are pushed into ocacheL2.
11 
12    This program needs to be compiled with -O.
13 */
14 
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include "../memcheck.h"
19 
20 
alloc_square_array(int nArr)21 double** alloc_square_array ( int nArr )
22 {
23   int i;
24   double** vec;
25   assert(nArr >= 1);
26   vec = malloc(nArr * sizeof(double*));
27   assert(vec);
28   for (i = 0; i < nArr; i++) {
29     vec[i] = malloc(nArr * sizeof(double));
30     assert(vec);
31   }
32   return vec;
33 }
34 
do3x3smooth(double ** arr,int nArr)35 double** do3x3smooth ( double** arr, int nArr )
36 {
37   int i, j;
38   double** out;
39   assert(nArr >= 3);
40   out = alloc_square_array(nArr - 2);
41   assert(out);
42   for (i = 1; i < nArr-1; i++) {
43     for (j = 1; j < nArr-1; j++) {
44       double s =   arr[i-1][j-1] + arr[i-1][j  ] + arr[i-1][j+1]
45                  + arr[i  ][j-1] + arr[i  ][j  ] + arr[i  ][j+1]
46                  + arr[i+1][j-1] + arr[i+1][j  ] + arr[i+1][j+1];
47       out[i-1][j-1] = s / 9.0;
48     }
49   }
50   return out;
51 }
52 
sum(double ** arr,int nArr)53 double sum ( double** arr, int nArr )
54 {
55   int i, j;
56   double s = 0.0;
57   assert(nArr >= 1);
58   for (i = 0; i < nArr; i++) {
59     for (j = 0; j < nArr; j++) {
60       s += arr[i][j];
61     }
62   }
63   return s;
64 }
65 
setup_arr(double ** arr,int nArr)66 void setup_arr ( /*OUT*/double** arr, int nArr )
67 {
68   int i, j;
69   assert(nArr >= 1);
70   for (i = 0; i < nArr; i++) {
71     for (j = 0; j < nArr; j++) {
72       arr[i][j] = (double)(i * j);
73       if (i == nArr/2 && j == nArr/2) {
74          unsigned char* p = (unsigned char*)&arr[i][j];
75          (void) VALGRIND_MAKE_MEM_UNDEFINED(p, 1);
76       }
77     }
78   }
79 }
80 
main(void)81 int main ( void )
82 {
83   int nArr = 2300;
84   int ri;
85   double r, **arr, **arr2, **arr3;
86   arr = alloc_square_array(nArr);
87   setup_arr( arr, nArr );
88   arr2 = do3x3smooth( arr, nArr );
89   arr3 = do3x3smooth( arr2, nArr-2 );
90   r = sum( arr3, nArr-4 );
91   /* Convert answer to int before testing it, so as to
92      guarantee there's only one conditional branch. */
93   if (0) fprintf(stderr, "r = %g\n", r );
94   r /= 10000.0;
95   ri = (int)r;
96   if (0) fprintf(stderr, "ri = %d\n", ri);
97   if (ri == 696565111) {
98      fprintf(stderr, "Test succeeded.\n");
99   } else {
100      fprintf(stderr, "Test FAILED !\n");
101      assert(0);
102   }
103   return 0;
104 }
105