1 /* Shamelessly plugged off gcc/testsuite/gcc.c-torture/execute/pr28982a.c.
2
3 The idea is to induce high register pressure for both int/fp registers
4 so that they spill. By default FMV instructions would be used to stash
5 int reg to a fp reg (and vice-versa) but that could be costlier than
6 spilling to stack. */
7
8 /* { dg-do compile } */
9 /* { dg-require-effective-target hard_float } */
10 /* { dg-options "-march=rv64g -mabi=lp64d -ffast-math" } */
11
12 #define NITER 4
13 #define NVARS 20
14 #define MULTI(X) \
15 X( 0), X( 1), X( 2), X( 3), X( 4), X( 5), X( 6), X( 7), X( 8), X( 9), \
16 X(10), X(11), X(12), X(13), X(14), X(15), X(16), X(17), X(18), X(19)
17
18 #define DECLAREI(INDEX) inc##INDEX = incs[INDEX]
19 #define DECLAREF(INDEX) *ptr##INDEX = ptrs[INDEX], result##INDEX = 5
20 #define LOOP(INDEX) result##INDEX += result##INDEX * (*ptr##INDEX), ptr##INDEX += inc##INDEX
21 #define COPYOUT(INDEX) results[INDEX] = result##INDEX
22
23 double *ptrs[NVARS];
24 double results[NVARS];
25 int incs[NVARS];
26
27 void __attribute__((noinline))
28 foo (int n)
29 {
30 int MULTI (DECLAREI);
31 double MULTI (DECLAREF);
32 while (n--)
33 MULTI (LOOP);
34 MULTI (COPYOUT);
35 }
36
37 double input[NITER * NVARS];
38
39 int
40 main (void)
41 {
42 int i;
43
44 for (i = 0; i < NVARS; i++)
45 ptrs[i] = input + i, incs[i] = i;
46 for (i = 0; i < NITER * NVARS; i++)
47 input[i] = i;
48 foo (NITER);
49 for (i = 0; i < NVARS; i++)
50 if (results[i] != i * NITER * (NITER + 1) / 2)
51 return 1;
52 return 0;
53 }
54
55 /* { dg-final { scan-assembler-not "\tfmv\\.d\\.x\t" } } */
56 /* { dg-final { scan-assembler-not "\tfmv\\.x\\.d\t" } } */