@@ -1257,7 +1257,7 @@ void LowererMD::ChangeToShift(IR::Instr *const instr, const bool needFlags)
12571257 }
12581258}
12591259
1260- void LowererMD::ChangeToMul (IR::Instr *const instr, bool hasOverflowCheck)
1260+ void LowererMD::ChangeToIMul (IR::Instr *const instr, bool hasOverflowCheck)
12611261{
12621262 // If non-32 bit overflow check is needed, we have to use the IMUL form.
12631263 if (hasOverflowCheck && !instr->ShouldCheckFor32BitOverflow () && instr->ShouldCheckForNon32BitOverflow ())
@@ -1272,8 +1272,29 @@ void LowererMD::ChangeToMul(IR::Instr *const instr, bool hasOverflowCheck)
12721272 {
12731273 // MOV reg, imm
12741274 temp2 = IR::RegOpnd::New (TyInt32, instr->m_func );
1275+
1276+ IR::Opnd * src2 = instr->GetSrc2 ();
1277+ bool dontEncode = false ;
1278+ if (src2->IsHelperCallOpnd ())
1279+ {
1280+ dontEncode = true ;
1281+ }
1282+ else if (src2->IsIntConstOpnd () || src2->IsAddrOpnd ())
1283+ {
1284+ dontEncode = src2->IsIntConstOpnd () ? src2->AsIntConstOpnd ()->m_dontEncode : src2->AsAddrOpnd ()->m_dontEncode ;
1285+ }
1286+ else if (src2->IsInt64ConstOpnd ())
1287+ {
1288+ dontEncode = false ;
1289+ }
1290+ else
1291+ {
1292+ AssertMsg (false , " Unexpected immediate opnd" );
1293+ throw Js::OperationAbortedException ();
1294+ }
1295+
12751296 instr->InsertBefore (IR::Instr::New (Js::OpCode::MOV, temp2,
1276- IR::IntConstOpnd::New ((IntConstType)instr->GetSrc2 ()->GetImmediateValue (instr->m_func ), TyInt32, instr->m_func , true ),
1297+ IR::IntConstOpnd::New ((IntConstType)instr->GetSrc2 ()->GetImmediateValue (instr->m_func ), TyInt32, instr->m_func , dontEncode ),
12771298 instr->m_func ));
12781299 }
12791300 // eax = IMUL eax, reg
@@ -2061,7 +2082,7 @@ void LowererMD::LegalizeSrc(IR::Instr *const instr, IR::Opnd *src, const uint fo
20612082 if (!instr->isInlineeEntryInstr )
20622083 {
20632084 Assert (forms & L_Reg);
2064- IR::IntConstOpnd * newIntOpnd = IR::IntConstOpnd::New ( intOpnd->GetValue (), intOpnd-> GetType (), instr-> m_func , true );
2085+ IR::IntConstOpnd * newIntOpnd = intOpnd->Copy (instr-> m_func )-> AsIntConstOpnd ( );
20652086 IR::IndirOpnd * indirOpnd = instr->m_func ->GetTopFunc ()->GetConstantAddressIndirOpnd (intOpnd->GetValue (), newIntOpnd, IR::AddrOpndKindConstantAddress, TyMachPtr, Js::OpCode::MOV);
20662087 if (HoistLargeConstant (indirOpnd, src, instr))
20672088 {
@@ -2125,7 +2146,7 @@ void LowererMD::LegalizeSrc(IR::Instr *const instr, IR::Opnd *src, const uint fo
21252146 Assert (!instr->isInlineeEntryInstr );
21262147 Assert (forms & L_Reg);
21272148 // TODO: michhol, remove cast after making m_address intptr
2128- IR::AddrOpnd * newAddrOpnd = IR::AddrOpnd::New ( addrOpnd->m_address , addrOpnd-> GetAddrOpndKind (), instr->m_func , true );
2149+ IR::AddrOpnd * newAddrOpnd = addrOpnd->Copy ( instr->m_func )-> AsAddrOpnd ( );
21292150 IR::IndirOpnd * indirOpnd = instr->m_func ->GetTopFunc ()->GetConstantAddressIndirOpnd ((intptr_t )addrOpnd->m_address , newAddrOpnd, addrOpnd->GetAddrOpndKind (), TyMachPtr, Js::OpCode::MOV);
21302151 if (HoistLargeConstant (indirOpnd, src, instr))
21312152 {
@@ -6645,7 +6666,7 @@ LowererMD::EmitLoadFloatCommon(IR::Opnd *dst, IR::Opnd *src, IR::Instr *insertIn
66456666}
66466667
66476668IR::RegOpnd *
6648- LowererMD::EmitLoadFloat (IR::Opnd *dst, IR::Opnd *src, IR::Instr *insertInstr)
6669+ LowererMD::EmitLoadFloat (IR::Opnd *dst, IR::Opnd *src, IR::Instr *insertInstr, bool bailOutOnHelperCall )
66496670{
66506671 IR::LabelInstr *labelDone;
66516672 IR::Instr *instr;
@@ -6657,6 +6678,23 @@ LowererMD::EmitLoadFloat(IR::Opnd *dst, IR::Opnd *src, IR::Instr *insertInstr)
66576678 return nullptr ;
66586679 }
66596680
6681+ if (bailOutOnHelperCall)
6682+ {
6683+ if (!GlobOpt::DoEliminateArrayAccessHelperCall (this ->m_func ))
6684+ {
6685+ // Array access helper call removal is already off for some reason. Prevent trying to rejit again
6686+ // because it won't help and the same thing will happen again. Just abort jitting this function.
6687+ if (PHASE_TRACE (Js::BailOutPhase, this ->m_func ))
6688+ {
6689+ Output::Print (_u (" Aborting JIT because EliminateArrayAccessHelperCall is already off\n " ));
6690+ Output::Flush ();
6691+ }
6692+ throw Js::OperationAbortedException ();
6693+ }
6694+
6695+ throw Js::RejitException (RejitReason::ArrayAccessHelperCallEliminationDisabled);
6696+ }
6697+
66606698 IR::Opnd *memAddress = dst;
66616699
66626700 if (dst->IsRegOpnd ())
@@ -7219,7 +7257,7 @@ LowererMD::LowerInt4MulWithBailOut(
72197257 // Lower the instruction
72207258 if (!simplifiedMul)
72217259 {
7222- LowererMD::ChangeToMul (instr, needsOverflowCheck);
7260+ LowererMD::ChangeToIMul (instr, needsOverflowCheck);
72237261 }
72247262
72257263 const auto insertBeforeInstr = checkForNegativeZeroLabel ? checkForNegativeZeroLabel : bailOutLabel;
0 commit comments