From 01fc675c987997bbcf12c3d5c3df289cd755fc66 Mon Sep 17 00:00:00 2001 From: Clinton Ingram Date: Fri, 11 Jul 2025 14:58:09 -0700 Subject: [PATCH] allow containment of CnsVec under GetElement node with non-const index --- src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 8 ++++++++ src/coreclr/jit/lowerxarch.cpp | 2 +- src/coreclr/jit/lsraxarch.cpp | 7 ++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index 361e9ae8eee6ed..9402f64ffcff2c 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -2056,6 +2056,14 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) } baseReg = (isEBPbased) ? REG_EBP : REG_ESP; } + else if (op1->IsCnsVec()) + { + CORINFO_FIELD_HANDLE hnd = + GetEmitter()->emitSimdConst(&op1->AsVecCon()->gtSimdVal, emitTypeSize(op1)); + + baseReg = internalRegisters.GetSingle(node); + GetEmitter()->emitIns_R_C(INS_lea, emitTypeSize(TYP_I_IMPL), baseReg, hnd, 0, INS_OPTS_NONE); + } else { // Require GT_IND addr to be not contained. diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 784115399ced4c..fda8b11c9c2e37 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -10121,7 +10121,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) MakeSrcContained(node, op2); } - if (IsContainableMemoryOp(op1) && IsSafeToContainMem(node, op1)) + if (op1->IsCnsVec() || (IsContainableMemoryOp(op1) && IsSafeToContainMem(node, op1))) { MakeSrcContained(node, op1); } diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 8fb7ae7cfb6016..47c232540580d9 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -2304,12 +2304,17 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou if (!op2->OperIsConst() && !op1->isContained()) { - // If the index is not a constant or op1 is in register, + // If the index is not a constant and op1 is in register, // we will use the SIMD temp location to store the vector. var_types requiredSimdTempType = Compiler::getSIMDTypeForSize(intrinsicTree->GetSimdSize()); compiler->getSIMDInitTempVarNum(requiredSimdTempType); } + else if (op1->IsCnsVec()) + { + // We need an int reg to load the address of the CnsVec data. + buildInternalIntRegisterDefForNode(intrinsicTree); + } break; }