[release/6.0] Fix fgValueNumberArrIndexVal for wide reads (#58427)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Tue, 31 Aug 2021 17:21:56 +0000 (10:21 -0700)
committerGitHub <noreply@github.com>
Tue, 31 Aug 2021 17:21:56 +0000 (10:21 -0700)
* fix fgValueNumberArrIndexVal for wide reads

* Update test

* Fix regressions

* Update valuenum.cpp

Co-authored-by: EgorBo <egorbo@gmail.com>
src/coreclr/jit/valuenum.cpp
src/tests/JIT/Regression/JitBlue/Runtime_57914/Runtime_57914.cs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_57914/Runtime_57914.csproj [new file with mode: 0644]

index 84a7465..8e302db 100644 (file)
@@ -4242,11 +4242,12 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree*             tree,
     var_types elemTyp = DecodeElemType(elemTypeEq);
     var_types indType = (tree == nullptr) ? elemTyp : tree->TypeGet();
     ValueNum  selectedElem;
+    unsigned  elemWidth = elemTyp == TYP_STRUCT ? info.compCompHnd->getClassSize(elemTypeEq) : genTypeSize(elemTyp);
 
-    if (fldSeq == FieldSeqStore::NotAField())
+    if ((fldSeq == FieldSeqStore::NotAField()) || (genTypeSize(indType) > elemWidth))
     {
         // This doesn't represent a proper array access
-        JITDUMP("    *** NotAField sequence encountered in fgValueNumberArrIndexVal\n");
+        JITDUMP("    *** Not a proper arrray access encountered in fgValueNumberArrIndexVal\n");
 
         // a new unique value number
         selectedElem = vnStore->VNForExpr(compCurBB, elemTyp);
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_57914/Runtime_57914.cs b/src/tests/JIT/Regression/JitBlue/Runtime_57914/Runtime_57914.cs
new file mode 100644 (file)
index 0000000..f11dc7d
--- /dev/null
@@ -0,0 +1,50 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.CompilerServices;
+
+public class Program
+{
+    public static int Main()
+    {
+        return (Test1() && Test2()) ? 100 : 101;
+    }
+
+    private static bool Test1()
+    {
+        byte[] array = new byte[2];
+        array[0] = 1;
+        array[1] = 2;
+
+        // a1, a2 and a3 all have different values here
+        byte a1  = Unsafe.ReadUnaligned<byte>(ref array[0]);
+        short a2 = Unsafe.ReadUnaligned<short>(ref array[0]);
+        array[1] = 42;
+        short a3 = Unsafe.ReadUnaligned<short>(ref array[0]);
+
+        return a1 != a2 && a1 != a3 && a2 != a3;
+    }
+
+    private static bool Test2()
+    {
+        bool result = true;
+        byte[] buffer = new byte[4];
+        buffer[0] = 0x1;
+        buffer[1] = 0x2;
+        buffer[2] = 0x3;
+        buffer[3] = 0x4;
+
+        if (buffer.Length > 0)
+        {
+            int n = Unsafe.ReadUnaligned<int>(ref buffer[0]);
+            if (n != 0x4030201)
+                result = false;
+            Consume(n);
+        }
+        return result;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    static void Consume(int n) {}
+}
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_57914/Runtime_57914.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_57914/Runtime_57914.csproj
new file mode 100644 (file)
index 0000000..f3e1cbd
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>None</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>