summaryrefslogtreecommitdiff
path: root/tests/src/JIT/Regression/JitBlue/GitHub_7508/Vector3Test.cs
blob: 609141fd6466786c3ddfbe186a2ab69407124681 (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

// Since Issue 7508 was a performance issue, there's not really a correctness
// test for this.
// However, this is a very simple test that can be used to compare the code generated
// for a non-accelerated vector of 3 floats, a "raw" Vector3 and a Vector3
// wrapped in a struct.

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Numerics;

namespace Test01
{
    public struct SimpleVector3
    {
        [MethodImpl( MethodImplOptions.AggressiveInlining )]
        public SimpleVector3( float x, float y, float z )
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        [MethodImpl( MethodImplOptions.AggressiveInlining )]
        public static SimpleVector3 operator +( SimpleVector3 a, SimpleVector3 b )
            => new SimpleVector3( a.x + b.x, a.y + b.y, a.z + b.z );

        public float X
        {
            get { return x; }
            set { x = value; }
        }

        public float Y
        {
            get { return y; }
            set { y = value; }
        }

        public float Z
        {
            get { return z; }
            set { z = value; }
        }

        float x, y, z;
    }

    public struct WrappedVector3
    {
        [MethodImpl( MethodImplOptions.AggressiveInlining )]
        public WrappedVector3( float x, float y, float z )
        {
            v = new System.Numerics.Vector3( x, y, z );
        }

        [MethodImpl( MethodImplOptions.AggressiveInlining )]
        WrappedVector3( System.Numerics.Vector3 v )
        {
            this.v = v;
        }

        [MethodImpl( MethodImplOptions.AggressiveInlining )]
        public static WrappedVector3 operator +( WrappedVector3 a, WrappedVector3 b )
            => new WrappedVector3( a.v + b.v );

        public float X
        {
            get { return v.X; }
            set { v.X = value; }
        }

        public float Y
        {
            get { return v.Y; }
            set { v.Y = value; }
        }
                
        public float Z
        {
            get { return v.Z; }
            set { v.Z = value; }
        }

        Vector3 v;
    }

    public class Program
    {
        static Random random = new Random( 12345 );
        [MethodImpl( MethodImplOptions.NoInlining )]
        static SimpleVector3 RandomSimpleVector3()
            => new SimpleVector3( (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble() );
        [MethodImpl(MethodImplOptions.NoInlining)]
        static WrappedVector3 RandomWrappedVector3()
            => new WrappedVector3( (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble() );
        [MethodImpl(MethodImplOptions.NoInlining)]
        static Vector3 RandomVector3()
            => new Vector3( (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble() );

        public static float TestSimple()
        {
            var simpleA = RandomSimpleVector3();
            var simpleB = RandomSimpleVector3();
            var simpleC = simpleA + simpleB;
            Console.WriteLine("Simple Vector3: {0},{1},{2}", simpleC.X, simpleC.Y, simpleC.Z);
            return simpleC.X + simpleC.Y + simpleC.Z;
        }
        public static float TestWrapped()
        {
            var wrappedA = RandomWrappedVector3();
            var wrappedB = RandomWrappedVector3();
            var wrappedC = wrappedA + wrappedB;
            Console.WriteLine("Wrapped Vector3: {0},{1},{2}", wrappedC.X, wrappedC.Y, wrappedC.Z);
            return wrappedC.X + wrappedC.Y + wrappedC.Z;
        }
        public static float TestSIMD()
        {
            var a = RandomVector3();
            var b = RandomVector3();
            var c = a + b;
            Console.WriteLine("SIMD Vector3: {0},{1},{2}", c.X, c.Y, c.Z);
            return c.X + c.Y + c.Z;
        }
        public static int Main( string[] args )
        {
            int returnVal = 100;

            // First, test a simple (non-SIMD) Vector3 type
            float f = TestSimple();

            // Now a wrapped SIMD Vector3.
            if (TestWrapped() != f)
            {
                returnVal = -1;
            }

            // Now, SIMD Vector3
            if (TestSIMD() != f)
            {
                returnVal = -1;
            }

            return 100;
        }
    }
}