671f0ccc459f67d5c1123e32ee5c0b6ac85e6b57
[mono.git] / mono / mini / basic.cs
1 using System;
2 using System.Reflection;
3
4 /*
5  * Regression tests for the mono JIT.
6  *
7  * Each test needs to be of the form:
8  *
9  * static int test_<result>_<name> ();
10  *
11  * where <result> is an integer (the value that needs to be returned by
12  * the method to make it pass.
13  * <name> is a user-displayed name used to identify the test.
14  *
15  * The tests can be driven in two ways:
16  * *) running the program directly: Main() uses reflection to find and invoke
17  *      the test methods (this is useful mostly to check that the tests are correct)
18  * *) with the --regression switch of the jit (this is the preferred way since
19  *      all the tests will be run with optimizations on and off)
20  *
21  * The reflection logic could be moved to a .dll since we need at least another
22  * regression test file written in IL code to have better control on how
23  * the IL code looks.
24  */
25
26 class Tests {
27
28         static int Main () {
29                 return TestDriver.RunTests (typeof (Tests));
30         }
31         
32         public static int test_0_return () {
33                 return 0;
34         }
35
36         public static int test_100000_return_large () {
37                 return 100000;
38         }
39
40         public static int test_1_load_bool () {
41                 bool a = true;
42                 return a? 1: 0;
43         }
44
45         public static int test_0_load_bool_false () {
46                 bool a = false;
47                 return a? 1: 0;
48         }
49
50         public static int test_200_load_byte () {
51                 byte a = 200;
52                 return a;
53         }
54
55         public static int test_100_load_sbyte () {
56                 sbyte a = 100;
57                 return a;
58         }
59
60         public static int test_200_load_short () {
61                 short a = 200;
62                 return a;
63         }
64
65         public static int test_100_load_ushort () {
66                 ushort a = 100;
67                 return a;
68         }
69
70         public static int test_3_add_simple () {
71                 int a = 1; 
72                 int b = 2;
73                 return a + b;
74         }
75
76         public static int test_3_add_imm () {
77                 int a = 1; 
78                 return a + 2;
79         }
80
81         public static int test_13407573_add_largeimm () {
82                 int a = 1; 
83                 return a + 13407572;
84         }
85
86         public static int test_1_sub_simple () {
87                 int a = 1; 
88                 int b = 2;
89                 return b - a;
90         }
91
92         public static int test_1_sub_simple_un () {
93                 uint a = 1; 
94                 uint b = 2;
95                 return (int)(b - a);
96         }
97
98         public static int test_1_sub_imm () {
99                 int b = 2;
100                 return b - 1;
101         }
102
103         public static int test_2_sub_large_imm () {
104                 int b = 0xff0f0f;
105                 return b - 0xff0f0d;
106         }
107
108         public static int test_0_sub_inv_imm () {
109                 int b = 2;
110                 return 2 - b;
111         }
112
113         public static int test_2_and () {
114                 int b = 2;
115                 int a = 3;
116                 return b & a;
117         }
118
119         public static int test_0_and_imm () {
120                 int b = 2;
121                 return b & 0x10;
122         }
123
124         public static int test_0_and_large_imm () {
125                 int b = 2;
126                 return b & 0x10000000;
127         }
128
129         public static int test_0_and_large_imm2 () {
130                 int b = 2;
131                 return b & 0x100000f0;
132         }
133
134         public static int test_2_div () {
135                 int b = 6;
136                 int a = 3;
137                 return b / a;
138         }
139
140         public static int test_4_div_imm () {
141                 int b = 12;
142                 return b / 3;
143         }
144
145         public static int test_4_divun_imm () {
146                 uint b = 12;
147                 return (int)(b / 3);
148         }
149
150         public static int test_0_div_fold () {
151                 int b = -1;
152                 return b / 2;
153         }
154
155         public static int test_719177_div_destreg () {
156                 int year = 1970;
157                 return ((365* (year-1)) + ((year-1)/4));
158         }
159
160         public static int test_1_remun_imm () {
161                 uint b = 13;
162                 return (int)(b % 3);
163         }
164
165         public static int test_2_bigremun_imm () {
166                 unchecked {
167                         uint b = (uint)-2;
168                         return (int)(b % 3);
169                 }
170         }
171
172         public static int test_2_rem () {
173                 int b = 5;
174                 int a = 3;
175                 return b % a;
176         }
177
178         public static int test_4_rem_imm () {
179                 int b = 12;
180                 return b % 8;
181         }
182
183         public static int test_4_rem_big_imm () {
184                 int b = 10004;
185                 return b % 10000;
186         }
187
188         public static int test_9_mul () {
189                 int b = 3;
190                 int a = 3;
191                 return b * a;
192         }
193
194         public static int test_15_mul_imm () {
195                 int b = 3;
196                 return b * 5;
197         }
198
199         public static int test_24_mul () {
200                 int a = 3;
201                 int b = 8;
202                 int res;
203
204                 res = a * b;
205                 
206                 return res;
207         }
208
209         public static int test_24_mul_ovf () {
210                 int a = 3;
211                 int b = 8;
212                 int res;
213
214                 checked {
215                         res = a * b;
216                 }
217                 
218                 return res;
219         }
220
221         public static int test_24_mul_un () {
222                 uint a = 3;
223                 uint b = 8;
224                 uint res;
225
226                 res = a * b;
227                 
228                 return (int)res;
229         }
230
231         public static int test_24_mul_ovf_un () {
232                 uint a = 3;
233                 uint b = 8;
234                 uint res;
235
236                 checked {
237                         res = a * b;
238                 }
239                 
240                 return (int)res;
241         }
242
243         public static int test_0_add_ovf () {
244                 int i, j, k;
245
246                 checked {
247                         i = System.Int32.MinValue;
248                         j = 0;
249                         k = i + j;
250                 }
251
252                 if (k != System.Int32.MinValue)
253                         return 1;
254
255                 checked {
256                         i = System.Int32.MaxValue;
257                         j = 0;
258                         k = i + j;
259                 }
260
261                 if (k != System.Int32.MaxValue)
262                         return 2;
263
264                 checked {
265                         i = System.Int32.MinValue;
266                         j = System.Int32.MaxValue;
267                         k = i + j;
268                 }
269
270                 if (k != -1)
271                         return 3;
272
273                 checked {
274                         i = System.Int32.MaxValue;
275                         j = System.Int32.MinValue;
276                         k = i + j;
277                 }
278
279                 if (k != -1)
280                         return 4;
281
282                 checked {
283                         i = System.Int32.MinValue + 1234;
284                         j = -1234;
285                         k = i + j;
286                 }
287
288                 if (k != System.Int32.MinValue)
289                         return 5;
290
291                 checked {
292                         i = System.Int32.MaxValue - 1234;
293                         j = 1234;
294                         k = i + j;
295                 }
296
297                 if (k != System.Int32.MaxValue)
298                         return 6;
299
300                 return 0;
301         }
302
303         public static int test_0_add_un_ovf () {
304                 uint n = (uint)134217728 * 16;
305                 uint number = checked (n + (uint)0);
306
307                 return number == n ? 0 : 1;
308         }
309
310         public static int test_3_or () {
311                 int b = 2;
312                 int a = 3;
313                 return b | a;
314         }
315
316         public static int test_3_or_un () {
317                 uint b = 2;
318                 uint a = 3;
319                 return (int)(b | a);
320         }
321
322         public static int test_3_or_short_un () {
323                 ushort b = 2;
324                 ushort a = 3;
325                 return (int)(b | a);
326         }
327
328         public static int test_18_or_imm () {
329                 int b = 2;
330                 return b | 0x10;
331         }
332
333         public static int test_268435458_or_large_imm () {
334                 int b = 2;
335                 return b | 0x10000000;
336         }
337
338         public static int test_268435459_or_large_imm2 () {
339                 int b = 2;
340                 return b | 0x10000001;
341         }
342
343         public static int test_1_xor () {
344                 int b = 2;
345                 int a = 3;
346                 return b ^ a;
347         }
348
349         public static int test_1_xor_imm () {
350                 int b = 2;
351                 return b ^ 3;
352         }
353
354         public static int test_983041_xor_imm_large () {
355                 int b = 2;
356                 return b ^ 0xf0003;
357         }
358
359         public static int test_1_neg () {
360                 int b = -2;
361                 b++;
362                 return -b;
363         }
364
365         public static int test_2_not () {
366                 int b = ~2;
367                 b = ~b;
368                 return b;
369         }
370
371         public static int test_16_shift () {
372                 int b = 2;
373                 int a = 3;
374                 return b << a;
375         }
376         
377         public static int test_16_shift_add () {
378                 int b = 2;
379                 int a = 3;
380                 int c = 0;
381                 return b << (a + c);
382         }
383         
384         public static int test_16_shift_add2 () {
385                 int b = 2;
386                 int a = 3;
387                 int c = 0;
388                 return (b + c) << a;
389         }
390         
391         public static int test_16_shift_imm () {
392                 int b = 2;
393                 return b << 3;
394         }
395         
396         public static int test_524288_shift_imm_large () {
397                 int b = 2;
398                 return b << 18;
399         }
400         
401         public static int test_12_shift_imm_inv () {
402                 int b = 2;
403                 return 3 << 2;
404         }
405
406         public static int test_12_shift_imm_inv_sbyte () {
407                 sbyte b = 2;
408                 return 3 << 2;
409         }
410
411         public static int test_1_rshift_imm () {
412                 int b = 8;
413                 return b >> 3;
414         }
415         
416         public static int test_2_unrshift_imm () {
417                 uint b = 16;
418                 return (int)(b >> 3);
419         }
420         
421         public static int test_0_bigunrshift_imm () {
422                 unchecked {
423                         uint b = (uint)-1;
424                         b = b >> 1;
425                         if (b != 0x7fffffff)
426                                 return 1;
427                         return 0;
428                 }
429         }
430         
431         public static int test_0_bigrshift_imm () {
432                 int b = -1;
433                 b = b >> 1;
434                 if (b != -1)
435                         return 1;
436                 return 0;
437         }
438         
439         public static int test_1_rshift () {
440                 int b = 8;
441                 int a = 3;
442                 return b >> a;
443         }
444         
445         public static int test_2_unrshift () {
446                 uint b = 16;
447                 int a = 3;
448                 return (int)(b >> a);
449         }
450         
451         public static int test_0_bigunrshift () {
452                 unchecked {
453                         uint b = (uint)-1;
454                         int a = 1;
455                         b = b >> a;
456                         if (b != 0x7fffffff)
457                                 return 1;
458                         return 0;
459                 }
460         }
461         
462         public static int test_0_bigrshift () {
463                 int b = -1;
464                 int a = 1;
465                 b = b >> a;
466                 if (b != -1)
467                         return 1;
468                 return 0;
469         }
470         
471         public static int test_2_cond () {
472                 int b = 2, a = 3, c;
473                 if (a == b)
474                         return 0;
475                 return 2;
476         }
477         
478         public static int test_2_cond_short () {
479                 short b = 2, a = 3, c;
480                 if (a == b)
481                         return 0;
482                 return 2;
483         }
484         
485         public static int test_2_cond_sbyte () {
486                 sbyte b = 2, a = 3, c;
487                 if (a == b)
488                         return 0;
489                 return 2;
490         }
491         
492         public static int test_6_cascade_cond () {
493                 int b = 2, a = 3, c;
494                 if (a == b)
495                         return 0;
496                 else if (b > a)
497                         return 1;
498                 else if (b != b)
499                         return 2;
500                 else {
501                         c = 1;
502                 }
503                 return a + b + c;
504         }
505         
506         public static int test_6_cascade_short () {
507                 short b = 2, a = 3, c;
508                 if (a == b)
509                         return 0;
510                 else if (b > a)
511                         return 1;
512                 else if (b != b)
513                         return 2;
514                 else {
515                         c = 1;
516                 }
517                 return a + b + c;
518         }
519
520         public static int test_0_short_sign_extend () {
521                 int t1 = 0xffeedd;
522                 short s1 = (short)t1;
523                 int t2 = s1;
524
525                 if ((uint)t2 != 0xffffeedd) 
526                         return 1;
527                 else
528                         return 0;
529         }               
530         
531         public static int test_15_for_loop () {
532                 int i;
533                 for (i = 0; i < 15; ++i) {
534                 }
535                 return i;
536         }
537         
538         public static int test_11_nested_for_loop () {
539                 int i, j = 0; /* mcs bug here if j not set */
540                 for (i = 0; i < 15; ++i) {
541                         for (j = 200; j >= 5; --j) ;
542                 }
543                 return i - j;
544         }
545
546         public static int test_11_several_nested_for_loops () {
547                 int i, j = 0; /* mcs bug here if j not set */
548                 for (i = 0; i < 15; ++i) {
549                         for (j = 200; j >= 5; --j) ;
550                 }
551                 i = j = 0;
552                 for (i = 0; i < 15; ++i) {
553                         for (j = 200; j >= 5; --j) ;
554                 }
555                 return i - j;
556         }
557
558         public static int test_0_conv_ovf_i1 () {
559                 int c;
560
561                 //for (int j = 0; j < 10000000; j++)
562                 checked {
563                         c = 127;
564                         sbyte b = (sbyte)c;
565                         c = -128;
566                         b = (sbyte)c;
567                 }
568
569                 return 0;
570         }
571         
572         public static int test_0_conv_ovf_i1_un () {
573                 uint c;
574
575                 checked {
576                         c = 127;
577                         sbyte b = (sbyte)c;
578                 }
579                 
580                 return 0;
581         }
582         
583         public static int test_0_conv_ovf_i2 () {
584                 int c;
585
586                 checked {
587                         c = 32767;
588                         Int16 b = (Int16)c;
589                         c = -32768;
590                         b = (Int16)c;
591                         unchecked {
592                                 uint u = 0xfffffffd;
593                                 c = (int)u;
594                         }
595                         b = (Int16)c;
596                 }
597                 
598                 return 0;
599         }
600         
601         public static int test_0_conv_ovf_i2_un () {
602                 uint c;
603
604                 checked {
605                         c = 32767;
606                         Int16 b = (Int16)c;
607                 }
608                 
609                 return 0;
610         }
611         
612         public static int test_0_conv_ovf_u2 () {
613                 int c;
614
615                 checked {
616                         c = 65535;
617                         UInt16 b = (UInt16)c;
618                 }
619                 
620                 return 0;
621         }
622         
623         public static int test_0_conv_ovf_u2_un () {
624                 uint c;
625
626                 checked {
627                         c = 65535;
628                         UInt16 b = (UInt16)c;
629                 }
630                 
631                 return 0;
632         }
633         
634         public static int test_0_conv_ovf_u4 () {
635                 int c;
636
637                 checked {
638                         c = 0x7fffffff;
639                         uint b = (uint)c;
640                 }
641                 
642                 return 0;
643         }
644         
645         public static int test_0_bool () {
646                 bool val = true;
647                 if (val)
648                         return 0;
649                 return 1;
650         }
651         
652         public static int test_1_bool_inverted () {
653                 bool val = true;
654                 if (!val)
655                         return 0;
656                 return 1;
657         }
658
659         public static int test_1_bool_assign () {
660                 bool val = true;
661                 val = !val; // this should produce a ceq
662                 if (val)
663                         return 0;
664                 return 1;
665         }
666
667         public static int test_1_bool_multi () {
668                 bool val = true;
669                 bool val2 = true;
670                 val = !val;
671                 if ((val && !val2) && (!val2 && val))
672                         return 0;
673                 return 1;
674         }
675
676         public static int test_16_spill () {
677                 int a = 1;
678                 int b = 2;
679                 int c = 3;
680                 int d = 4;
681                 int e = 5;
682
683                 return (1 + (a + (b + (c + (d + e)))));
684         }
685
686         public static int test_1_switch () {
687                 int n = 0;
688
689                 switch (n) {
690                 case 0: return 1;
691                 case 1: return 2;
692                 case -1: return 3;
693                 default:
694                         return 4;
695                 }
696                 return 1;
697         }
698
699         public static int test_0_switch_constprop () {
700                 int n = -1;
701
702                 switch (n) {
703                 case 0: return 2;
704                 case 1: return 3;
705                 case 2: return 3;                       
706                 default:
707                         return 0;
708                 }
709                 return 3;
710         }
711
712         public static int test_0_switch_constprop2 () {
713                 int n = 3;
714
715                 switch (n) {
716                 case 0: return 2;
717                 case 1: return 3;
718                 case 2: return 3;                       
719                 default:
720                         return 0;
721                 }
722                 return 3;
723         }
724
725         public static int test_0_while_loop_1 () {
726
727                 int value = 255;
728                 
729                 do {
730                         value = value >> 4;
731                 } while (value != 0);
732                 
733                 return 0;
734         }
735
736         public static int test_0_while_loop_2 () {
737                 int value = 255;
738                 int position = 5;
739                 
740                 do {
741                         value = value >> 4;
742                 } while (value != 0 && position > 1);
743         
744                 return 0;
745         }
746
747         public static int test_0_char_conv () {
748                 int i = 1;
749                 
750                 char tc = (char) ('0' + i);
751
752                 if (tc != '1')
753                         return 1;
754                 
755                 return 0;
756         }
757
758         public static int test_3_shift_regalloc () {
759                 int shift = 8;
760                 int orig = 1;
761                 byte value = 0xfe;
762
763                 orig &= ~(0xff << shift);
764                 orig |= value << shift;
765
766                 if (orig == 0xfe01)
767                         return 3;
768                 return 0;
769         }
770
771         enum E {A, B};
772         
773         public static int test_2_optimize_branches () {
774                 switch (E.A) {
775                 case E.A:
776                         if (E.A == E.B) {
777                         }
778                         break;
779                 }
780                 return 2;
781         }
782
783         public static int test_0_checked_byte_cast () {
784                 int v = 250;
785                 int b = checked ((byte) (v));
786
787                 if (b != 250)
788                         return 1;
789                 return 0;
790         }
791
792         public static int test_0_checked_byte_cast_un () {
793                 uint v = 250;
794                 uint b = checked ((byte) (v));
795
796                 if (b != 250)
797                         return 1;
798                 return 0;
799         }
800
801         public static int test_0_checked_short_cast () {
802                 int v = 250;
803                 int b = checked ((ushort) (v));
804
805                 if (b != 250)
806                         return 1;
807                 return 0;
808         }
809
810         public static int test_0_checked_short_cast_un () {
811                 uint v = 250;
812                 uint b = checked ((ushort) (v));
813
814                 if (b != 250)
815                         return 1;
816                 return 0;
817         }
818         
819         public static int test_1_a_eq_b_plus_a () {
820                 int a = 0, b = 1;
821                 a = b + a;
822                 return a;
823         }
824
825         public static int test_0_comp () {
826                 int a = 0;
827                 int b = -1;
828                 int error = 1;
829                 bool val;
830
831                 val = a < b;
832                 if (val)
833                         return error;
834                 error++;
835
836                 val = a > b;
837                 if (!val)
838                         return error;
839                 error ++;
840
841                 val = a == b;
842                 if (val)
843                         return error;
844                 error ++;
845
846                 val = a == a;
847                 if (!val)
848                         return error;
849                 error ++;
850
851                 return 0;
852         }
853
854         public static int test_0_comp_unsigned () {
855                 uint a = 1;
856                 uint b = 0xffffffff;
857                 int error = 1;
858                 bool val;
859
860                 val = a < b;
861                 if (!val)
862                         return error;
863                 error++;
864
865                 val = a <= b;
866                 if (!val)
867                         return error;
868                 error++;
869
870                 val = a == b;
871                 if (val)
872                         return error;
873                 error++;
874
875                 val = a >= b;
876                 if (val)
877                         return error;
878                 error++;
879
880                 val = a > b;
881                 if (val)
882                         return error;
883                 error++;
884
885                 val = b < a;
886                 if (val)
887                         return error;
888                 error++;
889
890                 val = b <= a;
891                 if (val)
892                         return error;
893                 error++;
894
895                 val = b == a;
896                 if (val)
897                         return error;
898                 error++;
899
900                 val = b > a;
901                 if (!val)
902                         return error;
903                 error++;
904
905                 val = b >= a;
906                 if (!val)
907                         return error;
908                 error++;
909
910                 return 0;
911         }
912         
913         public static int test_16_cmov () 
914         {
915                 int n = 0;
916                 if (n == 0)
917                         n = 16;
918                 
919                 return n;
920         }
921         
922         public static int my_flags;
923         public static int test_0_and_cmp ()
924         {
925                 
926                 /* various forms of test [mem], imm */
927                 
928                 my_flags = 0x01020304;
929                 
930                 if ((my_flags & 0x01020304) == 0)
931                         return 1;
932                 
933                 if ((my_flags & 0x00000304) == 0)
934                         return 2;
935                 
936                 if ((my_flags & 0x00000004) == 0)
937                         return 3;
938                 
939                 if ((my_flags & 0x00000300) == 0)
940                         return 4;
941                 
942                 if ((my_flags & 0x00020000) == 0)
943                         return 5;
944                 
945                 if ((my_flags & 0x01000000) == 0)
946                         return 6;
947                 
948                 /* test esi, imm */
949                 int local = 0x01020304;
950                 
951                 if ((local & 0x01020304) == 0)
952                         return 7;
953                 
954                 if ((local & 0x00000304) == 0)
955                         return 8;
956                 
957                 if ((local & 0x00000004) == 0)
958                         return 9;
959                 
960                 if ((local & 0x00000300) == 0)
961                         return 10;
962                 
963                 if ((local & 0x00020000) == 0)
964                         return 11;
965                 
966                 if ((local & 0x01000000) == 0)
967                         return 12;
968                 
969                 return 0;
970         }
971         
972         public static int test_0_cne ()
973         {
974                 int x = 0;
975                 int y = 1;
976                 
977                 bool b = x != y;
978                 bool bb = x != x;
979                 
980                 if (!b)
981                         return 1;
982                 if (bb)
983                         return 2;
984                 
985                 return 0;
986         }
987         
988         static byte b;
989         public static int test_0_byte_compares ()
990         {
991                 b = 0xff;
992                 if (b == -1)
993                         return 1;
994                 b = 0;
995                 if (!(b < System.Byte.MaxValue))
996                         return 2;
997                 
998                 if (!(b <= System.Byte.MaxValue))
999                         return 3;
1000                 
1001                 return 0;
1002         }
1003         public static int test_0_cmp_regvar_zero ()
1004         {
1005                 int n = 10;
1006                 
1007                 if (!(n > 0 && n >= 0 && n != 0))
1008                         return 1;
1009                 if (n < 0 || n <= 0 || n == 0)
1010                         return 1;
1011                 
1012                 return 0;
1013         }
1014
1015 }