Bug 1303122: Handle stack in codegen of LCompareAndBranchI on x64; r=luke
authorBenjamin Bouvier <benj@benj.me>
Thu, 15 Sep 2016 21:34:36 +0200
changeset 314402 5841b0c33b7ef92545c920d6da48a1f8cb3543db
parent 314401 97d4dcf688a04822363f166aa415f08f0d937586
child 314403 945544b11e381c00753eb64e6c79196d7609033e
push id20571
push userkwierso@gmail.com
push dateMon, 19 Sep 2016 22:56:59 +0000
treeherderfx-team@671c2af548b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1303122
milestone51.0a1
Bug 1303122: Handle stack in codegen of LCompareAndBranchI on x64; r=luke MozReview-Commit-ID: EV5JUmcNYeh
js/src/jit-test/tests/wasm/regress/teavm-bugs.js
js/src/jit/x64/CodeGenerator-x64.cpp
js/src/jit/x64/CodeGenerator-x64.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/teavm-bugs.js
@@ -0,0 +1,30 @@
+// |jit-test| test-also-wasm-baseline
+load(libdir + "wasm.js");
+
+// Register allocation issue with LCompareI64AndBranch.
+let params = '';
+let locals = '';
+let tests = '';
+
+for (let i = 15; i --> 0;) {
+    params += `\n(param i64)`;
+    locals += `\n(local i64)`;
+    tests = `
+    (if
+        (i64.eq
+            (get_local ${i + 8})
+            (get_local ${i})
+        )
+        (get_local ${i + 8})
+        ${tests}
+    )`;
+}
+
+let code = `(module
+   (func $i64
+     ${params} ${locals}
+     ${tests}
+   )
+)`
+
+evalText(code);
--- a/js/src/jit/x64/CodeGenerator-x64.cpp
+++ b/js/src/jit/x64/CodeGenerator-x64.cpp
@@ -39,16 +39,26 @@ CodeGeneratorX64::ToOutValue(LInstructio
 }
 
 ValueOperand
 CodeGeneratorX64::ToTempValue(LInstruction* ins, size_t pos)
 {
     return ValueOperand(ToRegister(ins->getTemp(pos)));
 }
 
+Operand
+CodeGeneratorX64::ToOperand64(const LInt64Allocation& a64)
+{
+    const LAllocation& a = a64.value();
+    MOZ_ASSERT(!a.isFloatReg());
+    if (a.isGeneralReg())
+        return Operand(a.toGeneralReg()->reg());
+    return Operand(masm.getStackPointer(), ToStackOffset(a));
+}
+
 FrameSizeClass
 FrameSizeClass::FromDepth(uint32_t frameDepth)
 {
     return FrameSizeClass::None();
 }
 
 FrameSizeClass
 FrameSizeClass::ClassLimit()
@@ -241,27 +251,24 @@ CodeGeneratorX64::visitCompareI64(LCompa
 
 void
 CodeGeneratorX64::visitCompareI64AndBranch(LCompareI64AndBranch* lir)
 {
     MCompare* mir = lir->cmpMir();
     MOZ_ASSERT(mir->compareType() == MCompare::Compare_Int64 ||
                mir->compareType() == MCompare::Compare_UInt64);
 
-    const LInt64Allocation lhs = lir->getInt64Operand(LCompareI64::Lhs);
-    const LInt64Allocation rhs = lir->getInt64Operand(LCompareI64::Rhs);
+    LInt64Allocation lhs = lir->getInt64Operand(LCompareI64::Lhs);
+    LInt64Allocation rhs = lir->getInt64Operand(LCompareI64::Rhs);
     Register lhsReg = ToRegister64(lhs).reg;
 
-    if (IsConstant(rhs)) {
-        ImmWord imm = ImmWord(ToInt64(rhs));
-        masm.cmpPtr(lhsReg, imm);
-    } else {
-        Register rhsReg = ToRegister64(rhs).reg;
-        masm.cmpPtr(lhsReg, Operand(rhsReg));
-    }
+    if (IsConstant(rhs))
+        masm.cmpPtr(lhsReg, ImmWord(ToInt64(rhs)));
+    else
+        masm.cmpPtr(lhsReg, ToOperand64(rhs));
 
     bool isSigned = mir->compareType() == MCompare::Compare_Int64;
     emitBranch(JSOpToCondition(lir->jsop(), isSigned), lir->ifTrue(), lir->ifFalse());
 }
 
 void
 CodeGeneratorX64::visitDivOrModI64(LDivOrModI64* lir)
 {
--- a/js/src/jit/x64/CodeGenerator-x64.h
+++ b/js/src/jit/x64/CodeGenerator-x64.h
@@ -14,16 +14,17 @@ namespace jit {
 
 class CodeGeneratorX64 : public CodeGeneratorX86Shared
 {
     CodeGeneratorX64* thisFromCtor() {
         return this;
     }
 
   protected:
+    Operand ToOperand64(const LInt64Allocation& a);
     ValueOperand ToValue(LInstruction* ins, size_t pos);
     ValueOperand ToOutValue(LInstruction* ins);
     ValueOperand ToTempValue(LInstruction* ins, size_t pos);
 
     void storeUnboxedValue(const LAllocation* value, MIRType valueType,
                            Operand dest, MIRType slotType);
     void memoryBarrier(MemoryBarrierBits barrier);