summaryrefslogtreecommitdiff
path: root/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.cs
blob: ecd7e7fa3898dfea4f7edf4755e17acb6840525c (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
// 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.
using System;
using System.Runtime.CompilerServices;

struct MyStruct
{
    // Struct containing 4 fields, 3 of which are longs that will be decomposed.
    // The bug was that this resulted in 7 input registers to the GT_FIELD_LIST
    // parameter, which can't be accommodated by the register allocator.

    public MyStruct(long l1, long l2, long l3, int i)
    {
        f1 = l1;
        f2 = l2;
        f3 = l3;
        f4 = new int[i];
        f4[0] = i;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static MyStruct newMyStruct(long l1, long l2, long l3, int i)
    {
        return new MyStruct(l1, l2, l3, i);
    }

    public long f1;
    public long f2;
    public long f3;
    public int[] f4;
}

struct MyStruct2
{
    // This is a variation that includes a double field, to ensure that a mix of
    // field types are supported.
    public MyStruct2(long l1, long l2, double d, int i)
    {
        f1 = l1;
        f2 = l2;
        f3 = d;
        f4 = new int[i];
        f4[0] = i;
    }

    public long f1;
    public long f2;
    public double f3;
    public int[] f4;
}

struct MyStruct3
{
    // And finally one that includes longs and a double, but no ref.
    public MyStruct3(long l1, long l2, double d, int i)
    {
        f1 = l1;
        f2 = l2;
        f3 = d;
        f4 = i;
    }

    public long f1;
    public long f2;
    public double f3;
    public int f4;
}

class Program
{

    static int Pass = 100;
    static int Fail = -1;

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int AddFields(MyStruct s)
    {
        return (int)(s.f1 + s.f2 + s.f3 + s.f4[0]);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int AddFields2(MyStruct2 s)
    {
        return (int)(s.f1 + s.f2 + (int)s.f3 + s.f4[0]);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int AddFields3(MyStruct3 s)
    {
        return (int)(s.f1 + s.f2 + (int)s.f3 + s.f4);
    }

    static int Main(string[] args)
    {
        int returnVal = Pass;
        MyStruct s = new MyStruct(1, 2, 3, 4);
        int sum = AddFields(s);
        if (sum != 10)
        {
            Console.WriteLine("Failed first call");
            returnVal = Fail;
        }
        s = MyStruct.newMyStruct(1, 2, 3, 4);
        sum = AddFields(s);
        if (sum != 10)
        {
            Console.WriteLine("Failed second call");
            returnVal = Fail;
        }
        MyStruct2 s2 = new MyStruct2(1, 2, 3.0, 4);
        sum = AddFields2(s2);
        if (sum != 10)
        {
            Console.WriteLine("Failed third call");
            returnVal = Fail;
        }
        MyStruct3 s3 = new MyStruct3(1, 2, 3.0, 4);
        sum = AddFields3(s3);
        if (sum != 10)
        {
            Console.WriteLine("Failed fourth call");
            returnVal = Fail;
        }
        if (returnVal == Pass)
        {
            Console.WriteLine("Pass");
        }
        return returnVal;
    }
}