summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/runnable/sroa13220.d
blob: 2cec6665a331483f507d2e1b34df8df2fa85f199 (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
98
99
100
101
102
103
/* REQUIRED_ARGS: -O -inline -noboundscheck
 */
// https://github.com/dlang/pull/13220

version (D_SIMD)
{

mixin template VectorOps(VectorType, ArrayType: BaseType[N], BaseType, size_t N)
{
    enum Count = N;
    alias Base = BaseType;

    BaseType* ptr() return pure nothrow @nogc
    {
        return array.ptr;
    }

    // Unary operators
    VectorType opUnary(string op)() pure nothrow @safe @nogc
    {
        VectorType res = void;
        mixin("res.array[] = " ~ op ~ "array[];");
        return res;
    }

    // Binary operators
    VectorType opBinary(string op)(VectorType other) pure const nothrow @safe @nogc
    {
        VectorType res = void;
        mixin("res.array[] = array[] " ~ op ~ " other.array[];");
        return res;
    }

    // Assigning a BaseType value
    void opAssign(BaseType e) pure nothrow @safe @nogc
    {
        array[] = e;
    }

    // Assigning a static array
    void opAssign(ArrayType v) pure nothrow @safe @nogc
    {
        array[] = v[];
    }

    void opOpAssign(string op)(VectorType other) pure nothrow @safe @nogc
    {
        mixin("array[] "  ~ op ~ "= other.array[];");
    }

    // Assigning a dyn array
    this(ArrayType v) pure nothrow @safe @nogc
    {
        array[] = v[];
    }

    // Broadcast constructor
    this(BaseType x) pure nothrow @safe @nogc
    {
        array[] = x;
    }

    ref inout(BaseType) opIndex(size_t i) inout pure nothrow @safe @nogc
    {
        return array[i];
    }
}

// Note: can't be @safe with this signature
Vec loadUnaligned(Vec)(const(BaseType!Vec)* pvec) @trusted
{
    // Since this vector is emulated, it doesn't have alignement constraints
    // and as such we can just cast it.
    return *cast(Vec*)(pvec);
}

private template BaseType(V)
{
    alias typeof( ( { V v; return v; }()).array[0]) BaseType;
}

struct int4
{
    int[4] array;
    mixin VectorOps!(int4, int[4]);
}

alias __m128i = int4;
}

int main()
{
  version (D_SIMD)
  {
    int4 A = [1, 2, 3, 4];
    int4 ia = A;
    ia.ptr[2] = 5;
    int4 C = ia;
    int[4] result = [1, 2, 5, 4];
    assert(C.array == result);
  }
    return 0;
}