From: mikedn Date: Fri, 8 Nov 2019 23:21:49 +0000 (+0200) Subject: Fix mismatched type IND(LCL_VAR_ADDR) folding in RewriteSIMDOperand (dotnet/coreclr... X-Git-Tag: submit/tizen/20210909.063632~11030^2~64 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7e41822ef78aba5ce583c1bd539572d4c3d3ae8d;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fix mismatched type IND(LCL_VAR_ADDR) folding in RewriteSIMDOperand (dotnet/coreclr#27748) * Fix mismatched type IND(LCL_VAR_ADDR) folding in RewriteSIMDOperand If the indirection and the variable have different SIMD types then a LCL_FLD node of the appropiate type is needed instead of a LCL_VAR node. * Delete unused loadForm function Commit migrated from https://github.com/dotnet/coreclr/commit/a0bbdf98efd5b96c041d8b49d2a61d0ce5bf3212 --- diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 06451ab85ec..2a4c5c8ba82 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -7768,27 +7768,6 @@ private: return isOpaqueSIMDType(varDsc->lvVerTypeInfo.GetClassHandle()); } - // Returns true if the type of the tree is a byref of TYP_SIMD - bool isAddrOfSIMDType(GenTree* tree) - { - if (tree->TypeGet() == TYP_BYREF || tree->TypeGet() == TYP_I_IMPL) - { - switch (tree->OperGet()) - { - case GT_ADDR: - return varTypeIsSIMD(tree->gtGetOp1()); - - case GT_LCL_VAR_ADDR: - return lvaTable[tree->AsLclVarCommon()->GetLclNum()].lvSIMDType; - - default: - return isSIMDTypeLocal(tree); - } - } - - return false; - } - static bool isRelOpSIMDIntrinsic(SIMDIntrinsicID intrinsicId) { return (intrinsicId == SIMDIntrinsicEqual || intrinsicId == SIMDIntrinsicLessThan || diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index 4293880e392..4c1f32c6f92 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -37,21 +37,6 @@ genTreeOps addrForm(genTreeOps loadForm) } } -// return op that is the load equivalent of the given addr opcode -genTreeOps loadForm(genTreeOps addrForm) -{ - switch (addrForm) - { - case GT_LCL_VAR_ADDR: - return GT_LCL_VAR; - case GT_LCL_FLD_ADDR: - return GT_LCL_FLD; - default: - noway_assert(!"not a local address opcode\n"); - unreached(); - } -} - // copy the flags determined by mask from src to dst void copyFlags(GenTree* dst, GenTree* src, unsigned mask) { @@ -93,14 +78,33 @@ void Rationalizer::RewriteSIMDOperand(LIR::Use& use, bool keepBlk) return; } - // If we have GT_IND(GT_LCL_VAR_ADDR) and the GT_LCL_VAR_ADDR is TYP_BYREF/TYP_I_IMPL, - // and the var is a SIMD type, replace the expression by GT_LCL_VAR. + // If we have GT_IND(GT_LCL_VAR_ADDR) and the var is a SIMD type, + // replace the expression by GT_LCL_VAR or GT_LCL_FLD. GenTree* addr = tree->AsIndir()->Addr(); - if (addr->OperIsLocalAddr() && comp->isAddrOfSIMDType(addr)) + if (addr->OperIs(GT_LCL_VAR_ADDR) && comp->lvaGetDesc(addr->AsLclVar())->lvSIMDType) { BlockRange().Remove(tree); - addr->SetOper(loadForm(addr->OperGet())); + var_types lclType = comp->lvaGetDesc(addr->AsLclVar())->TypeGet(); + + if (lclType == simdType) + { + addr->SetOper(GT_LCL_VAR); + } + else + { + addr->SetOper(GT_LCL_FLD); + addr->AsLclFld()->gtLclOffs = 0; + addr->AsLclFld()->gtFieldSeq = FieldSeqStore::NotAField(); + + if (((addr->gtFlags & GTF_VAR_DEF) != 0) && (genTypeSize(simdType) < genTypeSize(lclType))) + { + addr->gtFlags |= GTF_VAR_USEASG; + } + + comp->lvaSetVarDoNotEnregister(addr->AsLclFld()->GetLclNum() DEBUGARG(Compiler::DNER_LocalField)); + } + addr->gtType = simdType; use.ReplaceWith(comp, addr); } diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_27405/GitHub_27405.cs b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_27405/GitHub_27405.cs new file mode 100644 index 00000000000..1b76993f602 --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_27405/GitHub_27405.cs @@ -0,0 +1,41 @@ +// 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 System; +using System.Numerics; +using System.Runtime.CompilerServices; + +class Program +{ + static int Main() + { + Vector3 v3 = Test1(new Vector4(1, 2, 3, 4)); + if (v3.X != 1 || v3.Y != 2 || v3.Z != 3) + { + return 42; + } + + Vector4 v4 = Test2(new Vector4(1, 2, 3, 4), new Vector4(2, 1, 4, 3)); + if (v4.X != 3 || v4.Y != 6 || v4.Z != 21 || v4.W != 0) + { + return 43; + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + public static Vector3 Test1(Vector4 value) + { + return Unsafe.As(ref value); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + static Vector4 Test2(Vector4 a, Vector4 b) + { + Vector4 c = a + b; + Vector3 d = Unsafe.As(ref c); + return a * new Vector4(d, 0); + } +} diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_27405/GitHub_27405.csproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_27405/GitHub_27405.csproj new file mode 100644 index 00000000000..f3e1cbd44b4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_27405/GitHub_27405.csproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + +