Handle contained BITCAST for STORE_LCL_FLD (#55852)
authorKunal Pathak <Kunal.Pathak@microsoft.com>
Tue, 20 Jul 2021 22:23:59 +0000 (15:23 -0700)
committerGitHub <noreply@github.com>
Tue, 20 Jul 2021 22:23:59 +0000 (15:23 -0700)
* Do not mark BITCAST as contained for STORE_LCL_FLD

* Add unit test

* Handle contained BITCAST in STORE_LCL_FLD

* Return 100

src/coreclr/jit/codegenxarch.cpp
src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.cs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.csproj [new file with mode: 0644]

index 6f605e5514bdc95cae292ab5fa91ca0b94692ca6..e361a56ae4747c5083d3f0717961742c69b7ef4f 100644 (file)
@@ -4425,7 +4425,7 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree)
 
 #ifdef FEATURE_SIMD
     // storing of TYP_SIMD12 (i.e. Vector3) field
-    if (tree->TypeGet() == TYP_SIMD12)
+    if (targetType == TYP_SIMD12)
     {
         genStoreLclTypeSIMD12(tree);
         return;
@@ -4436,7 +4436,32 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree)
     assert(genTypeSize(genActualType(targetType)) == genTypeSize(genActualType(op1->TypeGet())));
 
     genConsumeRegs(op1);
-    GetEmitter()->emitInsBinary(ins_Store(targetType), emitTypeSize(tree), tree, op1);
+
+    if (op1->OperIs(GT_BITCAST) && op1->isContained())
+    {
+        regNumber targetReg  = tree->GetRegNum();
+        GenTree*  bitCastSrc = op1->gtGetOp1();
+        var_types srcType    = bitCastSrc->TypeGet();
+        noway_assert(!bitCastSrc->isContained());
+
+        if (targetReg == REG_NA)
+        {
+            unsigned   lclNum = tree->GetLclNum();
+            LclVarDsc* varDsc = compiler->lvaGetDesc(lclNum);
+
+            GetEmitter()->emitIns_S_R(ins_Store(srcType, compiler->isSIMDTypeLocalAligned(lclNum)),
+                                      emitTypeSize(targetType), bitCastSrc->GetRegNum(), lclNum, 0);
+            varDsc->SetRegNum(REG_STK);
+        }
+        else
+        {
+            genBitCast(targetType, targetReg, srcType, bitCastSrc->GetRegNum());
+        }
+    }
+    else
+    {
+        GetEmitter()->emitInsBinary(ins_Store(targetType), emitTypeSize(tree), tree, op1);
+    }
 
     // Updating variable liveness after instruction was emitted
     genUpdateLife(tree);
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.cs b/src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.cs
new file mode 100644 (file)
index 0000000..bad94d8
--- /dev/null
@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.CompilerServices;
+
+struct S0
+{
+    public ulong F0;
+    public ulong F1;
+    public long F2;
+    public uint F4;
+    public uint F6;
+}
+
+public class Runtime_55141
+{
+    // UDIV is lowered to the MULHI/BITCAST nodes and they are stored in field (STORE_LCL_FLD).
+    // BITCAST is marked as contained so the value to be stored can be used from MULHI, but marking
+    // the containment of BITCAST is not supported in codegen for STORE_LCL_FLD.
+    public static int Main()
+    {
+        return (uint)Run(0) == 0 ? 100 : 0;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    public static uint Run(long x)
+    {
+        S0 vr1 = default(S0);
+        vr1.F4 = (uint)x / 254;
+        return vr1.F6;
+    }
+}
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.csproj
new file mode 100644 (file)
index 0000000..e8e73ed
--- /dev/null
@@ -0,0 +1,10 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <Optimize>True</Optimize>
+    <DebugType>None</DebugType>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>
\ No newline at end of file