1 #define DECLARE_ARRAY(A) array##A[0x10]
2 #define DECLARE_COUNTER(A) counter##A = 0
3 #define DECLARE_POINTER(A) *pointer##A = array##A + x
4 /* Create a loop that allows post-modification of pointerA, followed by
5    a use of the post-modified address.  */
6 #define BEFORE(A) counter##A += *pointer##A, pointer##A += 3
7 #define AFTER(A) counter##A += pointer##A[x]
8 
9 /* Set up the arrays so that one iteration of the loop sets the counter
10    to 3.0f.  */
11 #define INIT_ARRAY(A) array##A[1] = 1.0f, array##A[5] = 2.0f
12 
13 /* Check that the loop worked correctly for all values.  */
14 #define CHECK_ARRAY(A) exit_code |= (counter##A != 3.0f)
15 
16 /* Having 6 copies triggered the bug for ARM and Thumb.  */
17 #define MANY(A) A (0), A (1), A (2), A (3), A (4), A (5)
18 
19 /* Each addendA should be allocated a register.  */
20 #define INIT_VOLATILE(A) addend##A = vol
21 #define ADD_VOLATILE(A) vol += addend##A
22 
23 /* Having 5 copies triggered the bug for ARM and Thumb.  */
24 #define MANY2(A) A (0), A (1), A (2), A (3), A (4)
25 
26 float MANY (DECLARE_ARRAY);
27 float MANY (DECLARE_COUNTER);
28 
29 volatile int stop = 1;
30 volatile int vol;
31 
32 void __attribute__((noinline))
foo(int x)33 foo (int x)
34 {
35   float MANY (DECLARE_POINTER);
36   int i;
37 
38   do
39     {
40       MANY (BEFORE);
41       MANY (AFTER);
42       /* Create an inner loop that should ensure the code above
43 	 has registers free for reload inheritance.  */
44       {
45 	int MANY2 (INIT_VOLATILE);
46 	for (i = 0; i < 10; i++)
47 	  MANY2 (ADD_VOLATILE);
48       }
49     }
50   while (!stop);
51 }
52 
53 int
main(void)54 main (void)
55 {
56   int exit_code = 0;
57 
58   MANY (INIT_ARRAY);
59   foo (1);
60   MANY (CHECK_ARRAY);
61   return exit_code;
62 }
63