Browse Source

Make sure to mark all int64 split symbol as Live on back edge if the original int64 was also live.
Move the int64 split map to Func allowing to use post lower.
Also allowing some lowering methods to be static which was prevented before because it needed an instance of lowerer.

Fixes OS#12708317

Michael Ferris 8 năm trước cách đây
mục cha
commit
a6e2519268

+ 107 - 0
lib/Backend/Func.cpp

@@ -143,6 +143,9 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
     , m_forInEnumeratorArrayOffset(-1)
     , argInsCount(0)
     , m_globalObjTypeSpecFldInfoArray(nullptr)
+#if LOWER_SPLIT_INT64
+    , m_int64SymPairMap(nullptr)
+#endif
 #ifdef RECYCLER_WRITE_BARRIER_JIT
     , m_lowerer(nullptr)
 #endif
@@ -857,6 +860,110 @@ Func::SetDoFastPaths()
 #endif
 }
 
+#if LOWER_SPLIT_INT64
+Int64RegPair Func::FindOrCreateInt64Pair(IR::Opnd* opnd)
+{
+    AssertMsg(this->GetTopFunc()->currentPhases.Top() == Js::LowererPhase, "New Int64 sym map is only allowed during lower");
+    Int64RegPair pair;
+    IRType pairType = opnd->GetType();
+    if (opnd->IsInt64())
+    {
+        pairType = IRType_IsSignedInt(pairType) ? TyInt32 : TyUint32;
+    }
+    if (opnd->IsIndirOpnd())
+    {
+        IR::IndirOpnd* indir = opnd->AsIndirOpnd();
+        indir->SetType(pairType);
+        pair.low = indir;
+        pair.high = indir->Copy(this)->AsIndirOpnd();
+        pair.high->AsIndirOpnd()->SetOffset(indir->GetOffset() + 4);
+        return pair;
+    }
+
+    // Only indir opnd can have a type other than int64
+    Assert(opnd->IsInt64());
+
+    if (opnd->IsImmediateOpnd())
+    {
+        int64 value = opnd->GetImmediateValue(this);
+        pair.low = IR::IntConstOpnd::New((int32)value, pairType, this);
+        pair.high = IR::IntConstOpnd::New((int32)(value >> 32), pairType, this);
+        return pair;
+    }
+
+    Int64SymPair symPair;
+
+    if (!m_int64SymPairMap)
+    {
+        m_int64SymPairMap = Anew(m_alloc, Int64SymPairMap, m_alloc);
+    }
+    StackSym* stackSym = opnd->GetStackSym();
+    AssertOrFailFastMsg(stackSym, "Invalid int64 operand type");
+
+    SymID symId = stackSym->m_id;
+    if (!m_int64SymPairMap->TryGetValue(symId, &symPair))
+    {
+        if (stackSym->IsArgSlotSym() || stackSym->IsParamSlotSym())
+        {
+            const bool isArg = stackSym->IsArgSlotSym();
+            if (isArg)
+            {
+                Js::ArgSlot slotNumber = stackSym->GetArgSlotNum();
+                symPair.low = StackSym::NewArgSlotSym(slotNumber, this, pairType);
+                symPair.high = StackSym::NewArgSlotSym(slotNumber + 1, this, pairType);
+            }
+            else
+            {
+                Js::ArgSlot slotNumber = stackSym->GetParamSlotNum();
+                symPair.low = StackSym::NewParamSlotSym(slotNumber, this, pairType);
+                symPair.high = StackSym::NewParamSlotSym(slotNumber + 1, this, pairType);
+            }
+            symPair.low->m_allocated = true;
+            symPair.low->m_offset = stackSym->m_offset;
+            symPair.high->m_allocated = true;
+            symPair.high->m_offset = stackSym->m_offset + 4;
+        }
+        else
+        {
+            symPair.low = StackSym::New(pairType, this);
+            symPair.high = StackSym::New(pairType, this);
+        }
+        m_int64SymPairMap->Add(symId, symPair);
+    }
+
+    if (opnd->IsSymOpnd())
+    {
+        pair.low = IR::SymOpnd::New(symPair.low, opnd->AsSymOpnd()->m_offset, pairType, this);
+        pair.high = IR::SymOpnd::New(symPair.high, opnd->AsSymOpnd()->m_offset, pairType, this);
+    }
+    else
+    {
+        pair.low = IR::RegOpnd::New(symPair.low, pairType, this);
+        pair.high = IR::RegOpnd::New(symPair.high, pairType, this);
+    }
+    return pair;
+}
+
+void Func::Int64SplitExtendLoopLifetime(Loop* loop)
+{
+    if (m_int64SymPairMap)
+    {
+        BVSparse<JitArenaAllocator> *liveOnBackEdgeSyms = loop->regAlloc.liveOnBackEdgeSyms;
+        FOREACH_BITSET_IN_SPARSEBV(symId, liveOnBackEdgeSyms)
+        {
+            Int64SymPair pair;
+            if (m_int64SymPairMap->TryGetValue(symId, &pair))
+            {
+                // If we have replaced any sym that was live on the back edge for 2 other syms
+                // these 2 syms needs to be live on back edge as well.
+                liveOnBackEdgeSyms->Set(pair.low->m_id);
+                liveOnBackEdgeSyms->Set(pair.high->m_id);
+            }
+        } NEXT_BITSET_IN_SPARSEBV;
+    }
+}
+#endif
+
 #ifdef _M_ARM
 
 RegNum

+ 17 - 0
lib/Backend/Func.h

@@ -13,6 +13,12 @@ class FlowGraph;
 #include "UnwindInfoManager.h"
 #endif
 
+struct Int64RegPair
+{
+    IR::Opnd* high = nullptr;
+    IR::Opnd* low = nullptr;
+};
+
 struct Cloner
 {
     Cloner(Lowerer *lowerer, JitArenaAllocator *alloc) :
@@ -560,6 +566,11 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;
     byte GetPolyCacheUtil(const uint index) const;
     byte GetPolyCacheUtilToInitialize(const uint index) const;
 
+#if LOWER_SPLIT_INT64
+    Int64RegPair FindOrCreateInt64Pair(IR::Opnd*);
+    void Int64SplitExtendLoopLifetime(Loop* loop);
+#endif
+
 #if defined(_M_ARM32_OR_ARM64)
     RegNum GetLocalsPointer() const;
 #endif
@@ -1018,6 +1029,12 @@ private:
 #if DBG
     VtableHashMap * vtableMap;
 #endif
+#if LOWER_SPLIT_INT64
+    struct Int64SymPair {StackSym* high = nullptr; StackSym* low = nullptr;};
+    // Key is an int64 symId, value is a pair of int32 StackSym
+    typedef JsUtil::BaseDictionary<SymID, Int64SymPair, JitArenaAllocator> Int64SymPairMap;
+    Int64SymPairMap* m_int64SymPairMap;
+#endif
 #ifdef RECYCLER_WRITE_BARRIER_JIT
 public:
     Lowerer* m_lowerer;

+ 0 - 100
lib/Backend/Lower.cpp

@@ -2002,21 +2002,6 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
                 }
                 this->m_func->MarkConstantAddressSyms(instr->AsLabelInstr()->GetLoop()->regAlloc.liveOnBackEdgeSyms);
                 instr->AsLabelInstr()->GetLoop()->regAlloc.liveOnBackEdgeSyms->Or(this->addToLiveOnBackEdgeSyms);
-#ifndef _M_X64
-                if (m_int64RegPairMap)
-                {
-                    // If we have replaced any sym that was live on the back edge for 2 other syms, these 2 syms needs to be live on back edge as well.
-                    BVSparse<JitArenaAllocator> *liveOnBackEdgeSyms = instr->AsLabelInstr()->GetLoop()->regAlloc.liveOnBackEdgeSyms;
-                    m_int64RegPairMap->Map([&](SymID key, Int64SymPair value)
-                    {
-                        if (liveOnBackEdgeSyms->Test(key))
-                        {
-                            liveOnBackEdgeSyms->Set(value.low->m_id);
-                            liveOnBackEdgeSyms->Set(value.high->m_id);
-                        }
-                    });
-                }
-#endif
             }
             break;
 
@@ -9396,91 +9381,6 @@ Lowerer::GenerateFastBrBReturn(IR::Instr * instr)
     // $after
 }
 
-#ifndef _M_X64
-void Lowerer::EnsureInt64RegPairMap()
-{
-    if (!m_int64RegPairMap)
-    {
-        m_int64RegPairMap = Anew(m_alloc, Int64RegPairMap, m_alloc);
-    }
-}
-
-Int64RegPair Lowerer::FindOrCreateInt64Pair(IR::Opnd* reg)
-{
-    Int64RegPair pair;
-    IRType type = reg->GetType();
-    if (IRType_IsInt64(type))
-    {
-        type = IRType_IsSignedInt(type) ? TyInt32 : TyUint32;
-    }
-    if (reg->IsIndirOpnd())
-    {
-        IR::IndirOpnd* indir = reg->AsIndirOpnd();
-        indir->SetType(type);
-        pair.low = indir;
-        pair.high = indir->Copy(m_func)->AsIndirOpnd();
-        pair.high->AsIndirOpnd()->SetOffset(indir->GetOffset() + 4);
-        return pair;
-    }
-
-    // Only indir opnd can have a type other than int64
-    Assert(IRType_IsInt64(reg->GetType()));
-
-    if (reg->IsImmediateOpnd())
-    {
-        int64 value = reg->GetImmediateValue(m_func);
-        pair.low = IR::IntConstOpnd::New((int32)value, type, m_func);
-        pair.high = IR::IntConstOpnd::New((int32)(value >> 32), type, m_func);
-        return pair;
-    }
-
-    EnsureInt64RegPairMap();
-    StackSym* stackSym = reg->GetStackSym();
-    if (!stackSym)
-    {
-        AssertMsg(UNREACHED, "Invalid int64 operand type");
-        Js::Throw::FatalInternalError();
-    }
-
-    SymID symId = stackSym->m_id;
-    Int64SymPair symPair;
-    if (!m_int64RegPairMap->TryGetValue(symId, &symPair))
-    {
-        if (stackSym->IsArgSlotSym() || stackSym->IsParamSlotSym())
-        {
-            const bool isArg = stackSym->IsArgSlotSym();
-            typedef StackSym* (*SymConstr)(Js::ArgSlot, Func *, IRType);
-            SymConstr Constr = isArg ? &StackSym::NewArgSlotSym : (SymConstr)&StackSym::NewParamSlotSym;
-            Js::ArgSlot slotNumber = isArg ? stackSym->GetArgSlotNum() : stackSym->GetParamSlotNum();
-            symPair.low = Constr(slotNumber, this->m_func, type);
-            symPair.low->m_allocated = true;
-            symPair.low->m_offset = stackSym->m_offset;
-            symPair.high = Constr(slotNumber + 1, this->m_func, type);
-            symPair.high->m_allocated = true;
-            symPair.high->m_offset = stackSym->m_offset + 4;
-        }
-        else
-        {
-            symPair.low = StackSym::New(type, this->m_func);
-            symPair.high = StackSym::New(type, this->m_func);
-        }
-        m_int64RegPairMap->Add(symId, symPair);
-    }
-
-    if (reg->IsSymOpnd())
-    {
-        pair.low = IR::SymOpnd::New(symPair.low, reg->AsSymOpnd()->m_offset, type, this->m_func);
-        pair.high = IR::SymOpnd::New(symPair.high, reg->AsSymOpnd()->m_offset, type, this->m_func);
-    }
-    else
-    {
-        pair.low = IR::RegOpnd::New(symPair.low, type, this->m_func);
-        pair.high = IR::RegOpnd::New(symPair.high, type, this->m_func);
-    }
-    return pair;
-}
-#endif
-
 ///----------------------------------------------------------------------------
 ///
 /// Lowerer::LowerBrB - lower 1-operand (boolean) conditional branch

+ 0 - 19
lib/Backend/Lower.h

@@ -19,13 +19,6 @@ enum RoundMode : BYTE {
     RoundModeHalfToEven = 2
 };
 
-struct Int64RegPair
-{
-    IR::Opnd* high;
-    IR::Opnd* low;
-    Int64RegPair(): high(nullptr), low(nullptr) {}
-};
-
 #if defined(_M_IX86) || defined(_M_AMD64)
 #include "LowerMDShared.h"
 #elif defined(_M_ARM) || defined(_M_ARM64)
@@ -53,9 +46,6 @@ class Lowerer
 public:
     Lowerer(Func * func) : m_func(func), m_lowererMD(func), nextStackFunctionOpnd(nullptr), outerMostLoopLabel(nullptr),
         initializedTempSym(nullptr), addToLiveOnBackEdgeSyms(nullptr), currentRegion(nullptr)
-#ifndef _M_X64
-        , m_int64RegPairMap(nullptr)
-#endif
     {
 #ifdef RECYCLER_WRITE_BARRIER_JIT
         m_func->m_lowerer = this;
@@ -339,10 +329,6 @@ private:
     void            GenerateGetSingleCharString(IR::RegOpnd * charCodeOpnd, IR::Opnd * resultOpnd, IR::LabelInstr * labelHelper, IR::LabelInstr * doneLabel, IR::Instr * instr, bool isCodePoint);
     void            GenerateFastBrBReturn(IR::Instr * instr);
 
-#ifndef _M_X64
-    void            EnsureInt64RegPairMap();
-    Int64RegPair    FindOrCreateInt64Pair(IR::Opnd*);
-#endif
 public:
     static IR::LabelInstr *     InsertLabel(const bool isHelper, IR::Instr *const insertBeforeInstr);
 
@@ -708,9 +694,4 @@ private:
     BVSparse<JitArenaAllocator> * initializedTempSym;
     BVSparse<JitArenaAllocator> * addToLiveOnBackEdgeSyms;
     Region *        currentRegion;
-#ifndef _M_X64
-    struct Int64SymPair { StackSym* high; StackSym* low; };
-    typedef BaseDictionary<SymID, Int64SymPair, JitArenaAllocator> Int64RegPairMap;
-    Int64RegPairMap* m_int64RegPairMap;
-#endif
 };

+ 10 - 10
lib/Backend/LowerMDShared.cpp

@@ -838,14 +838,14 @@ LowererMD::LowerRet(IR::Instr * retInstr)
         case Js::AsmJsRetType::Int64:
         {
             regType = TyInt64;
-#ifdef _M_IX86
+#if LOWER_SPLIT_INT64
             regType = TyInt32;
             {
                 IR::Opnd* lowOpnd = nullptr;
                 IR::Opnd* highOpnd = nullptr;
                 if (retInstr->GetSrc1()->IsRegOpnd())
                 {
-                    Int64RegPair srcPair = m_lowerer->FindOrCreateInt64Pair(retInstr->GetSrc1()->AsRegOpnd());
+                    Int64RegPair srcPair = m_func->FindOrCreateInt64Pair(retInstr->GetSrc1()->AsRegOpnd());
                     lowOpnd = srcPair.low;
                     highOpnd = srcPair.high;
                 }
@@ -2789,12 +2789,12 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
 
     Assert(src1->IsRegOpnd());
 
-#ifndef _M_X64
+#if LOWER_SPLIT_INT64
     Int64RegPair src1Pair, src2Pair;
     if (isInt64Src)
     {
-        src1Pair = this->m_lowerer->FindOrCreateInt64Pair(src1);
-        src2Pair = this->m_lowerer->FindOrCreateInt64Pair(src2);
+        src1Pair = this->m_func->FindOrCreateInt64Pair(src1);
+        src2Pair = this->m_func->FindOrCreateInt64Pair(src2);
         src1 = src1Pair.high;
         src2 = src2Pair.high;
     }
@@ -8557,7 +8557,7 @@ LowererMD::EmitReinterpretPrimitive(IR::Opnd* dst, IR::Opnd* src, IR::Instr* ins
     {
 #if _M_AMD64
         LegalizeInsert(IR::Instr::New(Js::OpCode::MOVQ, dst, src, m_func));
-#elif _M_IX86
+#elif LOWER_SPLIT_INT64
         if (dst->IsInt64())
         {
             //    movd xmm2, xmm1
@@ -8565,7 +8565,7 @@ LowererMD::EmitReinterpretPrimitive(IR::Opnd* dst, IR::Opnd* src, IR::Instr* ins
             //    shufps xmm2, xmm2, 1
             //    movd high_bits, xmm2
             Assert(src->IsFloat64());
-            Int64RegPair dstPair = m_lowerer->FindOrCreateInt64Pair(dst);
+            Int64RegPair dstPair = m_func->FindOrCreateInt64Pair(dst);
 
             // shufps modifies the register, we shouldn't change the source here
             IR::RegOpnd* tmpDouble = IR::RegOpnd::New(TyFloat64, m_func);
@@ -8582,7 +8582,7 @@ LowererMD::EmitReinterpretPrimitive(IR::Opnd* dst, IR::Opnd* src, IR::Instr* ins
             //    shufps xmm0, xmm0, (0 | 2 << 2 | 3 << 4 | 3 << 6);
             Assert(src->IsInt64());
             Assert(dst->IsFloat64());
-            Int64RegPair srcPair = m_lowerer->FindOrCreateInt64Pair(src);
+            Int64RegPair srcPair = m_func->FindOrCreateInt64Pair(src);
 
             IR::RegOpnd* tmpDouble = IR::RegOpnd::New(TyFloat64, m_func);
             LegalizeInsert(IR::Instr::New(Js::OpCode::MOVD, dst, srcPair.low, m_func));
@@ -9576,7 +9576,7 @@ LowererMD::NegZeroBranching(IR::Opnd* opnd, IR::Instr* instr, IR::LabelInstr* is
     IR::RegOpnd *intOpnd = IR::RegOpnd::New(regType, this->m_func);
     EmitReinterpretFloatToInt(intOpnd, opnd, instr);
 
-#if _M_IX86
+#if LOWER_SPLIT_INT64
     if (!is32Bits)
     {
         // For 64bits comparisons on x86 we need to check 2 registers
@@ -9585,7 +9585,7 @@ LowererMD::NegZeroBranching(IR::Opnd* opnd, IR::Instr* instr, IR::LabelInstr* is
         // CMP intOpnd.low, k_NegZero.i32
         // BREQ isNeg0Label
         // JMP isNotNeg0Label
-        Int64RegPair dstPair = m_lowerer->FindOrCreateInt64Pair(intOpnd);
+        Int64RegPair dstPair = m_func->FindOrCreateInt64Pair(intOpnd);
         const uint32 high64NegZero = Js::NumberConstants::k_NegZero >> 32;
         const uint32 low64NegZero = Js::NumberConstants::k_NegZero & UINT32_MAX;
         IR::IntConstOpnd *negZeroHighOpnd = IR::IntConstOpnd::New(high64NegZero, TyUint32, m_func);

+ 4 - 0
lib/Backend/SccLiveness.cpp

@@ -219,6 +219,10 @@ SCCLiveness::Build()
                 loop->regAlloc.loopStart = instrNum;
                 loop->regAlloc.loopEnd = lastBranchNum;
 
+#if LOWER_SPLIT_INT64
+                func->Int64SplitExtendLoopLifetime(loop);
+#endif
+
                 // Tail duplication can result in cases in which an outer loop lexically ends before the inner loop.
                 // The register allocator could then thrash in the inner loop registers used for a live-on-back-edge
                 // sym on the outer loop. To prevent this, we need to mark the end of the outer loop as the end of the

+ 1 - 1
lib/Backend/amd64/LowererMDArch.cpp

@@ -2554,7 +2554,7 @@ LowererMDArch::EmitLongToInt(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInser
     Assert(dst->IsRegOpnd() && dst->IsInt32());
     Assert(src->IsInt64());
 
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV_TRUNC, dst, src, this->m_func));
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV_TRUNC, dst, src, instrInsert->m_func));
 }
 
 void

+ 24 - 21
lib/Backend/i386/LowererMDArch.cpp

@@ -762,7 +762,7 @@ LowererMDArch::LowerInt64CallDst(IR::Instr * callInstr)
     RegNum highReturnReg = RegEDX;
     IR::Instr * movInstr;
 
-    Int64RegPair dstPair = lowererMD->m_lowerer->FindOrCreateInt64Pair(callInstr->GetDst());
+    Int64RegPair dstPair = m_func->FindOrCreateInt64Pair(callInstr->GetDst());
     callInstr->GetDst()->SetType(TyInt32);
     movInstr = callInstr->SinkDst(GetAssignOp(TyInt32), lowReturnReg);
     movInstr->UnlinkDst();
@@ -1402,7 +1402,7 @@ LowererMDArch::LoadInt64HelperArgument(IR::Instr * instrInsert, IR::Opnd * opndA
     IR::Instr * instrPrev = IR::Instr::New(Js::OpCode::LEA, espOpnd, opnd, this->m_func);
     instrInsert->InsertBefore(instrPrev);
 
-    Int64RegPair argPair = this->lowererMD->m_lowerer->FindOrCreateInt64Pair(opndArg);
+    Int64RegPair argPair = m_func->FindOrCreateInt64Pair(opndArg);
 
     opnd = IR::IndirOpnd::New(espOpnd, 0, TyInt32, this->m_func);
     IR::Instr * instr = IR::Instr::New(Js::OpCode::MOV, opnd, argPair.low, this->m_func);
@@ -1906,8 +1906,8 @@ LowererMDArch::LowerInt64Assign(IR::Instr * instr)
     {
         int dstSize = dst->GetSize();
         int srcSize = src1->GetSize();
-        Int64RegPair dstPair = lowererMD->m_lowerer->FindOrCreateInt64Pair(dst);
-        Int64RegPair src1Pair = lowererMD->m_lowerer->FindOrCreateInt64Pair(src1);
+        Int64RegPair dstPair = m_func->FindOrCreateInt64Pair(dst);
+        Int64RegPair src1Pair = m_func->FindOrCreateInt64Pair(src1);
         IR::Instr* lowLoadInstr = IR::Instr::New(Js::OpCode::Ld_I4, dstPair.low, src1Pair.low, m_func);
 
         instr->InsertBefore(lowLoadInstr);
@@ -2016,9 +2016,9 @@ LowererMDArch::EmitInt64Instr(IR::Instr *instr)
         highOpCode = Js::OpCode::SBB;
 binopCommon:
     {
-        Int64RegPair dstPair = lowererMD->m_lowerer->FindOrCreateInt64Pair(dst);
-        Int64RegPair src1Pair = lowererMD->m_lowerer->FindOrCreateInt64Pair(src1);
-        Int64RegPair src2Pair = lowererMD->m_lowerer->FindOrCreateInt64Pair(src2);
+        Int64RegPair dstPair = m_func->FindOrCreateInt64Pair(dst);
+        Int64RegPair src1Pair = m_func->FindOrCreateInt64Pair(src1);
+        Int64RegPair src2Pair = m_func->FindOrCreateInt64Pair(src2);
         IR::Instr* lowInstr = IR::Instr::New(lowOpCode, dstPair.low, src1Pair.low, src2Pair.low, m_func);
         instr->InsertBefore(lowInstr);
         LowererMD::Legalize(lowInstr);
@@ -2101,8 +2101,8 @@ void LowererMDArch::LowerInt64Branch(IR::Instr *instr)
     Assert(src1 && src1->IsInt64());
     Assert(src2 && src2->IsInt64());
 
-    Int64RegPair src1Pair = lowererMD->m_lowerer->FindOrCreateInt64Pair(src1);
-    Int64RegPair src2Pair = lowererMD->m_lowerer->FindOrCreateInt64Pair(src2);
+    Int64RegPair src1Pair = m_func->FindOrCreateInt64Pair(src1);
+    Int64RegPair src2Pair = m_func->FindOrCreateInt64Pair(src2);
 
     const auto insertJNE = [&]()
     {
@@ -2564,19 +2564,20 @@ LowererMDArch::EmitIntToLong(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInser
 {
     Assert(dst->IsRegOpnd() && dst->IsInt64());
     Assert(src->IsInt32());
+    Func* func = instrInsert->m_func;
 
-    Int64RegPair dstPair = lowererMD->m_lowerer->FindOrCreateInt64Pair(dst);
+    Int64RegPair dstPair = func->FindOrCreateInt64Pair(dst);
 
-    IR::RegOpnd *regEAX = IR::RegOpnd::New(TyMachPtr, this->m_func);
+    IR::RegOpnd *regEAX = IR::RegOpnd::New(TyMachPtr, func);
     regEAX->SetReg(RegEAX);
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, regEAX, src, this->m_func));
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, regEAX, src, func));
 
-    IR::RegOpnd *regEDX = IR::RegOpnd::New(TyMachPtr, this->m_func);
+    IR::RegOpnd *regEDX = IR::RegOpnd::New(TyMachPtr, func);
     regEDX->SetReg(RegEDX);
 
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::CDQ, regEDX, instrInsert->m_func));
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.low, regEAX, this->m_func));
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.high, regEDX, this->m_func));
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::CDQ, regEDX, func));
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.low, regEAX, func));
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.high, regEDX, func));
 }
 
 void
@@ -2584,10 +2585,11 @@ LowererMDArch::EmitUIntToLong(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInse
 {
     Assert(dst->IsRegOpnd() && dst->IsInt64());
     Assert(src->IsUInt32());
+    Func* func = instrInsert->m_func;
 
-    Int64RegPair dstPair = lowererMD->m_lowerer->FindOrCreateInt64Pair(dst);
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.high, IR::IntConstOpnd::New(0, TyInt32, this->m_func), this->m_func));
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.low, src, this->m_func));
+    Int64RegPair dstPair = func->FindOrCreateInt64Pair(dst);
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.high, IR::IntConstOpnd::New(0, TyInt32, func), func));
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dstPair.low, src, func));
 }
 
 void
@@ -2595,9 +2597,10 @@ LowererMDArch::EmitLongToInt(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInser
 {
     Assert(dst->IsRegOpnd() && dst->IsInt32());
     Assert(src->IsInt64());
+    Func* func = instrInsert->m_func;
 
-    Int64RegPair srcPair = lowererMD->m_lowerer->FindOrCreateInt64Pair(src);
-    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dst, srcPair.low, this->m_func));
+    Int64RegPair srcPair = func->FindOrCreateInt64Pair(src);
+    instrInsert->InsertBefore(IR::Instr::New(Js::OpCode::MOV, dst, srcPair.low, func));
 }
 
 bool

+ 3 - 3
lib/Backend/i386/LowererMDArch.h

@@ -81,9 +81,9 @@ public:
             void                EmitLoadVar(IR::Instr *instrLoad, bool isFromUint32 = false, bool isHelper = false);
             void                EmitIntToFloat(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
             void                EmitUIntToFloat(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
-            void                EmitIntToLong(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
-            void                EmitUIntToLong(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
-            void                EmitLongToInt(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
+            static void         EmitIntToLong(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
+            static void         EmitUIntToLong(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
+            static void         EmitLongToInt(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
             bool                EmitLoadInt32(IR::Instr *instrLoad, bool conversionFromObjectAllowed, bool bailOutOnHelper = false, IR::LabelInstr * labelBailOut = nullptr);
 
             IR::Instr *         LoadCheckedFloat(IR::RegOpnd *opndOrig, IR::RegOpnd *opndFloat, IR::LabelInstr *labelInline, IR::LabelInstr *labelHelper, IR::Instr *instrInsert, const bool checkForNullInLoopBody = false);

+ 7 - 0
lib/Common/CommonDefines.h

@@ -638,6 +638,13 @@
 #endif
 #endif
 
+
+#ifdef _M_IX86
+#define LOWER_SPLIT_INT64 1
+#else
+#define LOWER_SPLIT_INT64 0
+#endif
+
 #if (defined(_M_IX86) || defined(_M_X64)) && !defined(DISABLE_JIT)
 #define ASMJS_PLAT
 #endif

+ 5 - 1
lib/Runtime/Language/InterpreterStackFrame.cpp

@@ -9155,7 +9155,11 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
         Assert(m_functionBody->IsWasmFunction());
         uint index = GetRegRawInt(regIndex);
         Wasm::WasmFunctionInfo* info = m_functionBody->GetAsmJsFunctionInfo()->GetWebAssemblyModule()->GetWasmFunctionInfo(index);
-        Output::SkipToColumn(WAsmJs::Tracing::GetPrintCol());
+        int col = WAsmJs::Tracing::GetPrintCol();
+        if (col > 0)
+        {
+            Output::SkipToColumn(col);
+        }
         info->GetBody()->DumpFullFunctionName();
         Output::Print(_u("("));
 #endif