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
26float MANY (DECLARE_ARRAY);
27float MANY (DECLARE_COUNTER);
28
29volatile int stop = 1;
30volatile int vol;
31
32void __attribute__((noinline))
33foo (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
53int
54main (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