[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mono / tests / tailcall-virt.il
blob37e447dbc4cfce619a92787ef5de0dda6d7d8a38
1 /*
2 Test tail.callvirt.
4 Author:
5     Jay Krell (jaykrell@microsoft.com)
7 Copyright 2018 Microsoft
8 Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 This IL will exit with 0 for success, 1 for failure.
11 It is based on nearby C# that is based on nearby F#.
13 This test covers tail.callvirt.
14 Incidentally it is a mutual recursion, not a self-recursion,
15 no generics, no pointers, small function signature, no value types, etc.
17 This is based on F#, that stack overflows or exit with 1 or 2.
18 If testing the F#, be sure to compile with --optimize- else
19 the tailcall might be optimized away:
20         type A() =
21             member this.f2 (a) = if a > 0 then this.f1(a - 1)
22                                  else 1
23             member this.f1 (a) = if a > 0 then this.f2(a - 1)
24                                  else 2
26         let a =         A()
27         printfn "%d" (a.f1(1000 * 1000 * 10))
29 and more closely on C#, csc -optimize to keep
30 ret next call, ildasm and add tail.:
31         using System;
32         using System.Runtime.CompilerServices;
33         using static System.Runtime.CompilerServices.MethodImplOptions;
35         unsafe class A
36         {
37             static int check (long stack1, long stack2)
38             {
39                 return (stack1 == stack2) ? 0 : 1;
40             }
42             [MethodImpl (NoInlining)]
43             public virtual int f1(int counter, long initial_stack, long current_stack)
44             {
45                 int local;
46                 if (counter > 0)
47                     return f2(counter - 1, initial_stack, (long)&local);
48                 return check((long)&local, current_stack);
49             }
51             [MethodImpl (NoInlining)]
52             public virtual int f2(int counter, long initial_stack, long current_stack)
53             {
54                 int local;
55                 if (counter > 0)
56                     return f1(counter - 1, initial_stack, (long)&local);
57                 return check((long)&local, current_stack);
58             }
60             [MethodImpl (NoInlining)]
61             public static void Main()
62             {
63                 int stack;
64                 Environment.Exit(new A().f1(100, (long)&stack, 0));
65             }
66         }
69 .assembly extern mscorlib { }
71 .assembly 'tailcall-virt' { }
73 .class A
75 .method static int32 check(int64 stack1, int64 stack2) 
77         ldarg.0
78         ldarg.1
79         beq.s IL_0006
80         ldc.i4.1
81         ret
83 IL_0006:
84         ldc.i4.0
85         ret
88 .method newslot virtual instance int32 f1(int32 counter, int64 initial_stack, int64 current_stack) noinlining
90         .locals init (int32 V_0)
91         ldarg.1
92         ldc.i4.0
93         ble.s IL_0013
94         ldarg.0
95         ldarg.1
96         ldc.i4.1
97         sub
98         ldarg.2
99         ldloca.s V_0
100         conv.u
101         conv.u8
102         tail. callvirt instance int32 A::f2(int32, int64, int64)
103         ret
105 IL_0013:
106         ldloca.s V_0
107         conv.u
108         conv.u8
109         ldarg.3
110         tail. call int32 A::check(int64, int64)
111         ret
114 .method newslot virtual instance int32 f2(int32 counter, int64 initial_stack, int64 current_stack) noinlining
116         .locals init (int32 V_0)
117         ldarg.1
118         ldc.i4.0
119         ble.s IL_0013
120         ldarg.0
121         ldarg.1
122         ldc.i4.1
123         sub
124         ldarg.2
125         ldloca.s V_0
126         conv.u
127         conv.u8
128         tail. callvirt instance int32 A::f1(int32, int64, int64)
129         ret
131 IL_0013:
132         ldloca.s V_0
133         conv.u
134         conv.u8
135         ldarg.3
136         tail. call int32 A::check(int64, int64)
137         ret
140 .method static void Main() noinlining
142         .entrypoint
143         .locals init (int32 V_0)
144         newobj instance void A::.ctor()
145         ldc.i4 0x100
146         ldloca.s V_0
147         conv.u
148         conv.u8
149         ldc.i4.0
150         conv.i8
151         callvirt instance int32 A::f1(int32, int64, int64)
152         tail. call void [mscorlib]System.Environment::Exit(int32)
153         ret
156 .method instance void .ctor() 
158         ldarg.0
159         tail. call instance void [mscorlib]System.Object::.ctor()
160         ret