aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/arm/lob6.c
blob: 17b6124295e8ae9e1cb57e41fa43a954b3390eec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* Check that GCC generates Armv8.1-M low over head loop instructions
   with some less trivial loops and the result is correct.  */
/* { dg-do run } */
/* { dg-require-effective-target arm_v8_1_lob_ok } */
/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */
/* { dg-options "-march=armv8.1-m.main -mthumb -O3 --save-temps" } */
#include <stdlib.h>
#include "lob.h"

#define TEST_CODE1				\
  {						\
    for (int i = 0; i < N; i++)			\
      {						\
	a[i] = i;				\
	b[i] = i * 2;				\
						\
	for (int k = 0; k < N; k++)		\
	  {					\
	    MAYBE_LOB;				\
	    c[k] = k / 2;			\
	  }					\
	c[i] = a[i] - b[i];			\
      }						\
  }

#define TEST_CODE2				\
  {						\
    for (int i = 0; i < N / 2; i++)		\
      {						\
	MAYBE_LOB;				\
	if (c[i] % 2 == 0)			\
	  break;				\
	a[i]++;					\
	b[i]++;					\
      }						\
  }

int a1[N];
int b1[N];
int c1[N];

int a2[N];
int b2[N];
int c2[N];

#define MAYBE_LOB
void __attribute__((noinline))
loop1 (int *a, int *b, int *c)
  TEST_CODE1;

void __attribute__((noinline))
loop2 (int *a, int *b, int *c)
  TEST_CODE2;

#undef MAYBE_LOB
#define MAYBE_LOB NO_LOB

void
ref1 (int *a, int *b, int *c)
  TEST_CODE1;

void
ref2 (int *a, int *b, int *c)
  TEST_CODE2;

void
check (void)
{
  for (int i = 0; i < N; i++)
    {
      NO_LOB;
      if (a1[i] != a2[i]
	  && b1[i] != b2[i]
	  && c1[i] != c2[i])
	abort ();
    }
}

int
main (void)
{
  reset_data (a1, b1, c1);
  reset_data (a2, b2, c2);
  loop1 (a1, b1, c1);
  ref1 (a2, b2, c2);
  check ();

  reset_data (a1, b1, c1);
  reset_data (a2, b2, c2);
  loop2 (a1, b1, c1);
  ref2 (a2, b2, c2);
  check ();

  return 0;
}
/* { dg-final { scan-assembler-times {dls\s\S*,\s\S*} 1 } } */
/* { dg-final { scan-assembler-times {le\slr,\s\S*} 1 } } */