Apply changes from https://github.com/dotnet/runtime/commit/eb1756e97d23df13bc6fe798e...
[mono-project.git] / mono / tests / tailcall-member-function-in-valuetype.il
blobca2a1375482736cfab220161aa8e2a463f33def5
1 /*
2 To fix this, use a range check in the call and dynamically
3 decide tailcall or not.
5 Apply that to not just the `this` parameter, but all ref valuetypes.
7 Note that a small valuetype is no easier because it still has
8 reference semantics and is always passed by address.
10 using System;
11 using System.Runtime.CompilerServices;
12 using static System.Runtime.CompilerServices.MethodImplOptions;
14 unsafe public
15 // change to class and it works
16 struct
17 ValueType
19         public int a;
21         [MethodImpl (NoInlining)]
22         static void check (long stack1, long stack2)
23         {
24 // NOTE: This is wierd in order to be later hand edited (removed) in the IL.
25                 if (stack1 != 0)
26                         return;
27                 if (stack1 == stack2)
28                         return;
29                 Console.WriteLine ("tailcall failure {0} {1}", stack1, stack2);
30                 Environment.Exit (1);
31         }
33         [MethodImpl (NoInlining)]
34         public void Method1 (long depth = 100, long stack = 0)
35         {
36                 int local;
37                 if (depth > 0) {
38                         Method2 (depth - 1, (long)&local);
39                         return;
40                 }
41                 check ((long)&local, stack);
42         }
44         [MethodImpl (NoInlining)]
45         void Method2 (long depth = 100, long stack = 0)
46         {
47                 int local;
48                 if (depth > 0) {
49                         Method1 (depth - 1, (long)&local);
50                         return;
51                 }
52                 check ((long)&local, stack);
53         }
56 class B
58         [MethodImpl (NoInlining)]
59         public static void Main (string[] args)
60         {
61                 new ValueType ().Method1 (999999);
62         }
66 .assembly extern mscorlib { }
68 .assembly 'tailcall-member-function-in-valuetype' { }
70 .class public ValueType
71 extends [mscorlib]System.ValueType
73 .field public int32 a
75 .method static void check (int64 stack1, int64 stack2) noinlining
78 ldarg 0
79 brfalse IL_0004
80 ret
82 IL_0004:
84 ldarg 0
85 ldarg 1
86 bne.un IL_0009
87 ret
89 IL_0009:
90 ldstr "tailcall failure {0} {1}"
91 ldarg 0
92 box [mscorlib]System.Int64
93 ldarg 1
94 box [mscorlib]System.Int64
95 call void class [mscorlib]System.Console::WriteLine(string, object, object)
96 ldc.i4 1
97 tail.
98 call void class [mscorlib]System.Environment::Exit(int32)
99 ret
102 .method public instance void Method1 (int64 depth, int64 stack) noinlining
104 .locals init ( int32 V_0)
106 ldarg 1
107 ldc.i8 0
108 ble IL_0014
110 ldarg 0
111 ldarg 1
112 ldc.i8 1
114 ldloca 0
115 conv.u8
116 tail.
117 call instance void valuetype ValueType::Method2(int64, int64)
120 IL_0014:
121 ldloca 0
122 conv.u8
123 ldarg 2
124 tail.
125 call void valuetype ValueType::check(int64, int64)
129 .method instance void Method2 (int64 depth, int64 stack) noinlining
131 .locals init ( int32 V_0)
133 ldarg 1
134 ldc.i8 0
135 ble IL_0014
137 ldarg 0
138 ldarg 1
139 ldc.i8 1
141 ldloca 0
142 conv.u8
143 tail.
144 call instance void valuetype ValueType::Method1(int64, int64)
147 IL_0014:
148 ldloca 0
149 conv.u8
150 ldarg 2
151 tail.
152 call void valuetype ValueType::check(int64, int64)
156 .class B
157 extends [mscorlib]System.Object
160 .method public static void Main (string[] args) noinlining
162 .entrypoint
163 .locals init ( valuetype ValueType V_0)
165 ldloca 0
166 initobj ValueType
167 ldloc 0
168 stloc 0
169 ldloca 0
170 ldc.i8 1
171 ldc.i8 0
172 tail.
173 call instance void valuetype ValueType::Method1(int64, int64)
177 .method public instance default void '.ctor' ()
179 ldarg 0
180 tail.
181 call instance void object::'.ctor'()