Bug 1250952: Create a join block in case we're in dead code after the condition; r=luke
authorBenjamin Bouvier <benj@benj.me>
Wed, 24 Feb 2016 20:09:29 +0100
changeset 321956 ac848037025ee39218bc95099dcc384ca095b052
parent 321955 583d2cb7c78a5fe912c222aeb693eaf054e3db80
child 321957 883f0723ad50679f61740fa559c830691cb8bdfb
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1250952
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1250952: Create a join block in case we're in dead code after the condition; r=luke MozReview-Commit-ID: IMo3dhE67TQ
js/src/asmjs/WasmIonCompile.cpp
js/src/jit-test/tests/wasm/basic-control-flow.js
--- a/js/src/asmjs/WasmIonCompile.cpp
+++ b/js/src/asmjs/WasmIonCompile.cpp
@@ -871,41 +871,31 @@ class FunctionCompiler
             return false;
 
         curBlock_ = *thenBlock;
         mirGraph().moveBlockToEnd(curBlock_);
         return true;
     }
 
     void assertCurrentBlockIs(MBasicBlock* block) {
-        if (inDeadCode())
-            return;
-        MOZ_ASSERT(curBlock_ == block);
+        MOZ_ASSERT(inDeadCode() || curBlock_ == block);
     }
 
     bool appendThenBlock(BlockVector* thenBlocks)
     {
         if (inDeadCode())
             return true;
         return thenBlocks->append(curBlock_);
     }
 
     bool joinIf(const BlockVector& thenBlocks, MBasicBlock* joinBlock)
     {
-        if (!joinBlock)
-            return true;
         MOZ_ASSERT_IF(curBlock_, thenBlocks.back() == curBlock_);
-        for (size_t i = 0; i < thenBlocks.length(); i++) {
-            thenBlocks[i]->end(MGoto::New(alloc(), joinBlock));
-            if (!joinBlock->addPredecessor(alloc(), thenBlocks[i]))
-                return false;
-        }
         curBlock_ = joinBlock;
-        mirGraph().moveBlockToEnd(curBlock_);
-        return true;
+        return joinIfElse(thenBlocks);
     }
 
     void switchToElse(MBasicBlock* elseBlock)
     {
         if (!elseBlock)
             return;
         curBlock_ = elseBlock;
         mirGraph().moveBlockToEnd(curBlock_);
@@ -2669,17 +2659,17 @@ EmitTableSwitch(FunctionCompiler& f)
     MDefinition* _;
     if (hasDefault && !EmitExprStmt(f, &_))
         return false;
 
     return f.joinSwitch(switchBlock, cases, defaultBlock);
 }
 
 static bool
-EmitRet(FunctionCompiler& f)
+EmitReturn(FunctionCompiler& f)
 {
     ExprType ret = f.sig().ret();
 
     if (IsVoid(ret)) {
         f.returnVoid();
         return true;
     }
 
@@ -2760,17 +2750,17 @@ EmitExpr(FunctionCompiler& f, ExprType t
         return EmitContinue(f, HasLabel(false));
       case Expr::ContinueLabel:
         return EmitContinue(f, HasLabel(true));
       case Expr::Break:
         return EmitBreak(f, HasLabel(false));
       case Expr::BreakLabel:
         return EmitBreak(f, HasLabel(true));
       case Expr::Return:
-        return EmitRet(f);
+        return EmitReturn(f);
       case Expr::Call:
         return EmitCall(f, exprOffset, type, def);
       case Expr::CallIndirect:
         return EmitCallIndirect(f, exprOffset, type, def);
       case Expr::CallImport:
         return EmitCallImport(f, exprOffset, type, def);
       case Expr::AtomicsFence:
         f.memoryBarrier(MembarFull);
--- a/js/src/jit-test/tests/wasm/basic-control-flow.js
+++ b/js/src/jit-test/tests/wasm/basic-control-flow.js
@@ -132,16 +132,17 @@ assertErrorMessage(() => wasmEvalText('(
 assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if_else (i32.const 1) (i32.const 0) (if (i32.const 1) (i32.const 1)))))'), TypeError, mismatchError("void", "i32"));
 wasmEvalText('(module (func (if_else (i32.const 1) (i32.const 0) (if (i32.const 1) (i32.const 1)))))');
 
 // ----------------------------------------------------------------------------
 // return
 
 assertEq(wasmEvalText('(module (func (return)) (export "" 0))')(), undefined);
 assertEq(wasmEvalText('(module (func (result i32) (return (i32.const 1))) (export "" 0))')(), 1);
+assertEq(wasmEvalText('(module (func (if (return) (i32.const 0))) (export "" 0))')(), undefined);
 assertErrorMessage(() => wasmEvalText('(module (func (result f32) (return (i32.const 1))) (export "" 0))'), TypeError, mismatchError("i32", "f32"));
 assertThrowsInstanceOf(() => wasmEvalText('(module (func (result i32) (return)) (export "" 0))'), TypeError);
 assertThrowsInstanceOf(() => wasmEvalText('(module (func (return (i32.const 1))) (export "" 0))'), TypeError);
 
 // TODO: convert these to wasmEval and assert some results once they are implemented
 
 // ----------------------------------------------------------------------------
 // br / br_if