From d38a5396608240a6426668238e06056c69b85c50 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Tue, 20 Jul 2021 15:23:59 -0700 Subject: [PATCH] Handle contained BITCAST for STORE_LCL_FLD (#55852) * 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 | 29 +++++++++++++++-- .../JitBlue/Runtime_55141/Runtime_55141.cs | 32 +++++++++++++++++++ .../Runtime_55141/Runtime_55141.csproj | 10 ++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.csproj diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 6f605e5514bdc..e361a56ae4747 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -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 index 0000000000000..bad94d8b1d609 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.cs @@ -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 index 0000000000000..e8e73ed9d1a35 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_55141/Runtime_55141.csproj @@ -0,0 +1,10 @@ + + + Exe + True + None + + + + + \ No newline at end of file