From: Will Smith Date: Wed, 9 Aug 2023 18:50:13 +0000 (-0700) Subject: [JIT] ARM64 vector right-shift must dead-code eliminate if the constant is zero.... X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~410 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32cf5dfabe046c2e914a163ed712711d0fc39e2c;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [JIT] ARM64 vector right-shift must dead-code eliminate if the constant is zero. (#90051) * ARM64 vector right-shift must dead-code eliminate if the constant is zero * Update emitarm64.cpp * Use proper size * Formatting * Formatting * Fixing test * Add comment * Add comment --- diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 1c38058..b4e8132 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -5162,6 +5162,9 @@ void emitter::emitIns_R_R_I( assert(isVectorRegister(reg2)); isRightShift = emitInsIsVectorRightShift(ins); + assert(!isRightShift || + (imm != 0 && "instructions for vector right-shift do not allow zero as an immediate value")); + if (insOptsAnyArrangement(opt)) { // Vector operation diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 05ccf66..d3ba9ae 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -335,29 +335,35 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { assert(hasImmediateOperand); - if (isRMW) - { - GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); - - HWIntrinsicImmOpHelper helper(this, intrin.op3, node); + auto emitShift = [&](GenTree* op, regNumber reg) { + HWIntrinsicImmOpHelper helper(this, op, node); for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) { const int shiftAmount = helper.ImmValue(); - GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op2Reg, shiftAmount, opt); + if (shiftAmount == 0) + { + // TODO: Use emitIns_Mov instead. + // We do not use it currently because it will still elide the 'mov' + // even if 'canSkip' is false. We cannot elide the 'mov' here. + GetEmitter()->emitIns_R_R_R(INS_mov, emitTypeSize(node), targetReg, reg, reg); + } + else + { + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, reg, shiftAmount, opt); + } } + }; + + if (isRMW) + { + GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); + emitShift(intrin.op3, op2Reg); } else { - HWIntrinsicImmOpHelper helper(this, intrin.op2, node); - - for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) - { - const int shiftAmount = helper.ImmValue(); - - GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, shiftAmount, opt); - } + emitShift(intrin.op2, op1Reg); } } else