From 09a3007460bee01bdd90280647d82ff7c2b8c518 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 6 Feb 2023 12:23:26 +0100 Subject: [PATCH] Optimize IND(RVA) (#81651) Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/assertionprop.cpp | 2 ++ src/coreclr/jit/valuenum.cpp | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 5f2173b..3a91b5a 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -6157,6 +6157,8 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Sta case GT_ARR_LENGTH: break; + case GT_OBJ: + case GT_BLK: case GT_IND: { const ValueNum vn = tree->GetVN(VNK_Conservative); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index cd91c27..c255ef1 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8770,12 +8770,12 @@ bool Compiler::fgValueNumberConstLoad(GenTreeIndir* tree) // ssize_t byteOffset = 0; FieldSeq* fieldSeq = nullptr; - if ((varTypeIsIntegral(tree) || varTypeIsFloating(tree)) && + if ((varTypeIsSIMD(tree) || varTypeIsIntegral(tree) || varTypeIsFloating(tree)) && GetStaticFieldSeqAndAddress(vnStore, tree->gtGetOp1(), &byteOffset, &fieldSeq)) { CORINFO_FIELD_HANDLE fieldHandle = fieldSeq->GetFieldHandle(); int size = (int)genTypeSize(tree->TypeGet()); - const int maxElementSize = sizeof(int64_t); + const int maxElementSize = 32; // SIMD32 if ((fieldHandle != nullptr) && (size > 0) && (size <= maxElementSize) && ((size_t)byteOffset < INT_MAX)) { uint8_t buffer[maxElementSize] = {0}; @@ -8785,7 +8785,7 @@ bool Compiler::fgValueNumberConstLoad(GenTreeIndir* tree) switch (tree->TypeGet()) { #define READ_VALUE(typ) \ - typ val = 0; \ + typ val = {}; \ memcpy(&val, buffer, sizeof(typ)); case TYP_BOOL: @@ -8849,7 +8849,36 @@ bool Compiler::fgValueNumberConstLoad(GenTreeIndir* tree) tree->gtVNPair.SetBoth(vnStore->VNForDoubleCon(val)); return true; } +#if defined(FEATURE_SIMD) + case TYP_SIMD8: + { + READ_VALUE(simd8_t); + tree->gtVNPair.SetBoth(vnStore->VNForSimd8Con(val)); + return true; + } + case TYP_SIMD12: + { + READ_VALUE(simd12_t); + tree->gtVNPair.SetBoth(vnStore->VNForSimd12Con(val)); + return true; + } + case TYP_SIMD16: + { + READ_VALUE(simd16_t); + tree->gtVNPair.SetBoth(vnStore->VNForSimd16Con(val)); + return true; + } +#if defined(TARGET_XARCH) + case TYP_SIMD32: + { + READ_VALUE(simd32_t); + tree->gtVNPair.SetBoth(vnStore->VNForSimd32Con(val)); + return true; + } +#endif +#endif default: + assert(!varTypeIsSIMD(tree)); break; } } @@ -8857,7 +8886,7 @@ bool Compiler::fgValueNumberConstLoad(GenTreeIndir* tree) } // Throughput check, the logic below is only for USHORT (char) - if (!tree->TypeIs(TYP_USHORT)) + if (!tree->OperIs(GT_IND) || !tree->TypeIs(TYP_USHORT)) { return false; } @@ -9215,7 +9244,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) // Note VNF_PtrToStatic statics are currently always "simple". fgValueNumberFieldLoad(tree, /* baseAddr */ nullptr, fldSeq, offset); } - else if (tree->OperIs(GT_IND) && fgValueNumberConstLoad(tree->AsIndir())) + else if (tree->OperIs(GT_IND, GT_BLK, GT_OBJ) && fgValueNumberConstLoad(tree->AsIndir())) { // VN is assigned inside fgValueNumberConstLoad } -- 2.7.4