diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 4ca436f1d54e..5c22ec898f44 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -5775,12 +5775,8 @@ AttachDecision CallIRGenerator::tryAttachMathRound(HandleFunction callee) { } AttachDecision CallIRGenerator::tryAttachMathSqrt(HandleFunction callee) { - // Need one argument. - if (argc_ != 1) { - return AttachDecision::NoAction; - } - - if (!args_[0].isNumber()) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { return AttachDecision::NoAction; } @@ -5803,6 +5799,31 @@ AttachDecision CallIRGenerator::tryAttachMathSqrt(HandleFunction callee) { return AttachDecision::Attach; } +AttachDecision CallIRGenerator::tryAttachMathFRound(HandleFunction callee) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'fround' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argumentId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + NumberOperandId numberId = writer.guardIsNumber(argumentId); + writer.mathFRoundNumberResult(numberId); + + // Math.fround always returns a double so we don't need type monitoring. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathFRound"); + return AttachDecision::Attach; +} + static bool CanAttachInt32Pow(const Value& baseVal, const Value& powerVal) { MOZ_ASSERT(baseVal.isInt32() || baseVal.isBoolean()); MOZ_ASSERT(powerVal.isInt32() || powerVal.isBoolean()); @@ -6224,6 +6245,8 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( return tryAttachMathRound(callee); case InlinableNative::MathSqrt: return tryAttachMathSqrt(callee); + case InlinableNative::MathFRound: + return tryAttachMathFRound(callee); case InlinableNative::MathATan2: return tryAttachMathATan2(callee); case InlinableNative::MathSin: diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index 2248707d4335..11f6ec3a6af4 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -1565,6 +1565,7 @@ class MOZ_RAII CallIRGenerator : public IRGenerator { AttachDecision tryAttachMathCeil(HandleFunction callee); AttachDecision tryAttachMathRound(HandleFunction callee); AttachDecision tryAttachMathSqrt(HandleFunction callee); + AttachDecision tryAttachMathFRound(HandleFunction callee); AttachDecision tryAttachMathATan2(HandleFunction callee); AttachDecision tryAttachMathFunction(HandleFunction callee, UnaryMathFunction fun); diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp index 1109e67905f9..6ed78921afc2 100644 --- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -3848,6 +3848,21 @@ bool CacheIRCompiler::emitMathSqrtNumberResult(NumberOperandId inputId) { return true; } +bool CacheIRCompiler::emitMathFRoundNumberResult(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoAvailableFloatRegister scratch(*this, FloatReg0); + + allocator.ensureDoubleRegister(masm, inputId, scratch); + + masm.convertDoubleToFloat32(scratch, scratch); + masm.convertFloat32ToDouble(scratch, scratch); + + masm.boxDouble(scratch, output.valueReg(), scratch); + return true; +} + bool CacheIRCompiler::emitMathAtan2NumberResult(NumberOperandId yId, NumberOperandId xId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); diff --git a/js/src/jit/CacheIROps.yaml b/js/src/jit/CacheIROps.yaml index 31876300e086..1db651dec92c 100644 --- a/js/src/jit/CacheIROps.yaml +++ b/js/src/jit/CacheIROps.yaml @@ -891,6 +891,13 @@ args: input: NumberId +- name: MathFRoundNumberResult + shared: true + transpile: true + cost_estimate: 1 + args: + input: NumberId + # Because Baseline stub code is shared by all realms in the Zone, this # instruction loads a pointer to the RNG from a stub field. - name: MathRandomResult diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 78a394f7e1bf..7ee9fff6d099 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -4046,6 +4046,12 @@ MDefinition* MToFloat32::foldsTo(TempAllocator& alloc) { float(input->toConstant()->numberToDouble())); } + // Fold ToFloat32(ToDouble(int32)) to ToFloat32(int32). + if (input->isToDouble() && + input->toToDouble()->input()->type() == MIRType::Int32) { + return MToFloat32::New(alloc, input->toToDouble()->input()); + } + return this; } diff --git a/js/src/jit/WarpCacheIRTranspiler.cpp b/js/src/jit/WarpCacheIRTranspiler.cpp index 5808e7b47632..6f3c10407fbb 100644 --- a/js/src/jit/WarpCacheIRTranspiler.cpp +++ b/js/src/jit/WarpCacheIRTranspiler.cpp @@ -1268,6 +1268,17 @@ bool WarpCacheIRTranspiler::emitMathSqrtNumberResult(NumberOperandId inputId) { return true; } +bool WarpCacheIRTranspiler::emitMathFRoundNumberResult( + NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MToFloat32::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; +} + bool WarpCacheIRTranspiler::emitMathAtan2NumberResult(NumberOperandId yId, NumberOperandId xId) { MDefinition* y = getOperand(yId);