From e9cd3f19f39cf08916e5922a43ea986dbb661b7b Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Fri, 31 May 2024 20:58:56 +0200 Subject: [PATCH] JIT: Consume FMA intrinsic operands in right order (#102914) The operands of the FMA intrinsic are permuted in a non-standard way during LSRA. Codegen already takes this into account, but the handling was missing when consuming the operands. Fix #102773 --- src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index 8ef9517c344d5..11d746111be5a 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -3053,8 +3053,6 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) regNumber targetReg = node->GetRegNum(); - genConsumeMultiOpOperands(node); - regNumber op1NodeReg = op1->GetRegNum(); regNumber op2NodeReg = op2->GetRegNum(); regNumber op3NodeReg = op3->GetRegNum(); @@ -3143,6 +3141,21 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) } } +#ifdef DEBUG + // Use nums are assigned in LIR order but this node is special and doesn't + // actually use operands. Fix up the use nums here to avoid asserts. + unsigned useNum1 = op1->gtUseNum; + unsigned useNum2 = op2->gtUseNum; + unsigned useNum3 = op3->gtUseNum; + emitOp1->gtUseNum = useNum1; + emitOp2->gtUseNum = useNum2; + emitOp3->gtUseNum = useNum3; +#endif + + genConsumeRegs(emitOp1); + genConsumeRegs(emitOp2); + genConsumeRegs(emitOp3); + assert(ins != INS_invalid); genHWIntrinsic_R_R_R_RM(ins, attr, targetReg, emitOp1->GetRegNum(), emitOp2->GetRegNum(), emitOp3, instOptions); genProduceReg(node);