summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2016-06-15 22:53:47 -0700
committerGitHub <noreply@github.com>2016-06-15 22:53:47 -0700
commitd5a0338ddefc9551f3f573b4950ab046f58d9464 (patch)
treead66ff39c9470a184b3a7eebebb49665297be19a /tests
parent9ec70e119cca0cf317e1d64a3efd2bb9021e6d80 (diff)
parent1b34b726c3644ca494be54f90bbb190905e52e4e (diff)
downloadcoreclr-d5a0338ddefc9551f3f573b4950ab046f58d9464.tar.gz
coreclr-d5a0338ddefc9551f3f573b4950ab046f58d9464.tar.bz2
coreclr-d5a0338ddefc9551f3f573b4950ab046f58d9464.zip
Merge pull request #5819 from AndyAyersMS/InlineTestsV1
Inliner: simple performance tests
Diffstat (limited to 'tests')
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs810
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs810
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs330
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs890
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs890
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.csproj47
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs930
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.csproj47
24 files changed, 10804 insertions, 0 deletions
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs
new file mode 100644
index 0000000000..8271c40a43
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsByte
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Bytes feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static byte Five = 5;
+ static byte Ten = 10;
+
+ static byte Id(byte x)
+ {
+ return x;
+ }
+
+ static byte F00(byte x)
+ {
+ return (byte) (x * x);
+ }
+
+ static bool Bench00p()
+ {
+ byte t = 10;
+ byte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ byte t = Ten;
+ byte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ byte t = Id(10);
+ byte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ byte t = Id(Ten);
+ byte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ byte t = Id(10);
+ byte f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ byte t = Id(Ten);
+ byte f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ byte t = 10;
+ byte f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ byte t = Ten;
+ byte f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ byte t = 5;
+ byte f = F00((byte)(2 * t));
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ byte t = Five;
+ byte f = F00((byte)(2 * t));
+ return (f == 100);
+ }
+
+ static byte F01(byte x)
+ {
+ return (byte)(1000 / x);
+ }
+
+ static bool Bench01p()
+ {
+ byte t = 10;
+ byte f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ byte t = Ten;
+ byte f = F01(t);
+ return (f == 100);
+ }
+
+ static byte F02(byte x)
+ {
+ return (byte) (20 * (x / 2));
+ }
+
+ static bool Bench02p()
+ {
+ byte t = 10;
+ byte f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ byte t = Ten;
+ byte f = F02(t);
+ return (f == 100);
+ }
+
+ static byte F03(byte x)
+ {
+ return (byte)(91 + 1009 % x);
+ }
+
+ static bool Bench03p()
+ {
+ byte t = 10;
+ byte f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ byte t = Ten;
+ byte f = F03(t);
+ return (f == 100);
+ }
+
+ static byte F04(byte x)
+ {
+ return (byte)(50 * (x % 4));
+ }
+
+ static bool Bench04p()
+ {
+ byte t = 10;
+ byte f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ byte t = Ten;
+ byte f = F04(t);
+ return (f == 100);
+ }
+
+ static byte F05(byte x)
+ {
+ return (byte)((1 << x) - 924);
+ }
+
+ static bool Bench05p()
+ {
+ byte t = 10;
+ byte f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ byte t = Ten;
+ byte f = F05(t);
+ return (f == 100);
+ }
+
+ static byte F051(byte x)
+ {
+ return (byte)(102400 >> x);
+ }
+
+ static bool Bench05p1()
+ {
+ byte t = 10;
+ byte f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ byte t = Ten;
+ byte f = F051(t);
+ return (f == 100);
+ }
+
+ static byte F06(byte x)
+ {
+ return (byte)(-x + 110);
+ }
+
+ static bool Bench06p()
+ {
+ byte t = 10;
+ byte f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ byte t = Ten;
+ byte f = F06(t);
+ return (f == 100);
+ }
+
+ static byte F07(byte x)
+ {
+ return (byte)(~x + 111);
+ }
+
+ static bool Bench07p()
+ {
+ byte t = 10;
+ byte f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ byte t = Ten;
+ byte f = F07(t);
+ return (f == 100);
+ }
+
+ static byte F071(byte x)
+ {
+ return (byte)((x ^ -1) + 111);
+ }
+
+ static bool Bench07p1()
+ {
+ byte t = 10;
+ byte f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ byte t = Ten;
+ byte f = F071(t);
+ return (f == 100);
+ }
+
+ static byte F08(byte x)
+ {
+ return (byte)((x & 0x7) + 98);
+ }
+
+ static bool Bench08p()
+ {
+ byte t = 10;
+ byte f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ byte t = Ten;
+ byte f = F08(t);
+ return (f == 100);
+ }
+
+ static byte F09(byte x)
+ {
+ return (byte)((x | 0x7) + 85);
+ }
+
+ static bool Bench09p()
+ {
+ byte t = 10;
+ byte f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ byte t = Ten;
+ byte f = F09(t);
+ return (f == 100);
+ }
+
+ // Bytes feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static byte F10(byte x)
+ {
+ return x == 10 ? (byte) 100 : (byte) 0;
+ }
+
+ static bool Bench10p()
+ {
+ byte t = 10;
+ byte f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ byte t = Ten;
+ byte f = F10(t);
+ return (f == 100);
+ }
+
+ static byte F101(byte x)
+ {
+ return x != 10 ? (byte) 0 : (byte) 100;
+ }
+
+ static bool Bench10p1()
+ {
+ byte t = 10;
+ byte f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ byte t = Ten;
+ byte f = F101(t);
+ return (f == 100);
+ }
+
+ static byte F102(byte x)
+ {
+ return x >= 10 ? (byte) 100 : (byte) 0;
+ }
+
+ static bool Bench10p2()
+ {
+ byte t = 10;
+ byte f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ byte t = Ten;
+ byte f = F102(t);
+ return (f == 100);
+ }
+
+ static byte F103(byte x)
+ {
+ return x <= 10 ? (byte) 100 : (byte) 0;
+ }
+
+ static bool Bench10p3()
+ {
+ byte t = 10;
+ byte f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ byte t = Ten;
+ byte f = F102(t);
+ return (f == 100);
+ }
+
+ static byte F11(byte x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ byte t = 10;
+ byte f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ byte t = Ten;
+ byte f = F11(t);
+ return (f == 100);
+ }
+
+ static byte F111(byte x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ byte t = 10;
+ byte f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ byte t = Ten;
+ byte f = F111(t);
+ return (f == 100);
+ }
+
+ static byte F112(byte x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ byte t = 10;
+ byte f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ byte t = Ten;
+ byte f = F112(t);
+ return (f == 100);
+ }
+ static byte F113(byte x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ byte t = 10;
+ byte f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ byte t = Ten;
+ byte f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static byte F20(byte x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ byte t = 10;
+ byte f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ byte t = Ten;
+ byte f = F20(t);
+ return (f == 100);
+ }
+
+ static byte F21(byte x)
+ {
+ return (byte)(-x + 100 + x);
+ }
+
+ static bool Bench21p()
+ {
+ byte t = 10;
+ byte f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ byte t = Ten;
+ byte f = F21(t);
+ return (f == 100);
+ }
+
+ static byte F211(byte x)
+ {
+ return (byte)(x - x + 100);
+ }
+
+ static bool Bench21p1()
+ {
+ byte t = 10;
+ byte f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ byte t = Ten;
+ byte f = F211(t);
+ return (f == 100);
+ }
+
+ static byte F22(byte x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ byte t = 10;
+ byte f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ byte t = Ten;
+ byte f = F22(t);
+ return (f == 100);
+ }
+
+ static byte F23(byte x)
+ {
+ if (x > 0)
+ {
+ return (byte)(90 + x);
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ byte t = 10;
+ byte f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ byte t = Ten;
+ byte f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static byte F30(byte x, byte y)
+ {
+ return (byte)(y * y);
+ }
+
+ static bool Bench30p()
+ {
+ byte t = 10;
+ byte f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ byte t = Ten;
+ byte f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ byte s = Ten;
+ byte t = 10;
+ byte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ byte s = 10;
+ byte t = Ten;
+ byte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ byte s = 10;
+ byte t = 10;
+ byte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ byte s = Ten;
+ byte t = Ten;
+ byte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ byte s = 10;
+ byte t = s;
+ byte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ byte s = Ten;
+ byte t = s;
+ byte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static byte F31(byte x, byte y, byte z)
+ {
+ return (byte)(z * z);
+ }
+
+ static bool Bench31p()
+ {
+ byte t = 10;
+ byte f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ byte t = Ten;
+ byte f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ byte r = Ten;
+ byte s = Ten;
+ byte t = 10;
+ byte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ byte r = 10;
+ byte s = 10;
+ byte t = Ten;
+ byte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ byte r = 10;
+ byte s = 10;
+ byte t = 10;
+ byte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ byte r = Ten;
+ byte s = Ten;
+ byte t = Ten;
+ byte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ byte r = 10;
+ byte s = r;
+ byte t = s;
+ byte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ byte r = Ten;
+ byte s = r;
+ byte t = s;
+ byte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static byte F40(byte x, byte y)
+ {
+ return (byte)(x * x + y * y - 100);
+ }
+
+ static bool Bench40p()
+ {
+ byte t = 10;
+ byte f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ byte t = Ten;
+ byte f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ byte s = Ten;
+ byte t = 10;
+ byte f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ byte s = 10;
+ byte t = Ten;
+ byte f = F40(s, t);
+ return (f == 100);
+ }
+
+ static byte F41(byte x, byte y)
+ {
+ return (byte)(x * y);
+ }
+
+ static bool Bench41p()
+ {
+ byte t = 10;
+ byte f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ byte t = Ten;
+ byte f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ byte s = 10;
+ byte t = Ten;
+ byte f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ byte s = Ten;
+ byte t = 10;
+ byte f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsByte).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.csproj
new file mode 100644
index 0000000000..c8319ca32f
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsByte.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs
new file mode 100644
index 0000000000..0d1f9284ba
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsChar
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Chars feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static char Five = (char) 5;
+ static char Ten = (char) 10;
+
+ static char Id(char x)
+ {
+ return x;
+ }
+
+ static char F00(char x)
+ {
+ return (char) (x * x);
+ }
+
+ static bool Bench00p()
+ {
+ char t = (char) 10;
+ char f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ char t = Ten;
+ char f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ char t = Id((char)10);
+ char f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ char t = Id(Ten);
+ char f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ char t = Id((char)10);
+ char f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ char t = Id(Ten);
+ char f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ char t = (char) 10;
+ char f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ char t = Ten;
+ char f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ char t = (char) 5;
+ char f = F00((char)(2 * t));
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ char t = Five;
+ char f = F00((char)(2 * t));
+ return (f == 100);
+ }
+
+ static char F01(char x)
+ {
+ return (char)(1000 / x);
+ }
+
+ static bool Bench01p()
+ {
+ char t = (char) 10;
+ char f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ char t = Ten;
+ char f = F01(t);
+ return (f == 100);
+ }
+
+ static char F02(char x)
+ {
+ return (char) (20 * (x / 2));
+ }
+
+ static bool Bench02p()
+ {
+ char t = (char) 10;
+ char f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ char t = Ten;
+ char f = F02(t);
+ return (f == 100);
+ }
+
+ static char F03(char x)
+ {
+ return (char)(91 + 1009 % x);
+ }
+
+ static bool Bench03p()
+ {
+ char t = (char) 10;
+ char f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ char t = Ten;
+ char f = F03(t);
+ return (f == 100);
+ }
+
+ static char F04(char x)
+ {
+ return (char)(50 * (x % 4));
+ }
+
+ static bool Bench04p()
+ {
+ char t = (char) 10;
+ char f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ char t = Ten;
+ char f = F04(t);
+ return (f == 100);
+ }
+
+ static char F05(char x)
+ {
+ return (char)((1 << x) - 924);
+ }
+
+ static bool Bench05p()
+ {
+ char t = (char) 10;
+ char f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ char t = Ten;
+ char f = F05(t);
+ return (f == 100);
+ }
+
+ static char F051(char x)
+ {
+ return (char)(102400 >> x);
+ }
+
+ static bool Bench05p1()
+ {
+ char t = (char) 10;
+ char f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ char t = Ten;
+ char f = F051(t);
+ return (f == 100);
+ }
+
+ static char F06(char x)
+ {
+ return (char)(-x + 110);
+ }
+
+ static bool Bench06p()
+ {
+ char t = (char) 10;
+ char f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ char t = Ten;
+ char f = F06(t);
+ return (f == 100);
+ }
+
+ static char F07(char x)
+ {
+ return (char)(~x + 111);
+ }
+
+ static bool Bench07p()
+ {
+ char t = (char) 10;
+ char f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ char t = Ten;
+ char f = F07(t);
+ return (f == 100);
+ }
+
+ static char F071(char x)
+ {
+ return (char)((x ^ -1) + 111);
+ }
+
+ static bool Bench07p1()
+ {
+ char t = (char) 10;
+ char f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ char t = Ten;
+ char f = F071(t);
+ return (f == 100);
+ }
+
+ static char F08(char x)
+ {
+ return (char)((x & 0x7) + 98);
+ }
+
+ static bool Bench08p()
+ {
+ char t = (char) 10;
+ char f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ char t = Ten;
+ char f = F08(t);
+ return (f == 100);
+ }
+
+ static char F09(char x)
+ {
+ return (char)((x | 0x7) + 85);
+ }
+
+ static bool Bench09p()
+ {
+ char t = (char) 10;
+ char f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ char t = Ten;
+ char f = F09(t);
+ return (f == 100);
+ }
+
+ // Chars feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static char F10(char x)
+ {
+ return x == 10 ? (char) 100 : (char) 0;
+ }
+
+ static bool Bench10p()
+ {
+ char t = (char) 10;
+ char f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ char t = Ten;
+ char f = F10(t);
+ return (f == 100);
+ }
+
+ static char F101(char x)
+ {
+ return x != 10 ? (char) 0 : (char) 100;
+ }
+
+ static bool Bench10p1()
+ {
+ char t = (char) 10;
+ char f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ char t = Ten;
+ char f = F101(t);
+ return (f == 100);
+ }
+
+ static char F102(char x)
+ {
+ return x >= 10 ? (char) 100 : (char) 0;
+ }
+
+ static bool Bench10p2()
+ {
+ char t = (char) 10;
+ char f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ char t = Ten;
+ char f = F102(t);
+ return (f == 100);
+ }
+
+ static char F103(char x)
+ {
+ return x <= 10 ? (char) 100 : (char) 0;
+ }
+
+ static bool Bench10p3()
+ {
+ char t = (char) 10;
+ char f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ char t = Ten;
+ char f = F102(t);
+ return (f == 100);
+ }
+
+ static char F11(char x)
+ {
+ if (x == 10)
+ {
+ return (char) 100;
+ }
+ else
+ {
+ return (char) 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ char t = (char) 10;
+ char f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ char t = Ten;
+ char f = F11(t);
+ return (f == 100);
+ }
+
+ static char F111(char x)
+ {
+ if (x != 10)
+ {
+ return (char) 0;
+ }
+ else
+ {
+ return (char) 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ char t = (char) 10;
+ char f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ char t = Ten;
+ char f = F111(t);
+ return (f == 100);
+ }
+
+ static char F112(char x)
+ {
+ if (x > 10)
+ {
+ return (char) 0;
+ }
+ else
+ {
+ return (char) 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ char t = (char) 10;
+ char f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ char t = Ten;
+ char f = F112(t);
+ return (f == 100);
+ }
+ static char F113(char x)
+ {
+ if (x < 10)
+ {
+ return (char) 0;
+ }
+ else
+ {
+ return (char) 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ char t = (char) 10;
+ char f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ char t = Ten;
+ char f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static char F20(char x)
+ {
+ return (char) 100;
+ }
+
+ static bool Bench20p()
+ {
+ char t = (char) 10;
+ char f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ char t = Ten;
+ char f = F20(t);
+ return (f == 100);
+ }
+
+ static char F21(char x)
+ {
+ return (char)(-x + 100 + x);
+ }
+
+ static bool Bench21p()
+ {
+ char t = (char) 10;
+ char f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ char t = Ten;
+ char f = F21(t);
+ return (f == 100);
+ }
+
+ static char F211(char x)
+ {
+ return (char)(x - x + 100);
+ }
+
+ static bool Bench21p1()
+ {
+ char t = (char) 10;
+ char f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ char t = Ten;
+ char f = F211(t);
+ return (f == 100);
+ }
+
+ static char F22(char x)
+ {
+ if (x > 0)
+ {
+ return (char) 100;
+ }
+
+ return (char) 100;
+ }
+
+ static bool Bench22p()
+ {
+ char t = (char) 10;
+ char f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ char t = Ten;
+ char f = F22(t);
+ return (f == 100);
+ }
+
+ static char F23(char x)
+ {
+ if (x > 0)
+ {
+ return (char)(90 + x);
+ }
+
+ return (char) 100;
+ }
+
+ static bool Bench23p()
+ {
+ char t = (char) 10;
+ char f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ char t = Ten;
+ char f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static char F30(char x, char y)
+ {
+ return (char)(y * y);
+ }
+
+ static bool Bench30p()
+ {
+ char t = (char) 10;
+ char f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ char t = Ten;
+ char f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ char s = Ten;
+ char t = (char) 10;
+ char f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ char s = (char) 10;
+ char t = Ten;
+ char f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ char s = (char) 10;
+ char t = (char) 10;
+ char f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ char s = Ten;
+ char t = Ten;
+ char f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ char s = (char) 10;
+ char t = s;
+ char f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ char s = Ten;
+ char t = s;
+ char f = F30(s, t);
+ return (f == 100);
+ }
+
+ static char F31(char x, char y, char z)
+ {
+ return (char)(z * z);
+ }
+
+ static bool Bench31p()
+ {
+ char t = (char) 10;
+ char f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ char t = Ten;
+ char f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ char r = Ten;
+ char s = Ten;
+ char t = (char) 10;
+ char f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ char r = (char) 10;
+ char s = (char) 10;
+ char t = Ten;
+ char f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ char r = (char) 10;
+ char s = (char) 10;
+ char t = (char) 10;
+ char f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ char r = Ten;
+ char s = Ten;
+ char t = Ten;
+ char f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ char r = (char) 10;
+ char s = r;
+ char t = s;
+ char f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ char r = Ten;
+ char s = r;
+ char t = s;
+ char f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static char F40(char x, char y)
+ {
+ return (char)(x * x + y * y - 100);
+ }
+
+ static bool Bench40p()
+ {
+ char t = (char) 10;
+ char f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ char t = Ten;
+ char f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ char s = Ten;
+ char t = (char) 10;
+ char f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ char s = (char) 10;
+ char t = Ten;
+ char f = F40(s, t);
+ return (f == 100);
+ }
+
+ static char F41(char x, char y)
+ {
+ return (char)(x * y);
+ }
+
+ static bool Bench41p()
+ {
+ char t = (char) 10;
+ char f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ char t = Ten;
+ char f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ char s = (char) 10;
+ char t = Ten;
+ char f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ char s = Ten;
+ char t = (char) 10;
+ char f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsChar).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.csproj
new file mode 100644
index 0000000000..e0f78ff254
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsChar.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs
new file mode 100644
index 0000000000..6c95d482d5
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs
@@ -0,0 +1,810 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsDouble
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Doubles feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static double Five = 5;
+ static double Ten = 10;
+
+ static double Id(double x)
+ {
+ return x;
+ }
+
+ static double F00(double x)
+ {
+ return x * x;
+ }
+
+ static bool Bench00p()
+ {
+ double t = 10;
+ double f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ double t = Ten;
+ double f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ double t = Id(10);
+ double f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ double t = Id(Ten);
+ double f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ double t = Id(10);
+ double f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ double t = Id(Ten);
+ double f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ double t = 10;
+ double f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ double t = Ten;
+ double f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ double t = 5;
+ double f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ double t = Five;
+ double f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static double F01(double x)
+ {
+ return 1000 / x;
+ }
+
+ static bool Bench01p()
+ {
+ double t = 10;
+ double f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ double t = Ten;
+ double f = F01(t);
+ return (f == 100);
+ }
+
+ static double F02(double x)
+ {
+ return 20 * (x / 2);
+ }
+
+ static bool Bench02p()
+ {
+ double t = 10;
+ double f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ double t = Ten;
+ double f = F02(t);
+ return (f == 100);
+ }
+
+ static double F03(double x)
+ {
+ return 91 + 1009 % x;
+ }
+
+ static bool Bench03p()
+ {
+ double t = 10;
+ double f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ double t = Ten;
+ double f = F03(t);
+ return (f == 100);
+ }
+
+ static double F04(double x)
+ {
+ return 50 * (x % 4);
+ }
+
+ static bool Bench04p()
+ {
+ double t = 10;
+ double f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ double t = Ten;
+ double f = F04(t);
+ return (f == 100);
+ }
+
+ static double F06(double x)
+ {
+ return -x + 110;
+ }
+
+ static bool Bench06p()
+ {
+ double t = 10;
+ double f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ double t = Ten;
+ double f = F06(t);
+ return (f == 100);
+ }
+
+ // Doubles feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static double F10(double x)
+ {
+ return x == 10 ? 100 : 0;
+ }
+
+ static bool Bench10p()
+ {
+ double t = 10;
+ double f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ double t = Ten;
+ double f = F10(t);
+ return (f == 100);
+ }
+
+ static double F101(double x)
+ {
+ return x != 10 ? 0 : 100;
+ }
+
+ static bool Bench10p1()
+ {
+ double t = 10;
+ double f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ double t = Ten;
+ double f = F101(t);
+ return (f == 100);
+ }
+
+ static double F102(double x)
+ {
+ return x >= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p2()
+ {
+ double t = 10;
+ double f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ double t = Ten;
+ double f = F102(t);
+ return (f == 100);
+ }
+
+ static double F103(double x)
+ {
+ return x <= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p3()
+ {
+ double t = 10;
+ double f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ double t = Ten;
+ double f = F102(t);
+ return (f == 100);
+ }
+
+ static double F11(double x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ double t = 10;
+ double f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ double t = Ten;
+ double f = F11(t);
+ return (f == 100);
+ }
+
+ static double F111(double x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ double t = 10;
+ double f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ double t = Ten;
+ double f = F111(t);
+ return (f == 100);
+ }
+
+ static double F112(double x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ double t = 10;
+ double f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ double t = Ten;
+ double f = F112(t);
+ return (f == 100);
+ }
+ static double F113(double x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ double t = 10;
+ double f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ double t = Ten;
+ double f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static double F20(double x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ double t = 10;
+ double f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ double t = Ten;
+ double f = F20(t);
+ return (f == 100);
+ }
+
+ static double F21(double x)
+ {
+ return -x + 100 + x;
+ }
+
+ static bool Bench21p()
+ {
+ double t = 10;
+ double f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ double t = Ten;
+ double f = F21(t);
+ return (f == 100);
+ }
+
+ static double F211(double x)
+ {
+ return x - x + 100;
+ }
+
+ static bool Bench21p1()
+ {
+ double t = 10;
+ double f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ double t = Ten;
+ double f = F211(t);
+ return (f == 100);
+ }
+
+ static double F22(double x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ double t = 10;
+ double f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ double t = Ten;
+ double f = F22(t);
+ return (f == 100);
+ }
+
+ static double F23(double x)
+ {
+ if (x > 0)
+ {
+ return 90 + x;
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ double t = 10;
+ double f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ double t = Ten;
+ double f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static double F30(double x, double y)
+ {
+ return y * y;
+ }
+
+ static bool Bench30p()
+ {
+ double t = 10;
+ double f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ double t = Ten;
+ double f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ double s = Ten;
+ double t = 10;
+ double f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ double s = 10;
+ double t = Ten;
+ double f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ double s = 10;
+ double t = 10;
+ double f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ double s = Ten;
+ double t = Ten;
+ double f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ double s = 10;
+ double t = s;
+ double f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ double s = Ten;
+ double t = s;
+ double f = F30(s, t);
+ return (f == 100);
+ }
+
+ static double F31(double x, double y, double z)
+ {
+ return z * z;
+ }
+
+ static bool Bench31p()
+ {
+ double t = 10;
+ double f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ double t = Ten;
+ double f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ double r = Ten;
+ double s = Ten;
+ double t = 10;
+ double f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ double r = 10;
+ double s = 10;
+ double t = Ten;
+ double f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ double r = 10;
+ double s = 10;
+ double t = 10;
+ double f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ double r = Ten;
+ double s = Ten;
+ double t = Ten;
+ double f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ double r = 10;
+ double s = r;
+ double t = s;
+ double f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ double r = Ten;
+ double s = r;
+ double t = s;
+ double f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static double F40(double x, double y)
+ {
+ return x * x + y * y - 100;
+ }
+
+ static bool Bench40p()
+ {
+ double t = 10;
+ double f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ double t = Ten;
+ double f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ double s = Ten;
+ double t = 10;
+ double f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ double s = 10;
+ double t = Ten;
+ double f = F40(s, t);
+ return (f == 100);
+ }
+
+ static double F41(double x, double y)
+ {
+ return x * y;
+ }
+
+ static bool Bench41p()
+ {
+ double t = 10;
+ double f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ double t = Ten;
+ double f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ double s = 10;
+ double t = Ten;
+ double f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ double s = Ten;
+ double t = 10;
+ double f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench06p", "Bench06n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsDouble).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.csproj
new file mode 100644
index 0000000000..60de76c39f
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsDouble.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs
new file mode 100644
index 0000000000..bbd65a4004
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs
@@ -0,0 +1,810 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsFloat
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Floats feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static float Five = 5;
+ static float Ten = 10;
+
+ static float Id(float x)
+ {
+ return x;
+ }
+
+ static float F00(float x)
+ {
+ return x * x;
+ }
+
+ static bool Bench00p()
+ {
+ float t = 10;
+ float f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ float t = Ten;
+ float f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ float t = Id(10);
+ float f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ float t = Id(Ten);
+ float f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ float t = Id(10);
+ float f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ float t = Id(Ten);
+ float f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ float t = 10;
+ float f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ float t = Ten;
+ float f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ float t = 5;
+ float f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ float t = Five;
+ float f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static float F01(float x)
+ {
+ return 1000 / x;
+ }
+
+ static bool Bench01p()
+ {
+ float t = 10;
+ float f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ float t = Ten;
+ float f = F01(t);
+ return (f == 100);
+ }
+
+ static float F02(float x)
+ {
+ return 20 * (x / 2);
+ }
+
+ static bool Bench02p()
+ {
+ float t = 10;
+ float f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ float t = Ten;
+ float f = F02(t);
+ return (f == 100);
+ }
+
+ static float F03(float x)
+ {
+ return 91 + 1009 % x;
+ }
+
+ static bool Bench03p()
+ {
+ float t = 10;
+ float f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ float t = Ten;
+ float f = F03(t);
+ return (f == 100);
+ }
+
+ static float F04(float x)
+ {
+ return 50 * (x % 4);
+ }
+
+ static bool Bench04p()
+ {
+ float t = 10;
+ float f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ float t = Ten;
+ float f = F04(t);
+ return (f == 100);
+ }
+
+ static float F06(float x)
+ {
+ return -x + 110;
+ }
+
+ static bool Bench06p()
+ {
+ float t = 10;
+ float f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ float t = Ten;
+ float f = F06(t);
+ return (f == 100);
+ }
+
+ // Floats feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static float F10(float x)
+ {
+ return x == 10 ? 100 : 0;
+ }
+
+ static bool Bench10p()
+ {
+ float t = 10;
+ float f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ float t = Ten;
+ float f = F10(t);
+ return (f == 100);
+ }
+
+ static float F101(float x)
+ {
+ return x != 10 ? 0 : 100;
+ }
+
+ static bool Bench10p1()
+ {
+ float t = 10;
+ float f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ float t = Ten;
+ float f = F101(t);
+ return (f == 100);
+ }
+
+ static float F102(float x)
+ {
+ return x >= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p2()
+ {
+ float t = 10;
+ float f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ float t = Ten;
+ float f = F102(t);
+ return (f == 100);
+ }
+
+ static float F103(float x)
+ {
+ return x <= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p3()
+ {
+ float t = 10;
+ float f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ float t = Ten;
+ float f = F102(t);
+ return (f == 100);
+ }
+
+ static float F11(float x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ float t = 10;
+ float f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ float t = Ten;
+ float f = F11(t);
+ return (f == 100);
+ }
+
+ static float F111(float x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ float t = 10;
+ float f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ float t = Ten;
+ float f = F111(t);
+ return (f == 100);
+ }
+
+ static float F112(float x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ float t = 10;
+ float f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ float t = Ten;
+ float f = F112(t);
+ return (f == 100);
+ }
+ static float F113(float x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ float t = 10;
+ float f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ float t = Ten;
+ float f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static float F20(float x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ float t = 10;
+ float f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ float t = Ten;
+ float f = F20(t);
+ return (f == 100);
+ }
+
+ static float F21(float x)
+ {
+ return -x + 100 + x;
+ }
+
+ static bool Bench21p()
+ {
+ float t = 10;
+ float f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ float t = Ten;
+ float f = F21(t);
+ return (f == 100);
+ }
+
+ static float F211(float x)
+ {
+ return x - x + 100;
+ }
+
+ static bool Bench21p1()
+ {
+ float t = 10;
+ float f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ float t = Ten;
+ float f = F211(t);
+ return (f == 100);
+ }
+
+ static float F22(float x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ float t = 10;
+ float f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ float t = Ten;
+ float f = F22(t);
+ return (f == 100);
+ }
+
+ static float F23(float x)
+ {
+ if (x > 0)
+ {
+ return 90 + x;
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ float t = 10;
+ float f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ float t = Ten;
+ float f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static float F30(float x, float y)
+ {
+ return y * y;
+ }
+
+ static bool Bench30p()
+ {
+ float t = 10;
+ float f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ float t = Ten;
+ float f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ float s = Ten;
+ float t = 10;
+ float f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ float s = 10;
+ float t = Ten;
+ float f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ float s = 10;
+ float t = 10;
+ float f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ float s = Ten;
+ float t = Ten;
+ float f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ float s = 10;
+ float t = s;
+ float f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ float s = Ten;
+ float t = s;
+ float f = F30(s, t);
+ return (f == 100);
+ }
+
+ static float F31(float x, float y, float z)
+ {
+ return z * z;
+ }
+
+ static bool Bench31p()
+ {
+ float t = 10;
+ float f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ float t = Ten;
+ float f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ float r = Ten;
+ float s = Ten;
+ float t = 10;
+ float f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ float r = 10;
+ float s = 10;
+ float t = Ten;
+ float f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ float r = 10;
+ float s = 10;
+ float t = 10;
+ float f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ float r = Ten;
+ float s = Ten;
+ float t = Ten;
+ float f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ float r = 10;
+ float s = r;
+ float t = s;
+ float f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ float r = Ten;
+ float s = r;
+ float t = s;
+ float f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static float F40(float x, float y)
+ {
+ return x * x + y * y - 100;
+ }
+
+ static bool Bench40p()
+ {
+ float t = 10;
+ float f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ float t = Ten;
+ float f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ float s = Ten;
+ float t = 10;
+ float f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ float s = 10;
+ float t = Ten;
+ float f = F40(s, t);
+ return (f == 100);
+ }
+
+ static float F41(float x, float y)
+ {
+ return x * y;
+ }
+
+ static bool Bench41p()
+ {
+ float t = 10;
+ float f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ float t = Ten;
+ float f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ float s = 10;
+ float t = Ten;
+ float f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ float s = Ten;
+ float t = 10;
+ float f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench06p", "Bench06n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsFloat).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.csproj
new file mode 100644
index 0000000000..70b3e29a97
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsFloat.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs
new file mode 100644
index 0000000000..03d59f93d0
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsInt
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Ints feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static int Five = 5;
+ static int Ten = 10;
+
+ static int Id(int x)
+ {
+ return x;
+ }
+
+ static int F00(int x)
+ {
+ return x * x;
+ }
+
+ static bool Bench00p()
+ {
+ int t = 10;
+ int f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ int t = Ten;
+ int f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ int t = Id(10);
+ int f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ int t = Id(Ten);
+ int f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ int t = Id(10);
+ int f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ int t = Id(Ten);
+ int f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ int t = 10;
+ int f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ int t = Ten;
+ int f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ int t = 5;
+ int f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ int t = Five;
+ int f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static int F01(int x)
+ {
+ return 1000 / x;
+ }
+
+ static bool Bench01p()
+ {
+ int t = 10;
+ int f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ int t = Ten;
+ int f = F01(t);
+ return (f == 100);
+ }
+
+ static int F02(int x)
+ {
+ return 20 * (x / 2);
+ }
+
+ static bool Bench02p()
+ {
+ int t = 10;
+ int f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ int t = Ten;
+ int f = F02(t);
+ return (f == 100);
+ }
+
+ static int F03(int x)
+ {
+ return 91 + 1009 % x;
+ }
+
+ static bool Bench03p()
+ {
+ int t = 10;
+ int f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ int t = Ten;
+ int f = F03(t);
+ return (f == 100);
+ }
+
+ static int F04(int x)
+ {
+ return 50 * (x % 4);
+ }
+
+ static bool Bench04p()
+ {
+ int t = 10;
+ int f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ int t = Ten;
+ int f = F04(t);
+ return (f == 100);
+ }
+
+ static int F05(int x)
+ {
+ return (1 << x) - 924;
+ }
+
+ static bool Bench05p()
+ {
+ int t = 10;
+ int f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ int t = Ten;
+ int f = F05(t);
+ return (f == 100);
+ }
+
+ static int F051(int x)
+ {
+ return (102400 >> x);
+ }
+
+ static bool Bench05p1()
+ {
+ int t = 10;
+ int f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ int t = Ten;
+ int f = F051(t);
+ return (f == 100);
+ }
+
+ static int F06(int x)
+ {
+ return -x + 110;
+ }
+
+ static bool Bench06p()
+ {
+ int t = 10;
+ int f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ int t = Ten;
+ int f = F06(t);
+ return (f == 100);
+ }
+
+ static int F07(int x)
+ {
+ return ~x + 111;
+ }
+
+ static bool Bench07p()
+ {
+ int t = 10;
+ int f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ int t = Ten;
+ int f = F07(t);
+ return (f == 100);
+ }
+
+ static int F071(int x)
+ {
+ return (x ^ -1) + 111;
+ }
+
+ static bool Bench07p1()
+ {
+ int t = 10;
+ int f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ int t = Ten;
+ int f = F071(t);
+ return (f == 100);
+ }
+
+ static int F08(int x)
+ {
+ return (x & 0x7) + 98;
+ }
+
+ static bool Bench08p()
+ {
+ int t = 10;
+ int f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ int t = Ten;
+ int f = F08(t);
+ return (f == 100);
+ }
+
+ static int F09(int x)
+ {
+ return (x | 0x7) + 85;
+ }
+
+ static bool Bench09p()
+ {
+ int t = 10;
+ int f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ int t = Ten;
+ int f = F09(t);
+ return (f == 100);
+ }
+
+ // Ints feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static int F10(int x)
+ {
+ return x == 10 ? 100 : 0;
+ }
+
+ static bool Bench10p()
+ {
+ int t = 10;
+ int f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ int t = Ten;
+ int f = F10(t);
+ return (f == 100);
+ }
+
+ static int F101(int x)
+ {
+ return x != 10 ? 0 : 100;
+ }
+
+ static bool Bench10p1()
+ {
+ int t = 10;
+ int f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ int t = Ten;
+ int f = F101(t);
+ return (f == 100);
+ }
+
+ static int F102(int x)
+ {
+ return x >= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p2()
+ {
+ int t = 10;
+ int f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ int t = Ten;
+ int f = F102(t);
+ return (f == 100);
+ }
+
+ static int F103(int x)
+ {
+ return x <= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p3()
+ {
+ int t = 10;
+ int f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ int t = Ten;
+ int f = F102(t);
+ return (f == 100);
+ }
+
+ static int F11(int x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ int t = 10;
+ int f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ int t = Ten;
+ int f = F11(t);
+ return (f == 100);
+ }
+
+ static int F111(int x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ int t = 10;
+ int f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ int t = Ten;
+ int f = F111(t);
+ return (f == 100);
+ }
+
+ static int F112(int x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ int t = 10;
+ int f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ int t = Ten;
+ int f = F112(t);
+ return (f == 100);
+ }
+ static int F113(int x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ int t = 10;
+ int f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ int t = Ten;
+ int f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static int F20(int x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ int t = 10;
+ int f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ int t = Ten;
+ int f = F20(t);
+ return (f == 100);
+ }
+
+ static int F21(int x)
+ {
+ return -x + 100 + x;
+ }
+
+ static bool Bench21p()
+ {
+ int t = 10;
+ int f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ int t = Ten;
+ int f = F21(t);
+ return (f == 100);
+ }
+
+ static int F211(int x)
+ {
+ return x - x + 100;
+ }
+
+ static bool Bench21p1()
+ {
+ int t = 10;
+ int f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ int t = Ten;
+ int f = F211(t);
+ return (f == 100);
+ }
+
+ static int F22(int x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ int t = 10;
+ int f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ int t = Ten;
+ int f = F22(t);
+ return (f == 100);
+ }
+
+ static int F23(int x)
+ {
+ if (x > 0)
+ {
+ return 90 + x;
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ int t = 10;
+ int f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ int t = Ten;
+ int f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static int F30(int x, int y)
+ {
+ return y * y;
+ }
+
+ static bool Bench30p()
+ {
+ int t = 10;
+ int f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ int t = Ten;
+ int f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ int s = Ten;
+ int t = 10;
+ int f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ int s = 10;
+ int t = Ten;
+ int f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ int s = 10;
+ int t = 10;
+ int f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ int s = Ten;
+ int t = Ten;
+ int f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ int s = 10;
+ int t = s;
+ int f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ int s = Ten;
+ int t = s;
+ int f = F30(s, t);
+ return (f == 100);
+ }
+
+ static int F31(int x, int y, int z)
+ {
+ return z * z;
+ }
+
+ static bool Bench31p()
+ {
+ int t = 10;
+ int f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ int t = Ten;
+ int f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ int r = Ten;
+ int s = Ten;
+ int t = 10;
+ int f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ int r = 10;
+ int s = 10;
+ int t = Ten;
+ int f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ int r = 10;
+ int s = 10;
+ int t = 10;
+ int f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ int r = Ten;
+ int s = Ten;
+ int t = Ten;
+ int f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ int r = 10;
+ int s = r;
+ int t = s;
+ int f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ int r = Ten;
+ int s = r;
+ int t = s;
+ int f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static int F40(int x, int y)
+ {
+ return x * x + y * y - 100;
+ }
+
+ static bool Bench40p()
+ {
+ int t = 10;
+ int f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ int t = Ten;
+ int f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ int s = Ten;
+ int t = 10;
+ int f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ int s = 10;
+ int t = Ten;
+ int f = F40(s, t);
+ return (f == 100);
+ }
+
+ static int F41(int x, int y)
+ {
+ return x * y;
+ }
+
+ static bool Bench41p()
+ {
+ int t = 10;
+ int f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ int t = Ten;
+ int f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ int s = 10;
+ int t = Ten;
+ int f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ int s = Ten;
+ int t = 10;
+ int f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsInt).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.csproj
new file mode 100644
index 0000000000..f5f361032a
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsInt.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs
new file mode 100644
index 0000000000..f4e45f50db
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsLong
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Longs feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static long Five = 5;
+ static long Ten = 10;
+
+ static long Id(long x)
+ {
+ return x;
+ }
+
+ static long F00(long x)
+ {
+ return x * x;
+ }
+
+ static bool Bench00p()
+ {
+ long t = 10;
+ long f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ long t = Ten;
+ long f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ long t = Id(10);
+ long f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ long t = Id(Ten);
+ long f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ long t = Id(10);
+ long f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ long t = Id(Ten);
+ long f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ long t = 10;
+ long f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ long t = Ten;
+ long f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ long t = 5;
+ long f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ long t = Five;
+ long f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static long F01(long x)
+ {
+ return 1000 / x;
+ }
+
+ static bool Bench01p()
+ {
+ long t = 10;
+ long f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ long t = Ten;
+ long f = F01(t);
+ return (f == 100);
+ }
+
+ static long F02(long x)
+ {
+ return 20 * (x / 2);
+ }
+
+ static bool Bench02p()
+ {
+ long t = 10;
+ long f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ long t = Ten;
+ long f = F02(t);
+ return (f == 100);
+ }
+
+ static long F03(long x)
+ {
+ return 91 + 1009 % x;
+ }
+
+ static bool Bench03p()
+ {
+ long t = 10;
+ long f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ long t = Ten;
+ long f = F03(t);
+ return (f == 100);
+ }
+
+ static long F04(long x)
+ {
+ return 50 * (x % 4);
+ }
+
+ static bool Bench04p()
+ {
+ long t = 10;
+ long f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ long t = Ten;
+ long f = F04(t);
+ return (f == 100);
+ }
+
+ static long F05(long x)
+ {
+ return (1 << (int) x) - 924;
+ }
+
+ static bool Bench05p()
+ {
+ long t = 10;
+ long f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ long t = Ten;
+ long f = F05(t);
+ return (f == 100);
+ }
+
+ static long F051(long x)
+ {
+ return (102400 >> (int) x);
+ }
+
+ static bool Bench05p1()
+ {
+ long t = 10;
+ long f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ long t = Ten;
+ long f = F051(t);
+ return (f == 100);
+ }
+
+ static long F06(long x)
+ {
+ return -x + 110;
+ }
+
+ static bool Bench06p()
+ {
+ long t = 10;
+ long f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ long t = Ten;
+ long f = F06(t);
+ return (f == 100);
+ }
+
+ static long F07(long x)
+ {
+ return ~x + 111;
+ }
+
+ static bool Bench07p()
+ {
+ long t = 10;
+ long f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ long t = Ten;
+ long f = F07(t);
+ return (f == 100);
+ }
+
+ static long F071(long x)
+ {
+ return (x ^ -1) + 111;
+ }
+
+ static bool Bench07p1()
+ {
+ long t = 10;
+ long f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ long t = Ten;
+ long f = F071(t);
+ return (f == 100);
+ }
+
+ static long F08(long x)
+ {
+ return (x & 0x7) + 98;
+ }
+
+ static bool Bench08p()
+ {
+ long t = 10;
+ long f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ long t = Ten;
+ long f = F08(t);
+ return (f == 100);
+ }
+
+ static long F09(long x)
+ {
+ return (x | 0x7) + 85;
+ }
+
+ static bool Bench09p()
+ {
+ long t = 10;
+ long f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ long t = Ten;
+ long f = F09(t);
+ return (f == 100);
+ }
+
+ // Longs feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static long F10(long x)
+ {
+ return x == 10 ? 100 : 0;
+ }
+
+ static bool Bench10p()
+ {
+ long t = 10;
+ long f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ long t = Ten;
+ long f = F10(t);
+ return (f == 100);
+ }
+
+ static long F101(long x)
+ {
+ return x != 10 ? 0 : 100;
+ }
+
+ static bool Bench10p1()
+ {
+ long t = 10;
+ long f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ long t = Ten;
+ long f = F101(t);
+ return (f == 100);
+ }
+
+ static long F102(long x)
+ {
+ return x >= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p2()
+ {
+ long t = 10;
+ long f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ long t = Ten;
+ long f = F102(t);
+ return (f == 100);
+ }
+
+ static long F103(long x)
+ {
+ return x <= 10 ? 100 : 0;
+ }
+
+ static bool Bench10p3()
+ {
+ long t = 10;
+ long f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ long t = Ten;
+ long f = F102(t);
+ return (f == 100);
+ }
+
+ static long F11(long x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ long t = 10;
+ long f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ long t = Ten;
+ long f = F11(t);
+ return (f == 100);
+ }
+
+ static long F111(long x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ long t = 10;
+ long f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ long t = Ten;
+ long f = F111(t);
+ return (f == 100);
+ }
+
+ static long F112(long x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ long t = 10;
+ long f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ long t = Ten;
+ long f = F112(t);
+ return (f == 100);
+ }
+ static long F113(long x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ long t = 10;
+ long f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ long t = Ten;
+ long f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static long F20(long x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ long t = 10;
+ long f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ long t = Ten;
+ long f = F20(t);
+ return (f == 100);
+ }
+
+ static long F21(long x)
+ {
+ return -x + 100 + x;
+ }
+
+ static bool Bench21p()
+ {
+ long t = 10;
+ long f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ long t = Ten;
+ long f = F21(t);
+ return (f == 100);
+ }
+
+ static long F211(long x)
+ {
+ return x - x + 100;
+ }
+
+ static bool Bench21p1()
+ {
+ long t = 10;
+ long f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ long t = Ten;
+ long f = F211(t);
+ return (f == 100);
+ }
+
+ static long F22(long x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ long t = 10;
+ long f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ long t = Ten;
+ long f = F22(t);
+ return (f == 100);
+ }
+
+ static long F23(long x)
+ {
+ if (x > 0)
+ {
+ return 90 + x;
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ long t = 10;
+ long f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ long t = Ten;
+ long f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static long F30(long x, long y)
+ {
+ return y * y;
+ }
+
+ static bool Bench30p()
+ {
+ long t = 10;
+ long f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ long t = Ten;
+ long f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ long s = Ten;
+ long t = 10;
+ long f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ long s = 10;
+ long t = Ten;
+ long f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ long s = 10;
+ long t = 10;
+ long f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ long s = Ten;
+ long t = Ten;
+ long f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ long s = 10;
+ long t = s;
+ long f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ long s = Ten;
+ long t = s;
+ long f = F30(s, t);
+ return (f == 100);
+ }
+
+ static long F31(long x, long y, long z)
+ {
+ return z * z;
+ }
+
+ static bool Bench31p()
+ {
+ long t = 10;
+ long f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ long t = Ten;
+ long f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ long r = Ten;
+ long s = Ten;
+ long t = 10;
+ long f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ long r = 10;
+ long s = 10;
+ long t = Ten;
+ long f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ long r = 10;
+ long s = 10;
+ long t = 10;
+ long f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ long r = Ten;
+ long s = Ten;
+ long t = Ten;
+ long f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ long r = 10;
+ long s = r;
+ long t = s;
+ long f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ long r = Ten;
+ long s = r;
+ long t = s;
+ long f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static long F40(long x, long y)
+ {
+ return x * x + y * y - 100;
+ }
+
+ static bool Bench40p()
+ {
+ long t = 10;
+ long f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ long t = Ten;
+ long f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ long s = Ten;
+ long t = 10;
+ long f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ long s = 10;
+ long t = Ten;
+ long f = F40(s, t);
+ return (f == 100);
+ }
+
+ static long F41(long x, long y)
+ {
+ return x * y;
+ }
+
+ static bool Bench41p()
+ {
+ long t = 10;
+ long f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ long t = Ten;
+ long f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ long s = 10;
+ long t = Ten;
+ long f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ long s = Ten;
+ long t = 10;
+ long f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsLong).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.csproj
new file mode 100644
index 0000000000..b4cfab2e28
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsLong.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs
new file mode 100644
index 0000000000..b329122967
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsSByte
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Sbytes feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static sbyte Five = 5;
+ static sbyte Ten = 10;
+
+ static sbyte Id(sbyte x)
+ {
+ return x;
+ }
+
+ static sbyte F00(sbyte x)
+ {
+ return (sbyte) (x * x);
+ }
+
+ static bool Bench00p()
+ {
+ sbyte t = 10;
+ sbyte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ sbyte t = Ten;
+ sbyte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ sbyte t = Id(10);
+ sbyte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ sbyte t = Id(Ten);
+ sbyte f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ sbyte t = Id(10);
+ sbyte f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ sbyte t = Id(Ten);
+ sbyte f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ sbyte t = 10;
+ sbyte f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ sbyte t = Ten;
+ sbyte f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ sbyte t = 5;
+ sbyte f = F00((sbyte)(2 * t));
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ sbyte t = Five;
+ sbyte f = F00((sbyte)(2 * t));
+ return (f == 100);
+ }
+
+ static sbyte F01(sbyte x)
+ {
+ return (sbyte)(1000 / x);
+ }
+
+ static bool Bench01p()
+ {
+ sbyte t = 10;
+ sbyte f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ sbyte t = Ten;
+ sbyte f = F01(t);
+ return (f == 100);
+ }
+
+ static sbyte F02(sbyte x)
+ {
+ return (sbyte) (20 * (x / 2));
+ }
+
+ static bool Bench02p()
+ {
+ sbyte t = 10;
+ sbyte f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ sbyte t = Ten;
+ sbyte f = F02(t);
+ return (f == 100);
+ }
+
+ static sbyte F03(sbyte x)
+ {
+ return (sbyte)(91 + 1009 % x);
+ }
+
+ static bool Bench03p()
+ {
+ sbyte t = 10;
+ sbyte f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ sbyte t = Ten;
+ sbyte f = F03(t);
+ return (f == 100);
+ }
+
+ static sbyte F04(sbyte x)
+ {
+ return (sbyte)(50 * (x % 4));
+ }
+
+ static bool Bench04p()
+ {
+ sbyte t = 10;
+ sbyte f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ sbyte t = Ten;
+ sbyte f = F04(t);
+ return (f == 100);
+ }
+
+ static sbyte F05(sbyte x)
+ {
+ return (sbyte)((1 << x) - 924);
+ }
+
+ static bool Bench05p()
+ {
+ sbyte t = 10;
+ sbyte f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ sbyte t = Ten;
+ sbyte f = F05(t);
+ return (f == 100);
+ }
+
+ static sbyte F051(sbyte x)
+ {
+ return (sbyte)(102400 >> x);
+ }
+
+ static bool Bench05p1()
+ {
+ sbyte t = 10;
+ sbyte f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ sbyte t = Ten;
+ sbyte f = F051(t);
+ return (f == 100);
+ }
+
+ static sbyte F06(sbyte x)
+ {
+ return (sbyte)(-x + 110);
+ }
+
+ static bool Bench06p()
+ {
+ sbyte t = 10;
+ sbyte f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ sbyte t = Ten;
+ sbyte f = F06(t);
+ return (f == 100);
+ }
+
+ static sbyte F07(sbyte x)
+ {
+ return (sbyte)(~x + 111);
+ }
+
+ static bool Bench07p()
+ {
+ sbyte t = 10;
+ sbyte f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ sbyte t = Ten;
+ sbyte f = F07(t);
+ return (f == 100);
+ }
+
+ static sbyte F071(sbyte x)
+ {
+ return (sbyte)((x ^ -1) + 111);
+ }
+
+ static bool Bench07p1()
+ {
+ sbyte t = 10;
+ sbyte f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ sbyte t = Ten;
+ sbyte f = F071(t);
+ return (f == 100);
+ }
+
+ static sbyte F08(sbyte x)
+ {
+ return (sbyte)((x & 0x7) + 98);
+ }
+
+ static bool Bench08p()
+ {
+ sbyte t = 10;
+ sbyte f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ sbyte t = Ten;
+ sbyte f = F08(t);
+ return (f == 100);
+ }
+
+ static sbyte F09(sbyte x)
+ {
+ return (sbyte)((x | 0x7) + 85);
+ }
+
+ static bool Bench09p()
+ {
+ sbyte t = 10;
+ sbyte f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ sbyte t = Ten;
+ sbyte f = F09(t);
+ return (f == 100);
+ }
+
+ // Sbytes feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static sbyte F10(sbyte x)
+ {
+ return x == 10 ? (sbyte) 100 : (sbyte) 0;
+ }
+
+ static bool Bench10p()
+ {
+ sbyte t = 10;
+ sbyte f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ sbyte t = Ten;
+ sbyte f = F10(t);
+ return (f == 100);
+ }
+
+ static sbyte F101(sbyte x)
+ {
+ return x != 10 ? (sbyte) 0 : (sbyte) 100;
+ }
+
+ static bool Bench10p1()
+ {
+ sbyte t = 10;
+ sbyte f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ sbyte t = Ten;
+ sbyte f = F101(t);
+ return (f == 100);
+ }
+
+ static sbyte F102(sbyte x)
+ {
+ return x >= 10 ? (sbyte) 100 : (sbyte) 0;
+ }
+
+ static bool Bench10p2()
+ {
+ sbyte t = 10;
+ sbyte f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ sbyte t = Ten;
+ sbyte f = F102(t);
+ return (f == 100);
+ }
+
+ static sbyte F103(sbyte x)
+ {
+ return x <= 10 ? (sbyte) 100 : (sbyte) 0;
+ }
+
+ static bool Bench10p3()
+ {
+ sbyte t = 10;
+ sbyte f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ sbyte t = Ten;
+ sbyte f = F102(t);
+ return (f == 100);
+ }
+
+ static sbyte F11(sbyte x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ sbyte t = 10;
+ sbyte f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ sbyte t = Ten;
+ sbyte f = F11(t);
+ return (f == 100);
+ }
+
+ static sbyte F111(sbyte x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ sbyte t = 10;
+ sbyte f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ sbyte t = Ten;
+ sbyte f = F111(t);
+ return (f == 100);
+ }
+
+ static sbyte F112(sbyte x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ sbyte t = 10;
+ sbyte f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ sbyte t = Ten;
+ sbyte f = F112(t);
+ return (f == 100);
+ }
+ static sbyte F113(sbyte x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ sbyte t = 10;
+ sbyte f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ sbyte t = Ten;
+ sbyte f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static sbyte F20(sbyte x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ sbyte t = 10;
+ sbyte f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ sbyte t = Ten;
+ sbyte f = F20(t);
+ return (f == 100);
+ }
+
+ static sbyte F21(sbyte x)
+ {
+ return (sbyte)(-x + 100 + x);
+ }
+
+ static bool Bench21p()
+ {
+ sbyte t = 10;
+ sbyte f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ sbyte t = Ten;
+ sbyte f = F21(t);
+ return (f == 100);
+ }
+
+ static sbyte F211(sbyte x)
+ {
+ return (sbyte)(x - x + 100);
+ }
+
+ static bool Bench21p1()
+ {
+ sbyte t = 10;
+ sbyte f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ sbyte t = Ten;
+ sbyte f = F211(t);
+ return (f == 100);
+ }
+
+ static sbyte F22(sbyte x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ sbyte t = 10;
+ sbyte f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ sbyte t = Ten;
+ sbyte f = F22(t);
+ return (f == 100);
+ }
+
+ static sbyte F23(sbyte x)
+ {
+ if (x > 0)
+ {
+ return (sbyte)(90 + x);
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ sbyte t = 10;
+ sbyte f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ sbyte t = Ten;
+ sbyte f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static sbyte F30(sbyte x, sbyte y)
+ {
+ return (sbyte)(y * y);
+ }
+
+ static bool Bench30p()
+ {
+ sbyte t = 10;
+ sbyte f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ sbyte t = Ten;
+ sbyte f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ sbyte s = Ten;
+ sbyte t = 10;
+ sbyte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ sbyte s = 10;
+ sbyte t = Ten;
+ sbyte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ sbyte s = 10;
+ sbyte t = 10;
+ sbyte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ sbyte s = Ten;
+ sbyte t = Ten;
+ sbyte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ sbyte s = 10;
+ sbyte t = s;
+ sbyte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ sbyte s = Ten;
+ sbyte t = s;
+ sbyte f = F30(s, t);
+ return (f == 100);
+ }
+
+ static sbyte F31(sbyte x, sbyte y, sbyte z)
+ {
+ return (sbyte)(z * z);
+ }
+
+ static bool Bench31p()
+ {
+ sbyte t = 10;
+ sbyte f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ sbyte t = Ten;
+ sbyte f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ sbyte r = Ten;
+ sbyte s = Ten;
+ sbyte t = 10;
+ sbyte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ sbyte r = 10;
+ sbyte s = 10;
+ sbyte t = Ten;
+ sbyte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ sbyte r = 10;
+ sbyte s = 10;
+ sbyte t = 10;
+ sbyte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ sbyte r = Ten;
+ sbyte s = Ten;
+ sbyte t = Ten;
+ sbyte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ sbyte r = 10;
+ sbyte s = r;
+ sbyte t = s;
+ sbyte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ sbyte r = Ten;
+ sbyte s = r;
+ sbyte t = s;
+ sbyte f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static sbyte F40(sbyte x, sbyte y)
+ {
+ return (sbyte)(x * x + y * y - 100);
+ }
+
+ static bool Bench40p()
+ {
+ sbyte t = 10;
+ sbyte f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ sbyte t = Ten;
+ sbyte f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ sbyte s = Ten;
+ sbyte t = 10;
+ sbyte f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ sbyte s = 10;
+ sbyte t = Ten;
+ sbyte f = F40(s, t);
+ return (f == 100);
+ }
+
+ static sbyte F41(sbyte x, sbyte y)
+ {
+ return (sbyte)(x * y);
+ }
+
+ static bool Bench41p()
+ {
+ sbyte t = 10;
+ sbyte f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ sbyte t = Ten;
+ sbyte f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ sbyte s = 10;
+ sbyte t = Ten;
+ sbyte f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ sbyte s = Ten;
+ sbyte t = 10;
+ sbyte f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsSByte).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.csproj
new file mode 100644
index 0000000000..22268de21f
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsSByte.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs
new file mode 100644
index 0000000000..8718111a72
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsShort
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Shorts feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static short Five = 5;
+ static short Ten = 10;
+
+ static short Id(short x)
+ {
+ return x;
+ }
+
+ static short F00(short x)
+ {
+ return (short) (x * x);
+ }
+
+ static bool Bench00p()
+ {
+ short t = 10;
+ short f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ short t = Ten;
+ short f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ short t = Id(10);
+ short f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ short t = Id(Ten);
+ short f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ short t = Id(10);
+ short f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ short t = Id(Ten);
+ short f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ short t = 10;
+ short f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ short t = Ten;
+ short f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ short t = 5;
+ short f = F00((short)(2 * t));
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ short t = Five;
+ short f = F00((short)(2 * t));
+ return (f == 100);
+ }
+
+ static short F01(short x)
+ {
+ return (short)(1000 / x);
+ }
+
+ static bool Bench01p()
+ {
+ short t = 10;
+ short f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ short t = Ten;
+ short f = F01(t);
+ return (f == 100);
+ }
+
+ static short F02(short x)
+ {
+ return (short) (20 * (x / 2));
+ }
+
+ static bool Bench02p()
+ {
+ short t = 10;
+ short f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ short t = Ten;
+ short f = F02(t);
+ return (f == 100);
+ }
+
+ static short F03(short x)
+ {
+ return (short)(91 + 1009 % x);
+ }
+
+ static bool Bench03p()
+ {
+ short t = 10;
+ short f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ short t = Ten;
+ short f = F03(t);
+ return (f == 100);
+ }
+
+ static short F04(short x)
+ {
+ return (short)(50 * (x % 4));
+ }
+
+ static bool Bench04p()
+ {
+ short t = 10;
+ short f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ short t = Ten;
+ short f = F04(t);
+ return (f == 100);
+ }
+
+ static short F05(short x)
+ {
+ return (short)((1 << x) - 924);
+ }
+
+ static bool Bench05p()
+ {
+ short t = 10;
+ short f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ short t = Ten;
+ short f = F05(t);
+ return (f == 100);
+ }
+
+ static short F051(short x)
+ {
+ return (short)(102400 >> x);
+ }
+
+ static bool Bench05p1()
+ {
+ short t = 10;
+ short f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ short t = Ten;
+ short f = F051(t);
+ return (f == 100);
+ }
+
+ static short F06(short x)
+ {
+ return (short)(-x + 110);
+ }
+
+ static bool Bench06p()
+ {
+ short t = 10;
+ short f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ short t = Ten;
+ short f = F06(t);
+ return (f == 100);
+ }
+
+ static short F07(short x)
+ {
+ return (short)(~x + 111);
+ }
+
+ static bool Bench07p()
+ {
+ short t = 10;
+ short f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ short t = Ten;
+ short f = F07(t);
+ return (f == 100);
+ }
+
+ static short F071(short x)
+ {
+ return (short)((x ^ -1) + 111);
+ }
+
+ static bool Bench07p1()
+ {
+ short t = 10;
+ short f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ short t = Ten;
+ short f = F071(t);
+ return (f == 100);
+ }
+
+ static short F08(short x)
+ {
+ return (short)((x & 0x7) + 98);
+ }
+
+ static bool Bench08p()
+ {
+ short t = 10;
+ short f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ short t = Ten;
+ short f = F08(t);
+ return (f == 100);
+ }
+
+ static short F09(short x)
+ {
+ return (short)((x | 0x7) + 85);
+ }
+
+ static bool Bench09p()
+ {
+ short t = 10;
+ short f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ short t = Ten;
+ short f = F09(t);
+ return (f == 100);
+ }
+
+ // Shorts feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static short F10(short x)
+ {
+ return x == 10 ? (short) 100 : (short) 0;
+ }
+
+ static bool Bench10p()
+ {
+ short t = 10;
+ short f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ short t = Ten;
+ short f = F10(t);
+ return (f == 100);
+ }
+
+ static short F101(short x)
+ {
+ return x != 10 ? (short) 0 : (short) 100;
+ }
+
+ static bool Bench10p1()
+ {
+ short t = 10;
+ short f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ short t = Ten;
+ short f = F101(t);
+ return (f == 100);
+ }
+
+ static short F102(short x)
+ {
+ return x >= 10 ? (short) 100 : (short) 0;
+ }
+
+ static bool Bench10p2()
+ {
+ short t = 10;
+ short f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ short t = Ten;
+ short f = F102(t);
+ return (f == 100);
+ }
+
+ static short F103(short x)
+ {
+ return x <= 10 ? (short) 100 : (short) 0;
+ }
+
+ static bool Bench10p3()
+ {
+ short t = 10;
+ short f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ short t = Ten;
+ short f = F102(t);
+ return (f == 100);
+ }
+
+ static short F11(short x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ short t = 10;
+ short f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ short t = Ten;
+ short f = F11(t);
+ return (f == 100);
+ }
+
+ static short F111(short x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ short t = 10;
+ short f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ short t = Ten;
+ short f = F111(t);
+ return (f == 100);
+ }
+
+ static short F112(short x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ short t = 10;
+ short f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ short t = Ten;
+ short f = F112(t);
+ return (f == 100);
+ }
+ static short F113(short x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ short t = 10;
+ short f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ short t = Ten;
+ short f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static short F20(short x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ short t = 10;
+ short f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ short t = Ten;
+ short f = F20(t);
+ return (f == 100);
+ }
+
+ static short F21(short x)
+ {
+ return (short)(-x + 100 + x);
+ }
+
+ static bool Bench21p()
+ {
+ short t = 10;
+ short f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ short t = Ten;
+ short f = F21(t);
+ return (f == 100);
+ }
+
+ static short F211(short x)
+ {
+ return (short)(x - x + 100);
+ }
+
+ static bool Bench21p1()
+ {
+ short t = 10;
+ short f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ short t = Ten;
+ short f = F211(t);
+ return (f == 100);
+ }
+
+ static short F22(short x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ short t = 10;
+ short f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ short t = Ten;
+ short f = F22(t);
+ return (f == 100);
+ }
+
+ static short F23(short x)
+ {
+ if (x > 0)
+ {
+ return (short)(90 + x);
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ short t = 10;
+ short f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ short t = Ten;
+ short f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static short F30(short x, short y)
+ {
+ return (short)(y * y);
+ }
+
+ static bool Bench30p()
+ {
+ short t = 10;
+ short f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ short t = Ten;
+ short f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ short s = Ten;
+ short t = 10;
+ short f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ short s = 10;
+ short t = Ten;
+ short f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ short s = 10;
+ short t = 10;
+ short f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ short s = Ten;
+ short t = Ten;
+ short f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ short s = 10;
+ short t = s;
+ short f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ short s = Ten;
+ short t = s;
+ short f = F30(s, t);
+ return (f == 100);
+ }
+
+ static short F31(short x, short y, short z)
+ {
+ return (short)(z * z);
+ }
+
+ static bool Bench31p()
+ {
+ short t = 10;
+ short f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ short t = Ten;
+ short f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ short r = Ten;
+ short s = Ten;
+ short t = 10;
+ short f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ short r = 10;
+ short s = 10;
+ short t = Ten;
+ short f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ short r = 10;
+ short s = 10;
+ short t = 10;
+ short f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ short r = Ten;
+ short s = Ten;
+ short t = Ten;
+ short f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ short r = 10;
+ short s = r;
+ short t = s;
+ short f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ short r = Ten;
+ short s = r;
+ short t = s;
+ short f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static short F40(short x, short y)
+ {
+ return (short)(x * x + y * y - 100);
+ }
+
+ static bool Bench40p()
+ {
+ short t = 10;
+ short f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ short t = Ten;
+ short f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ short s = Ten;
+ short t = 10;
+ short f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ short s = 10;
+ short t = Ten;
+ short f = F40(s, t);
+ return (f == 100);
+ }
+
+ static short F41(short x, short y)
+ {
+ return (short)(x * y);
+ }
+
+ static bool Bench41p()
+ {
+ short t = 10;
+ short f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ short t = Ten;
+ short f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ short s = 10;
+ short t = Ten;
+ short f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ short s = Ten;
+ short t = 10;
+ short f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsShort).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.csproj
new file mode 100644
index 0000000000..4f5db4c468
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsShort.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs
new file mode 100644
index 0000000000..b7319086d7
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs
@@ -0,0 +1,330 @@
+// 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.
+
+// Strings are the only ref class where there is built-in support for
+// constant objects.
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsString
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Ints feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static string Ten = "Ten";
+ static string Five = "Five";
+
+ static string Id(string x)
+ {
+ return x;
+ }
+
+ static char F00(string x)
+ {
+ return x[0];
+ }
+
+ static bool Bench00p()
+ {
+ string t = "Ten";
+ char f = F00(t);
+ return (f == 'T');
+ }
+
+ static bool Bench00n()
+ {
+ string t = Ten;
+ char f = F00(t);
+ return (f == 'T');
+ }
+
+ static int F01(string x)
+ {
+ return x.Length;
+ }
+
+ static bool Bench01p()
+ {
+ string t = "Ten";
+ int f = F01(t);
+ return (f == 3);
+ }
+
+ static bool Bench01n()
+ {
+ string t = Ten;
+ int f = F01(t);
+ return (f == 3);
+ }
+
+ static bool Bench01p1()
+ {
+ return "Ten".Length == 3;
+ }
+
+ static bool Bench01n1()
+ {
+ return Ten.Length == 3;
+ }
+
+ static bool Bench02p()
+ {
+ return "Ten".Equals("Ten", StringComparison.Ordinal);
+ }
+
+ static bool Bench02n()
+ {
+ return "Ten".Equals(Ten, StringComparison.Ordinal);
+ }
+
+ static bool Bench02n1()
+ {
+ return Ten.Equals("Ten", StringComparison.Ordinal);
+ }
+
+ static bool Bench02n2()
+ {
+ return Ten.Equals(Ten, StringComparison.Ordinal);
+ }
+
+ static bool Bench03p()
+ {
+ return "Ten" == "Ten";
+ }
+
+ static bool Bench03n()
+ {
+ return "Ten" == Ten;
+ }
+
+ static bool Bench03n1()
+ {
+ return Ten == "Ten";
+ }
+
+ static bool Bench03n2()
+ {
+ return Ten == Ten;
+ }
+
+ static bool Bench04p()
+ {
+ return "Ten" != "Five";
+ }
+
+ static bool Bench04n()
+ {
+ return "Ten" != Five;
+ }
+
+ static bool Bench04n1()
+ {
+ return Ten != "Five";
+ }
+
+ static bool Bench04n2()
+ {
+ return Ten != Five;
+ }
+
+ static bool Bench05p()
+ {
+ string t = "Ten";
+ return (t == t);
+ }
+
+ static bool Bench05n()
+ {
+ string t = Ten;
+ return (t == t);
+ }
+
+ static bool Bench06p()
+ {
+ return "Ten" != null;
+ }
+
+ static bool Bench06n()
+ {
+ return Ten != null;
+ }
+
+ static bool Bench07p()
+ {
+ return !"Ten".Equals(null);
+ }
+
+ static bool Bench07n()
+ {
+ return !Ten.Equals(null);
+ }
+
+ static bool Bench08p()
+ {
+ return !"Ten".Equals("Five", StringComparison.Ordinal);
+ }
+
+ static bool Bench08n()
+ {
+ return !"Ten".Equals(Five, StringComparison.Ordinal);
+ }
+
+ static bool Bench08n1()
+ {
+ return !Ten.Equals("Five", StringComparison.Ordinal);
+ }
+
+ static bool Bench08n2()
+ {
+ return !Ten.Equals(Five, StringComparison.Ordinal);
+ }
+
+ static bool Bench09p()
+ {
+ return string.Equals("Ten", "Ten");
+ }
+
+ static bool Bench09n()
+ {
+ return string.Equals("Ten", Ten);
+ }
+
+ static bool Bench09n1()
+ {
+ return string.Equals(Ten, "Ten");
+ }
+
+ static bool Bench09n2()
+ {
+ return string.Equals(Ten, Ten);
+ }
+
+ static bool Bench10p()
+ {
+ return !string.Equals("Five", "Ten");
+ }
+
+ static bool Bench10n()
+ {
+ return !string.Equals(Five, "Ten");
+ }
+
+ static bool Bench10n1()
+ {
+ return !string.Equals("Five", Ten);
+ }
+
+ static bool Bench10n2()
+ {
+ return !string.Equals(Five, Ten);
+ }
+
+ static bool Bench11p()
+ {
+ return !string.Equals("Five", null);
+ }
+
+ static bool Bench11n()
+ {
+ return !string.Equals(Five, null);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench01p", "Bench01n",
+ "Bench01p1", "Bench01n1",
+ "Bench02p", "Bench02n",
+ "Bench02n1", "Bench02n2",
+ "Bench03p", "Bench03n",
+ "Bench03n1", "Bench03n2",
+ "Bench04p", "Bench04n",
+ "Bench04n1", "Bench04n2",
+ "Bench05p", "Bench05n",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench08p", "Bench08n",
+ "Bench08n1", "Bench08n2",
+ "Bench09p", "Bench09n",
+ "Bench09n1", "Bench09n2",
+ "Bench10p", "Bench10n",
+ "Bench10n1", "Bench10n2",
+ "Bench11p", "Bench11n"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsString).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.csproj
new file mode 100644
index 0000000000..8dbc9932e9
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsString.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs
new file mode 100644
index 0000000000..db3316ea32
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs
@@ -0,0 +1,890 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsUInt
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Ints feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static uint Five = 5;
+ static uint Ten = 10;
+
+ static uint Id(uint x)
+ {
+ return x;
+ }
+
+ static uint F00(uint x)
+ {
+ return x * x;
+ }
+
+ static bool Bench00p()
+ {
+ uint t = 10;
+ uint f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ uint t = Ten;
+ uint f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ uint t = Id(10);
+ uint f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ uint t = Id(Ten);
+ uint f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ uint t = Id(10);
+ uint f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ uint t = Id(Ten);
+ uint f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ uint t = 10;
+ uint f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ uint t = Ten;
+ uint f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ uint t = 5;
+ uint f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ uint t = Five;
+ uint f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static uint F01(uint x)
+ {
+ return 1000 / x;
+ }
+
+ static bool Bench01p()
+ {
+ uint t = 10;
+ uint f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ uint t = Ten;
+ uint f = F01(t);
+ return (f == 100);
+ }
+
+ static uint F02(uint x)
+ {
+ return 20 * (x / 2);
+ }
+
+ static bool Bench02p()
+ {
+ uint t = 10;
+ uint f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ uint t = Ten;
+ uint f = F02(t);
+ return (f == 100);
+ }
+
+ static uint F03(uint x)
+ {
+ return 91 + 1009 % x;
+ }
+
+ static bool Bench03p()
+ {
+ uint t = 10;
+ uint f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ uint t = Ten;
+ uint f = F03(t);
+ return (f == 100);
+ }
+
+ static uint F04(uint x)
+ {
+ return 50 * (x % 4);
+ }
+
+ static bool Bench04p()
+ {
+ uint t = 10;
+ uint f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ uint t = Ten;
+ uint f = F04(t);
+ return (f == 100);
+ }
+
+ static uint F06(uint x)
+ {
+ return 110 - x;
+ }
+
+ static bool Bench06p()
+ {
+ uint t = 10;
+ uint f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ uint t = Ten;
+ uint f = F06(t);
+ return (f == 100);
+ }
+
+ static uint F07(uint x)
+ {
+ return ~x + 111;
+ }
+
+ static bool Bench07p()
+ {
+ uint t = 10;
+ uint f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ uint t = Ten;
+ uint f = F07(t);
+ return (f == 100);
+ }
+
+ static uint F071(uint x)
+ {
+ return (x ^ 0xFFFFFFFF) + 111;
+ }
+
+ static bool Bench07p1()
+ {
+ uint t = 10;
+ uint f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ uint t = Ten;
+ uint f = F071(t);
+ return (f == 100);
+ }
+
+ static uint F08(uint x)
+ {
+ return (x & 0x7) + 98;
+ }
+
+ static bool Bench08p()
+ {
+ uint t = 10;
+ uint f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ uint t = Ten;
+ uint f = F08(t);
+ return (f == 100);
+ }
+
+ static uint F09(uint x)
+ {
+ return (x | 0x7) + 85;
+ }
+
+ static bool Bench09p()
+ {
+ uint t = 10;
+ uint f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ uint t = Ten;
+ uint f = F09(t);
+ return (f == 100);
+ }
+
+ // Uints feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static uint F10(uint x)
+ {
+ return x == 10 ? 100u : 0u;
+ }
+
+ static bool Bench10p()
+ {
+ uint t = 10;
+ uint f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ uint t = Ten;
+ uint f = F10(t);
+ return (f == 100);
+ }
+
+ static uint F101(uint x)
+ {
+ return x != 10 ? 0u : 100u;
+ }
+
+ static bool Bench10p1()
+ {
+ uint t = 10;
+ uint f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ uint t = Ten;
+ uint f = F101(t);
+ return (f == 100);
+ }
+
+ static uint F102(uint x)
+ {
+ return x >= 10 ? 100u : 0u;
+ }
+
+ static bool Bench10p2()
+ {
+ uint t = 10;
+ uint f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ uint t = Ten;
+ uint f = F102(t);
+ return (f == 100);
+ }
+
+ static uint F103(uint x)
+ {
+ return x <= 10 ? 100u : 0u;
+ }
+
+ static bool Bench10p3()
+ {
+ uint t = 10;
+ uint f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ uint t = Ten;
+ uint f = F102(t);
+ return (f == 100);
+ }
+
+ static uint F11(uint x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ uint t = 10;
+ uint f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ uint t = Ten;
+ uint f = F11(t);
+ return (f == 100);
+ }
+
+ static uint F111(uint x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ uint t = 10;
+ uint f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ uint t = Ten;
+ uint f = F111(t);
+ return (f == 100);
+ }
+
+ static uint F112(uint x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ uint t = 10;
+ uint f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ uint t = Ten;
+ uint f = F112(t);
+ return (f == 100);
+ }
+ static uint F113(uint x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ uint t = 10;
+ uint f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ uint t = Ten;
+ uint f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static uint F20(uint x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ uint t = 10;
+ uint f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ uint t = Ten;
+ uint f = F20(t);
+ return (f == 100);
+ }
+
+ static uint F21(uint x)
+ {
+ return (uint) -x + 100 + x;
+ }
+
+ static bool Bench21p()
+ {
+ uint t = 10;
+ uint f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ uint t = Ten;
+ uint f = F21(t);
+ return (f == 100);
+ }
+
+ static uint F211(uint x)
+ {
+ return x - x + 100;
+ }
+
+ static bool Bench21p1()
+ {
+ uint t = 10;
+ uint f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ uint t = Ten;
+ uint f = F211(t);
+ return (f == 100);
+ }
+
+ static uint F22(uint x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ uint t = 10;
+ uint f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ uint t = Ten;
+ uint f = F22(t);
+ return (f == 100);
+ }
+
+ static uint F23(uint x)
+ {
+ if (x > 0)
+ {
+ return 90 + x;
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ uint t = 10;
+ uint f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ uint t = Ten;
+ uint f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static uint F30(uint x, uint y)
+ {
+ return y * y;
+ }
+
+ static bool Bench30p()
+ {
+ uint t = 10;
+ uint f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ uint t = Ten;
+ uint f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ uint s = Ten;
+ uint t = 10;
+ uint f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ uint s = 10;
+ uint t = Ten;
+ uint f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ uint s = 10;
+ uint t = 10;
+ uint f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ uint s = Ten;
+ uint t = Ten;
+ uint f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ uint s = 10;
+ uint t = s;
+ uint f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ uint s = Ten;
+ uint t = s;
+ uint f = F30(s, t);
+ return (f == 100);
+ }
+
+ static uint F31(uint x, uint y, uint z)
+ {
+ return z * z;
+ }
+
+ static bool Bench31p()
+ {
+ uint t = 10;
+ uint f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ uint t = Ten;
+ uint f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ uint r = Ten;
+ uint s = Ten;
+ uint t = 10;
+ uint f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ uint r = 10;
+ uint s = 10;
+ uint t = Ten;
+ uint f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ uint r = 10;
+ uint s = 10;
+ uint t = 10;
+ uint f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ uint r = Ten;
+ uint s = Ten;
+ uint t = Ten;
+ uint f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ uint r = 10;
+ uint s = r;
+ uint t = s;
+ uint f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ uint r = Ten;
+ uint s = r;
+ uint t = s;
+ uint f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static uint F40(uint x, uint y)
+ {
+ return x * x + y * y - 100;
+ }
+
+ static bool Bench40p()
+ {
+ uint t = 10;
+ uint f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ uint t = Ten;
+ uint f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ uint s = Ten;
+ uint t = 10;
+ uint f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ uint s = 10;
+ uint t = Ten;
+ uint f = F40(s, t);
+ return (f == 100);
+ }
+
+ static uint F41(uint x, uint y)
+ {
+ return x * y;
+ }
+
+ static bool Bench41p()
+ {
+ uint t = 10;
+ uint f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ uint t = Ten;
+ uint f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ uint s = 10;
+ uint t = Ten;
+ uint f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ uint s = Ten;
+ uint t = 10;
+ uint f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsUInt).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.csproj
new file mode 100644
index 0000000000..68640b81cb
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsUInt.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs
new file mode 100644
index 0000000000..72087077e2
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs
@@ -0,0 +1,890 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsULong
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Ints feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static ulong Five = 5;
+ static ulong Ten = 10;
+
+ static ulong Id(ulong x)
+ {
+ return x;
+ }
+
+ static ulong F00(ulong x)
+ {
+ return x * x;
+ }
+
+ static bool Bench00p()
+ {
+ ulong t = 10;
+ ulong f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ ulong t = Ten;
+ ulong f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ ulong t = Id(10);
+ ulong f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ ulong t = Id(Ten);
+ ulong f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ ulong t = Id(10);
+ ulong f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ ulong t = Id(Ten);
+ ulong f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ ulong t = 10;
+ ulong f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ ulong t = Ten;
+ ulong f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ ulong t = 5;
+ ulong f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ ulong t = Five;
+ ulong f = F00(2 * t);
+ return (f == 100);
+ }
+
+ static ulong F01(ulong x)
+ {
+ return 1000 / x;
+ }
+
+ static bool Bench01p()
+ {
+ ulong t = 10;
+ ulong f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ ulong t = Ten;
+ ulong f = F01(t);
+ return (f == 100);
+ }
+
+ static ulong F02(ulong x)
+ {
+ return 20 * (x / 2);
+ }
+
+ static bool Bench02p()
+ {
+ ulong t = 10;
+ ulong f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ ulong t = Ten;
+ ulong f = F02(t);
+ return (f == 100);
+ }
+
+ static ulong F03(ulong x)
+ {
+ return 91 + 1009 % x;
+ }
+
+ static bool Bench03p()
+ {
+ ulong t = 10;
+ ulong f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ ulong t = Ten;
+ ulong f = F03(t);
+ return (f == 100);
+ }
+
+ static ulong F04(ulong x)
+ {
+ return 50 * (x % 4);
+ }
+
+ static bool Bench04p()
+ {
+ ulong t = 10;
+ ulong f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ ulong t = Ten;
+ ulong f = F04(t);
+ return (f == 100);
+ }
+
+ static ulong F06(ulong x)
+ {
+ return 110 - x;
+ }
+
+ static bool Bench06p()
+ {
+ ulong t = 10;
+ ulong f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ ulong t = Ten;
+ ulong f = F06(t);
+ return (f == 100);
+ }
+
+ static ulong F07(ulong x)
+ {
+ return ~x + 111;
+ }
+
+ static bool Bench07p()
+ {
+ ulong t = 10;
+ ulong f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ ulong t = Ten;
+ ulong f = F07(t);
+ return (f == 100);
+ }
+
+ static ulong F071(ulong x)
+ {
+ return (x ^ 0xFFFFFFFFFFFFFFFF) + 111;
+ }
+
+ static bool Bench07p1()
+ {
+ ulong t = 10;
+ ulong f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ ulong t = Ten;
+ ulong f = F071(t);
+ return (f == 100);
+ }
+
+ static ulong F08(ulong x)
+ {
+ return (x & 0x7) + 98;
+ }
+
+ static bool Bench08p()
+ {
+ ulong t = 10;
+ ulong f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ ulong t = Ten;
+ ulong f = F08(t);
+ return (f == 100);
+ }
+
+ static ulong F09(ulong x)
+ {
+ return (x | 0x7) + 85;
+ }
+
+ static bool Bench09p()
+ {
+ ulong t = 10;
+ ulong f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ ulong t = Ten;
+ ulong f = F09(t);
+ return (f == 100);
+ }
+
+ // Ulongs feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static ulong F10(ulong x)
+ {
+ return x == 10 ? 100u : 0u;
+ }
+
+ static bool Bench10p()
+ {
+ ulong t = 10;
+ ulong f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ ulong t = Ten;
+ ulong f = F10(t);
+ return (f == 100);
+ }
+
+ static ulong F101(ulong x)
+ {
+ return x != 10 ? 0u : 100u;
+ }
+
+ static bool Bench10p1()
+ {
+ ulong t = 10;
+ ulong f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ ulong t = Ten;
+ ulong f = F101(t);
+ return (f == 100);
+ }
+
+ static ulong F102(ulong x)
+ {
+ return x >= 10 ? 100u : 0u;
+ }
+
+ static bool Bench10p2()
+ {
+ ulong t = 10;
+ ulong f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ ulong t = Ten;
+ ulong f = F102(t);
+ return (f == 100);
+ }
+
+ static ulong F103(ulong x)
+ {
+ return x <= 10 ? 100u : 0u;
+ }
+
+ static bool Bench10p3()
+ {
+ ulong t = 10;
+ ulong f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ ulong t = Ten;
+ ulong f = F102(t);
+ return (f == 100);
+ }
+
+ static ulong F11(ulong x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ ulong t = 10;
+ ulong f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ ulong t = Ten;
+ ulong f = F11(t);
+ return (f == 100);
+ }
+
+ static ulong F111(ulong x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ ulong t = 10;
+ ulong f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ ulong t = Ten;
+ ulong f = F111(t);
+ return (f == 100);
+ }
+
+ static ulong F112(ulong x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ ulong t = 10;
+ ulong f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ ulong t = Ten;
+ ulong f = F112(t);
+ return (f == 100);
+ }
+ static ulong F113(ulong x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ ulong t = 10;
+ ulong f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ ulong t = Ten;
+ ulong f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static ulong F20(ulong x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ ulong t = 10;
+ ulong f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ ulong t = Ten;
+ ulong f = F20(t);
+ return (f == 100);
+ }
+
+ static ulong F21(ulong x)
+ {
+ return x + 100 - x;
+ }
+
+ static bool Bench21p()
+ {
+ ulong t = 10;
+ ulong f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ ulong t = Ten;
+ ulong f = F21(t);
+ return (f == 100);
+ }
+
+ static ulong F211(ulong x)
+ {
+ return x - x + 100;
+ }
+
+ static bool Bench21p1()
+ {
+ ulong t = 10;
+ ulong f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ ulong t = Ten;
+ ulong f = F211(t);
+ return (f == 100);
+ }
+
+ static ulong F22(ulong x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ ulong t = 10;
+ ulong f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ ulong t = Ten;
+ ulong f = F22(t);
+ return (f == 100);
+ }
+
+ static ulong F23(ulong x)
+ {
+ if (x > 0)
+ {
+ return 90 + x;
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ ulong t = 10;
+ ulong f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ ulong t = Ten;
+ ulong f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static ulong F30(ulong x, ulong y)
+ {
+ return y * y;
+ }
+
+ static bool Bench30p()
+ {
+ ulong t = 10;
+ ulong f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ ulong t = Ten;
+ ulong f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ ulong s = Ten;
+ ulong t = 10;
+ ulong f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ ulong s = 10;
+ ulong t = Ten;
+ ulong f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ ulong s = 10;
+ ulong t = 10;
+ ulong f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ ulong s = Ten;
+ ulong t = Ten;
+ ulong f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ ulong s = 10;
+ ulong t = s;
+ ulong f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ ulong s = Ten;
+ ulong t = s;
+ ulong f = F30(s, t);
+ return (f == 100);
+ }
+
+ static ulong F31(ulong x, ulong y, ulong z)
+ {
+ return z * z;
+ }
+
+ static bool Bench31p()
+ {
+ ulong t = 10;
+ ulong f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ ulong t = Ten;
+ ulong f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ ulong r = Ten;
+ ulong s = Ten;
+ ulong t = 10;
+ ulong f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ ulong r = 10;
+ ulong s = 10;
+ ulong t = Ten;
+ ulong f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ ulong r = 10;
+ ulong s = 10;
+ ulong t = 10;
+ ulong f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ ulong r = Ten;
+ ulong s = Ten;
+ ulong t = Ten;
+ ulong f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ ulong r = 10;
+ ulong s = r;
+ ulong t = s;
+ ulong f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ ulong r = Ten;
+ ulong s = r;
+ ulong t = s;
+ ulong f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static ulong F40(ulong x, ulong y)
+ {
+ return x * x + y * y - 100;
+ }
+
+ static bool Bench40p()
+ {
+ ulong t = 10;
+ ulong f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ ulong t = Ten;
+ ulong f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ ulong s = Ten;
+ ulong t = 10;
+ ulong f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ ulong s = 10;
+ ulong t = Ten;
+ ulong f = F40(s, t);
+ return (f == 100);
+ }
+
+ static ulong F41(ulong x, ulong y)
+ {
+ return x * y;
+ }
+
+ static bool Bench41p()
+ {
+ ulong t = 10;
+ ulong f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ ulong t = Ten;
+ ulong f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ ulong s = 10;
+ ulong t = Ten;
+ ulong f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ ulong s = Ten;
+ ulong t = 10;
+ ulong f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsULong).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.csproj
new file mode 100644
index 0000000000..cb983a5ecb
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsULong.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs
new file mode 100644
index 0000000000..249e985496
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs
@@ -0,0 +1,930 @@
+// 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 Microsoft.Xunit.Performance;
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class ConstantArgsUShort
+{
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 100000;
+#endif
+
+ // Ushorts feeding math operations.
+ //
+ // Inlining in Bench0xp should enable constant folding
+ // Inlining in Bench0xn will not enable constant folding
+
+ static ushort Five = 5;
+ static ushort Ten = 10;
+
+ static ushort Id(ushort x)
+ {
+ return x;
+ }
+
+ static ushort F00(ushort x)
+ {
+ return (ushort) (x * x);
+ }
+
+ static bool Bench00p()
+ {
+ ushort t = 10;
+ ushort f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n()
+ {
+ ushort t = Ten;
+ ushort f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p1()
+ {
+ ushort t = Id(10);
+ ushort f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00n1()
+ {
+ ushort t = Id(Ten);
+ ushort f = F00(t);
+ return (f == 100);
+ }
+
+ static bool Bench00p2()
+ {
+ ushort t = Id(10);
+ ushort f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00n2()
+ {
+ ushort t = Id(Ten);
+ ushort f = F00(Id(t));
+ return (f == 100);
+ }
+
+ static bool Bench00p3()
+ {
+ ushort t = 10;
+ ushort f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00n3()
+ {
+ ushort t = Ten;
+ ushort f = F00(Id(Id(t)));
+ return (f == 100);
+ }
+
+ static bool Bench00p4()
+ {
+ ushort t = 5;
+ ushort f = F00((ushort)(2 * t));
+ return (f == 100);
+ }
+
+ static bool Bench00n4()
+ {
+ ushort t = Five;
+ ushort f = F00((ushort)(2 * t));
+ return (f == 100);
+ }
+
+ static ushort F01(ushort x)
+ {
+ return (ushort)(1000 / x);
+ }
+
+ static bool Bench01p()
+ {
+ ushort t = 10;
+ ushort f = F01(t);
+ return (f == 100);
+ }
+
+ static bool Bench01n()
+ {
+ ushort t = Ten;
+ ushort f = F01(t);
+ return (f == 100);
+ }
+
+ static ushort F02(ushort x)
+ {
+ return (ushort) (20 * (x / 2));
+ }
+
+ static bool Bench02p()
+ {
+ ushort t = 10;
+ ushort f = F02(t);
+ return (f == 100);
+ }
+
+ static bool Bench02n()
+ {
+ ushort t = Ten;
+ ushort f = F02(t);
+ return (f == 100);
+ }
+
+ static ushort F03(ushort x)
+ {
+ return (ushort)(91 + 1009 % x);
+ }
+
+ static bool Bench03p()
+ {
+ ushort t = 10;
+ ushort f = F03(t);
+ return (f == 100);
+ }
+
+ static bool Bench03n()
+ {
+ ushort t = Ten;
+ ushort f = F03(t);
+ return (f == 100);
+ }
+
+ static ushort F04(ushort x)
+ {
+ return (ushort)(50 * (x % 4));
+ }
+
+ static bool Bench04p()
+ {
+ ushort t = 10;
+ ushort f = F04(t);
+ return (f == 100);
+ }
+
+ static bool Bench04n()
+ {
+ ushort t = Ten;
+ ushort f = F04(t);
+ return (f == 100);
+ }
+
+ static ushort F05(ushort x)
+ {
+ return (ushort)((1 << x) - 924);
+ }
+
+ static bool Bench05p()
+ {
+ ushort t = 10;
+ ushort f = F05(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n()
+ {
+ ushort t = Ten;
+ ushort f = F05(t);
+ return (f == 100);
+ }
+
+ static ushort F051(ushort x)
+ {
+ return (ushort)(102400 >> x);
+ }
+
+ static bool Bench05p1()
+ {
+ ushort t = 10;
+ ushort f = F051(t);
+ return (f == 100);
+ }
+
+ static bool Bench05n1()
+ {
+ ushort t = Ten;
+ ushort f = F051(t);
+ return (f == 100);
+ }
+
+ static ushort F06(ushort x)
+ {
+ return (ushort)(-x + 110);
+ }
+
+ static bool Bench06p()
+ {
+ ushort t = 10;
+ ushort f = F06(t);
+ return (f == 100);
+ }
+
+ static bool Bench06n()
+ {
+ ushort t = Ten;
+ ushort f = F06(t);
+ return (f == 100);
+ }
+
+ static ushort F07(ushort x)
+ {
+ return (ushort)(~x + 111);
+ }
+
+ static bool Bench07p()
+ {
+ ushort t = 10;
+ ushort f = F07(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n()
+ {
+ ushort t = Ten;
+ ushort f = F07(t);
+ return (f == 100);
+ }
+
+ static ushort F071(ushort x)
+ {
+ return (ushort)((x ^ -1) + 111);
+ }
+
+ static bool Bench07p1()
+ {
+ ushort t = 10;
+ ushort f = F071(t);
+ return (f == 100);
+ }
+
+ static bool Bench07n1()
+ {
+ ushort t = Ten;
+ ushort f = F071(t);
+ return (f == 100);
+ }
+
+ static ushort F08(ushort x)
+ {
+ return (ushort)((x & 0x7) + 98);
+ }
+
+ static bool Bench08p()
+ {
+ ushort t = 10;
+ ushort f = F08(t);
+ return (f == 100);
+ }
+
+ static bool Bench08n()
+ {
+ ushort t = Ten;
+ ushort f = F08(t);
+ return (f == 100);
+ }
+
+ static ushort F09(ushort x)
+ {
+ return (ushort)((x | 0x7) + 85);
+ }
+
+ static bool Bench09p()
+ {
+ ushort t = 10;
+ ushort f = F09(t);
+ return (f == 100);
+ }
+
+ static bool Bench09n()
+ {
+ ushort t = Ten;
+ ushort f = F09(t);
+ return (f == 100);
+ }
+
+ // Ushorts feeding comparisons.
+ //
+ // Inlining in Bench1xp should enable branch optimization
+ // Inlining in Bench1xn will not enable branch optimization
+
+ static ushort F10(ushort x)
+ {
+ return x == 10 ? (ushort) 100 : (ushort) 0;
+ }
+
+ static bool Bench10p()
+ {
+ ushort t = 10;
+ ushort f = F10(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n()
+ {
+ ushort t = Ten;
+ ushort f = F10(t);
+ return (f == 100);
+ }
+
+ static ushort F101(ushort x)
+ {
+ return x != 10 ? (ushort) 0 : (ushort) 100;
+ }
+
+ static bool Bench10p1()
+ {
+ ushort t = 10;
+ ushort f = F101(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n1()
+ {
+ ushort t = Ten;
+ ushort f = F101(t);
+ return (f == 100);
+ }
+
+ static ushort F102(ushort x)
+ {
+ return x >= 10 ? (ushort) 100 : (ushort) 0;
+ }
+
+ static bool Bench10p2()
+ {
+ ushort t = 10;
+ ushort f = F102(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n2()
+ {
+ ushort t = Ten;
+ ushort f = F102(t);
+ return (f == 100);
+ }
+
+ static ushort F103(ushort x)
+ {
+ return x <= 10 ? (ushort) 100 : (ushort) 0;
+ }
+
+ static bool Bench10p3()
+ {
+ ushort t = 10;
+ ushort f = F103(t);
+ return (f == 100);
+ }
+
+ static bool Bench10n3()
+ {
+ ushort t = Ten;
+ ushort f = F102(t);
+ return (f == 100);
+ }
+
+ static ushort F11(ushort x)
+ {
+ if (x == 10)
+ {
+ return 100;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ static bool Bench11p()
+ {
+ ushort t = 10;
+ ushort f = F11(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n()
+ {
+ ushort t = Ten;
+ ushort f = F11(t);
+ return (f == 100);
+ }
+
+ static ushort F111(ushort x)
+ {
+ if (x != 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p1()
+ {
+ ushort t = 10;
+ ushort f = F111(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n1()
+ {
+ ushort t = Ten;
+ ushort f = F111(t);
+ return (f == 100);
+ }
+
+ static ushort F112(ushort x)
+ {
+ if (x > 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p2()
+ {
+ ushort t = 10;
+ ushort f = F112(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n2()
+ {
+ ushort t = Ten;
+ ushort f = F112(t);
+ return (f == 100);
+ }
+ static ushort F113(ushort x)
+ {
+ if (x < 10)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ static bool Bench11p3()
+ {
+ ushort t = 10;
+ ushort f = F113(t);
+ return (f == 100);
+ }
+
+ static bool Bench11n3()
+ {
+ ushort t = Ten;
+ ushort f = F113(t);
+ return (f == 100);
+ }
+
+ // Ununsed (or effectively unused) parameters
+ //
+ // Simple callee analysis may overstate inline benefit
+
+ static ushort F20(ushort x)
+ {
+ return 100;
+ }
+
+ static bool Bench20p()
+ {
+ ushort t = 10;
+ ushort f = F20(t);
+ return (f == 100);
+ }
+
+ static bool Bench20p1()
+ {
+ ushort t = Ten;
+ ushort f = F20(t);
+ return (f == 100);
+ }
+
+ static ushort F21(ushort x)
+ {
+ return (ushort)(-x + 100 + x);
+ }
+
+ static bool Bench21p()
+ {
+ ushort t = 10;
+ ushort f = F21(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n()
+ {
+ ushort t = Ten;
+ ushort f = F21(t);
+ return (f == 100);
+ }
+
+ static ushort F211(ushort x)
+ {
+ return (ushort)(x - x + 100);
+ }
+
+ static bool Bench21p1()
+ {
+ ushort t = 10;
+ ushort f = F211(t);
+ return (f == 100);
+ }
+
+ static bool Bench21n1()
+ {
+ ushort t = Ten;
+ ushort f = F211(t);
+ return (f == 100);
+ }
+
+ static ushort F22(ushort x)
+ {
+ if (x > 0)
+ {
+ return 100;
+ }
+
+ return 100;
+ }
+
+ static bool Bench22p()
+ {
+ ushort t = 10;
+ ushort f = F22(t);
+ return (f == 100);
+ }
+
+ static bool Bench22p1()
+ {
+ ushort t = Ten;
+ ushort f = F22(t);
+ return (f == 100);
+ }
+
+ static ushort F23(ushort x)
+ {
+ if (x > 0)
+ {
+ return (ushort)(90 + x);
+ }
+
+ return 100;
+ }
+
+ static bool Bench23p()
+ {
+ ushort t = 10;
+ ushort f = F23(t);
+ return (f == 100);
+ }
+
+ static bool Bench23n()
+ {
+ ushort t = Ten;
+ ushort f = F23(t);
+ return (f == 100);
+ }
+
+ // Multiple parameters
+
+ static ushort F30(ushort x, ushort y)
+ {
+ return (ushort)(y * y);
+ }
+
+ static bool Bench30p()
+ {
+ ushort t = 10;
+ ushort f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n()
+ {
+ ushort t = Ten;
+ ushort f = F30(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p1()
+ {
+ ushort s = Ten;
+ ushort t = 10;
+ ushort f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n1()
+ {
+ ushort s = 10;
+ ushort t = Ten;
+ ushort f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p2()
+ {
+ ushort s = 10;
+ ushort t = 10;
+ ushort f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n2()
+ {
+ ushort s = Ten;
+ ushort t = Ten;
+ ushort f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30p3()
+ {
+ ushort s = 10;
+ ushort t = s;
+ ushort f = F30(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench30n3()
+ {
+ ushort s = Ten;
+ ushort t = s;
+ ushort f = F30(s, t);
+ return (f == 100);
+ }
+
+ static ushort F31(ushort x, ushort y, ushort z)
+ {
+ return (ushort)(z * z);
+ }
+
+ static bool Bench31p()
+ {
+ ushort t = 10;
+ ushort f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n()
+ {
+ ushort t = Ten;
+ ushort f = F31(t, t, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p1()
+ {
+ ushort r = Ten;
+ ushort s = Ten;
+ ushort t = 10;
+ ushort f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n1()
+ {
+ ushort r = 10;
+ ushort s = 10;
+ ushort t = Ten;
+ ushort f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p2()
+ {
+ ushort r = 10;
+ ushort s = 10;
+ ushort t = 10;
+ ushort f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n2()
+ {
+ ushort r = Ten;
+ ushort s = Ten;
+ ushort t = Ten;
+ ushort f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31p3()
+ {
+ ushort r = 10;
+ ushort s = r;
+ ushort t = s;
+ ushort f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ static bool Bench31n3()
+ {
+ ushort r = Ten;
+ ushort s = r;
+ ushort t = s;
+ ushort f = F31(r, s, t);
+ return (f == 100);
+ }
+
+ // Two args, both used
+
+ static ushort F40(ushort x, ushort y)
+ {
+ return (ushort)(x * x + y * y - 100);
+ }
+
+ static bool Bench40p()
+ {
+ ushort t = 10;
+ ushort f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40n()
+ {
+ ushort t = Ten;
+ ushort f = F40(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p1()
+ {
+ ushort s = Ten;
+ ushort t = 10;
+ ushort f = F40(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench40p2()
+ {
+ ushort s = 10;
+ ushort t = Ten;
+ ushort f = F40(s, t);
+ return (f == 100);
+ }
+
+ static ushort F41(ushort x, ushort y)
+ {
+ return (ushort)(x * y);
+ }
+
+ static bool Bench41p()
+ {
+ ushort t = 10;
+ ushort f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41n()
+ {
+ ushort t = Ten;
+ ushort f = F41(t, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p1()
+ {
+ ushort s = 10;
+ ushort t = Ten;
+ ushort f = F41(s, t);
+ return (f == 100);
+ }
+
+ static bool Bench41p2()
+ {
+ ushort s = Ten;
+ ushort t = 10;
+ ushort f = F41(s, t);
+ return (f == 100);
+ }
+
+ private static IEnumerable<object[]> MakeArgs(params string[] args)
+ {
+ return args.Select(arg => new object[] { arg });
+ }
+
+ public static IEnumerable<object[]> TestFuncs = MakeArgs(
+ "Bench00p", "Bench00n",
+ "Bench00p1", "Bench00n1",
+ "Bench00p2", "Bench00n2",
+ "Bench00p3", "Bench00n3",
+ "Bench00p4", "Bench00n4",
+ "Bench01p", "Bench01n",
+ "Bench02p", "Bench02n",
+ "Bench03p", "Bench03n",
+ "Bench04p", "Bench04n",
+ "Bench05p", "Bench05n",
+ "Bench05p1", "Bench05n1",
+ "Bench06p", "Bench06n",
+ "Bench07p", "Bench07n",
+ "Bench07p1", "Bench07n1",
+ "Bench08p", "Bench08n",
+ "Bench09p", "Bench09n",
+ "Bench10p", "Bench10n",
+ "Bench10p1", "Bench10n1",
+ "Bench10p2", "Bench10n2",
+ "Bench10p3", "Bench10n3",
+ "Bench11p", "Bench11n",
+ "Bench11p1", "Bench11n1",
+ "Bench11p2", "Bench11n2",
+ "Bench11p3", "Bench11n3",
+ "Bench20p", "Bench20p1",
+ "Bench21p", "Bench21n",
+ "Bench21p1", "Bench21n1",
+ "Bench22p", "Bench22p1",
+ "Bench23p", "Bench23n",
+ "Bench30p", "Bench30n",
+ "Bench30p1", "Bench30n1",
+ "Bench30p2", "Bench30n2",
+ "Bench30p3", "Bench30n3",
+ "Bench31p", "Bench31n",
+ "Bench31p1", "Bench31n1",
+ "Bench31p2", "Bench31n2",
+ "Bench31p3", "Bench31n3",
+ "Bench40p", "Bench40n",
+ "Bench40p1", "Bench40p2",
+ "Bench41p", "Bench41n",
+ "Bench41p1", "Bench41p2"
+ );
+
+ static Func<bool> LookupFunc(object o)
+ {
+ TypeInfo t = typeof(ConstantArgsUShort).GetTypeInfo();
+ MethodInfo m = t.GetDeclaredMethod((string) o);
+ return m.CreateDelegate(typeof(Func<bool>)) as Func<bool>;
+ }
+
+ [Benchmark]
+ [MemberData(nameof(TestFuncs))]
+ public static void Test(object funcName)
+ {
+ Func<bool> f = LookupFunc(funcName);
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ f();
+ }
+ }
+ }
+ }
+
+ static bool TestBase(Func<bool> f)
+ {
+ bool result = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ result &= f();
+ }
+ return result;
+ }
+
+ public static int Main()
+ {
+ bool result = true;
+
+ foreach(object[] o in TestFuncs)
+ {
+ string funcName = (string) o[0];
+ Func<bool> func = LookupFunc(funcName);
+ bool thisResult = TestBase(func);
+ if (!thisResult)
+ {
+ Console.WriteLine("{0} failed", funcName);
+ }
+ result &= thisResult;
+ }
+
+ return (result ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.csproj
new file mode 100644
index 0000000000..d59541fe8d
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.csproj
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConstantArgsUShort.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>