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 } } */
|