aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/powerpc/pr97019.c
blob: 9bc8ee3daa32628f06b746efcb0f4f102dc4ff49 (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
/* This issue can only exist on little-endian P8 targets, since
   the built-in functions vec_ld/vec_st can use lxvd2x/stxvd2x
   (P8 big-endian) or lxv/stxv (P9 and later) for some cases,
   those rldicr instructions fed to them are necessary.  */
/* { dg-do compile } */
/* { dg-options "-O2 -mdejagnu-cpu=power8 -mvsx" } */
/* { dg-require-effective-target powerpc_vsx } */
/* { dg-require-effective-target le } */

/* Test there are no useless instructions "rldicr x,y,0,59"
   to align the addresses for lvx/stvx.  */

extern int a, b, c;
extern vector unsigned long long ev5, ev6, ev7, ev8;
extern int dummy (vector unsigned long long);

int test_vec_ld(unsigned char *pe) {

  vector unsigned long long v1, v2, v3, v4, v9;
  vector unsigned long long v5 = ev5;
  vector unsigned long long v6 = ev6;
  vector unsigned long long v7 = ev7;
  vector unsigned long long v8 = ev8;

  unsigned char *e = pe;

  do {
    if (a) {
      v1 = __builtin_vec_ld(16, (unsigned long long *)e);
      v2 = __builtin_vec_ld(32, (unsigned long long *)e);
      v3 = __builtin_vec_ld(48, (unsigned long long *)e);
      e = e + 8;
      for (int i = 0; i < a; i++) {
        v4 = v5;
        v5 = __builtin_crypto_vpmsumd(v1, v6);
        v6 = __builtin_crypto_vpmsumd(v2, v7);
        v7 = __builtin_crypto_vpmsumd(v3, v8);
        e = e + 8;
      }
    }
    v5 = __builtin_vec_ld(16, (unsigned long long *)e);
    v6 = __builtin_vec_ld(32, (unsigned long long *)e);
    v7 = __builtin_vec_ld(48, (unsigned long long *)e);
    if (c)
      b = 1;
  } while (b);

  return dummy(v4);
}

int test_vec_st(unsigned char *pe) {

  vector unsigned long long v1, v2, v3, v4;
  vector unsigned long long v5 = ev5;
  vector unsigned long long v6 = ev6;
  vector unsigned long long v7 = ev7;
  vector unsigned long long v8 = ev8;

  unsigned char *e = pe;

  do {
    if (a) {
      __builtin_vec_st(v1, 16, (unsigned long long *)e);
      __builtin_vec_st(v2, 32, (unsigned long long *)e);
      __builtin_vec_st(v3, 48, (unsigned long long *)e);
      e = e + 8;
      for (int i = 0; i < a; i++) {
        v4 = v5;
        v5 = __builtin_crypto_vpmsumd(v1, v6);
        v6 = __builtin_crypto_vpmsumd(v2, v7);
        v7 = __builtin_crypto_vpmsumd(v3, v8);
        e = e + 8;
      }
    }
    __builtin_vec_st(v5, 16, (unsigned long long *)e);
    __builtin_vec_st(v6, 32, (unsigned long long *)e);
    __builtin_vec_st(v7, 48, (unsigned long long *)e);
    if (c)
      b = 1;
  } while (b);

  return dummy(v4);
}

/* { dg-final { scan-assembler-not {(?n)rldicr.*,0,59} } } */