summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMike Danes <onemihaid@hotmail.com>2018-01-20 14:08:37 +0200
committerMike Danes <onemihaid@hotmail.com>2018-01-20 14:08:37 +0200
commitca397e5f57a649ad3bcc621cbb02354670f87a08 (patch)
tree4a494f97f3fdf53603483950aa61dd103dc62a8d /tests
parentc7c2869ca0def15c25b8043ac78a378e0145bac8 (diff)
downloadcoreclr-ca397e5f57a649ad3bcc621cbb02354670f87a08.tar.gz
coreclr-ca397e5f57a649ad3bcc621cbb02354670f87a08.tar.bz2
coreclr-ca397e5f57a649ad3bcc621cbb02354670f87a08.zip
Fix 64 bit shift inconsistencies (on 32 bit targets)
Recent shift changes made the JIT_LLsh helper mask the shift count to 6 bits. The other 2 helpers (JIT_LRsh and JIT_LRsz) so now we get inconsistencies such as `(x >> 64) != (x << 64)`. The ECMA spec says that "the return value is unspecified if shiftAmount is greater than or equal to the width of value" so the JIT has no obligation to implement a particular behavior. But it seems preferable to have all shift instructions behave similarly, it avoids complications and reduces risks. This also changes `ValueNumStore::EvalOpIntegral` to mask the shift count for 64 bit shifts so it matches `gtFoldExprConst`. Otherwise the produced value depends on the C/C++ compiler's behavior.
Diffstat (limited to 'tests')
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.il235
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.ilproj23
2 files changed, 258 insertions, 0 deletions
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.il b/tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.il
new file mode 100644
index 0000000000..34c07b13d2
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.il
@@ -0,0 +1,235 @@
+// 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.
+
+.assembly extern mscorlib { auto }
+.assembly extern System.Console { auto }
+.assembly GitHub_15949 { }
+
+// Ensure that shifting a 64 bit value by 64 bits produces the same value. The ECMA spec doesn't specify
+// what should happen in this case but it would be preferable to have the same behavior for all shift
+// instructions (use only the lowest 6 bits of the shift count).
+
+// This test is intended for 32 bit targets where RyuJIT has 4 different code paths that are of interest:
+// helper call, decomposition, constant folding via gtFoldExpr and constant folding via VN's EvalOpIntegral.
+// But it also works on the current 64 bit targets (ARM64 & x64) because they too have the same behavior.
+
+.class private auto ansi Program extends [mscorlib]System.Object
+{
+ .method static int32 Main() cil managed
+ {
+ .entrypoint
+ .maxstack 8
+ .locals(int64)
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shl_Helper(int64, int32, bool)
+ stloc.0
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shr_Helper(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_ShrUn_Helper(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shl_Decompose(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shr_Decompose(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_ShrUn_Decompose(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shl_gtFoldExpr(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shr_gtFoldExpr(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_ShrUn_gtFoldExpr(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shl_EvalOpIntegral(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_Shr_EvalOpIntegral(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ ldc.i4 1
+ call int64 Program::Test_ShrUn_EvalOpIntegral(int64, int32, bool)
+ ldloc.0
+ bne.un FAIL
+
+ ldc.i4 100
+ ret
+
+ FAIL:
+ ldc.i4 1
+ ret
+ }
+
+ .method static int64 Test_Shl_Helper(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldarg.0
+ ldarg.1
+ shl
+ ret
+ }
+
+ .method static int64 Test_Shr_Helper(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldarg.0
+ ldarg.1
+ shr
+ ret
+ }
+
+ .method static int64 Test_ShrUn_Helper(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldarg.0
+ ldarg.1
+ shr.un
+ ret
+ }
+
+ .method static int64 Test_Shl_Decompose(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldarg.0
+ ldc.i4 64
+ shl
+ ret
+ }
+
+ .method static int64 Test_Shr_Decompose(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldarg.0
+ ldc.i4 64
+ shr
+ ret
+ }
+
+ .method static int64 Test_ShrUn_Decompose(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldarg.0
+ ldc.i4 64
+ shr.un
+ ret
+ }
+
+ .method static int64 Test_Shl_gtFoldExpr(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ shl
+ ret
+ }
+
+ .method static int64 Test_Shr_gtFoldExpr(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ shr
+ ret
+ }
+
+ .method static int64 Test_ShrUn_gtFoldExpr(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldc.i8 0x1020304050607080
+ ldc.i4 64
+ shr.un
+ ret
+ }
+
+ .method static int64 Test_Shl_EvalOpIntegral(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldc.i8 0x1020304050607080
+ ldarg.2
+ brtrue L1
+ ldc.i4 64
+ br L2
+ L1: ldc.i4 64
+ L2: shl
+ ret
+ }
+
+ .method static int64 Test_Shr_EvalOpIntegral(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldc.i8 0x1020304050607080
+ ldarg.2
+ brtrue L1
+ ldc.i4 64
+ br L2
+ L1: ldc.i4 64
+ L2: shr
+ ret
+ }
+
+ .method static int64 Test_ShrUn_EvalOpIntegral(int64, int32, bool) cil managed noinlining
+ {
+ .maxstack 2
+ ldc.i8 0x1020304050607080
+ ldarg.2
+ brtrue L1
+ ldc.i4 64
+ br L2
+ L1: ldc.i4 64
+ L2: shr.un
+ ret
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.ilproj b/tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.ilproj
new file mode 100644
index 0000000000..65b4dcf5f4
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949.ilproj
@@ -0,0 +1,23 @@
+<?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>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="GitHub_15949.il" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project> \ No newline at end of file