Bug 1259903: Baldr: unify Select true and false types instead of checking against each other; r=luke
authorBenjamin Bouvier <benj@benj.me>
Wed, 30 Mar 2016 09:41:07 +0200
changeset 291059 2d7bdc3491d54fd7318c5314823d4c6f73ee0717
parent 291058 6c7e6cf636afde50f2dc72099c75e8b5125b97d3
child 291060 15a3458b4d114f6494370c5eae2583e77e6c73f5
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1259903
milestone48.0a1
Bug 1259903: Baldr: unify Select true and false types instead of checking against each other; r=luke MozReview-Commit-ID: 2GHFuLNTuP3
js/src/asmjs/Wasm.cpp
js/src/asmjs/WasmIonCompile.cpp
js/src/jit-test/tests/wasm/basic.js
--- a/js/src/asmjs/Wasm.cpp
+++ b/js/src/asmjs/Wasm.cpp
@@ -445,40 +445,37 @@ DecodeConversionOperator(FunctionDecoder
     if (!CheckType(f, actual, argType))
         return false;
 
     *type = ToExprType(to);
     return true;
 }
 
 static bool
-DecodeSelectOperator(FunctionDecoder& f, ExprType* type)
+DecodeSelect(FunctionDecoder& f, ExprType* type)
 {
     ExprType trueType;
     if (!DecodeExpr(f, &trueType))
         return false;
 
     if (trueType == ExprType::I64 && !f.checkI64Support())
         return false;
 
     ExprType falseType;
     if (!DecodeExpr(f, &falseType))
         return false;
 
-    if (!CheckType(f, falseType, trueType))
-        return false;
-
     ExprType condType;
     if (!DecodeExpr(f, &condType))
         return false;
 
     if (!CheckType(f, condType, ValType::I32))
         return false;
 
-    *type = trueType;
+    *type = Unify(trueType, falseType);
     return true;
 }
 
 static bool
 DecodeIfElse(FunctionDecoder& f, bool hasElse, ExprType* type)
 {
     ExprType condType;
     if (!DecodeExpr(f, &condType))
@@ -667,17 +664,17 @@ DecodeExpr(FunctionDecoder& f, ExprType*
         return DecodeConstF32(f, type);
       case Expr::F64Const:
         return DecodeConstF64(f, type);
       case Expr::GetLocal:
         return DecodeGetLocal(f, type);
       case Expr::SetLocal:
         return DecodeSetLocal(f, type);
       case Expr::Select:
-        return DecodeSelectOperator(f, type);
+        return DecodeSelect(f, type);
       case Expr::Block:
         return DecodeBlock(f, /* isLoop */ false, type);
       case Expr::Loop:
         return DecodeBlock(f, /* isLoop */ true, type);
       case Expr::If:
         return DecodeIfElse(f, /* hasElse */ false, type);
       case Expr::IfElse:
         return DecodeIfElse(f, /* hasElse */ true, type);
--- a/js/src/asmjs/WasmIonCompile.cpp
+++ b/js/src/asmjs/WasmIonCompile.cpp
@@ -2182,17 +2182,25 @@ EmitSelect(FunctionCompiler& f, MDefinit
     MDefinition* falseExpr;
     if (!EmitExpr(f, &falseExpr))
         return false;
 
     MDefinition* condExpr;
     if (!EmitExpr(f, &condExpr))
         return false;
 
-    *def = f.select(trueExpr, falseExpr, condExpr);
+    if (trueExpr && falseExpr &&
+        trueExpr->type() == falseExpr->type() &&
+        trueExpr->type() != MIRType_None)
+    {
+        *def = f.select(trueExpr, falseExpr, condExpr);
+    } else {
+        *def = nullptr;
+    }
+
     return true;
 }
 
 typedef bool IsAdd;
 
 static bool
 EmitAddOrSub(FunctionCompiler& f, ValType type, bool isAdd, MDefinition** def)
 {
--- a/js/src/jit-test/tests/wasm/basic.js
+++ b/js/src/jit-test/tests/wasm/basic.js
@@ -436,19 +436,25 @@ var {v2i, i2i, i2v} = wasmEvalText(`(mod
 wasmEvalText('(module (func $foo (nop)) (func (call $foo)))');
 wasmEvalText('(module (func (call $foo)) (func $foo (nop)))');
 wasmEvalText('(module (import $bar "a" "") (func (call_import $bar)) (func $foo (nop)))', {a:()=>{}});
 
 
 // ----------------------------------------------------------------------------
 // select
 
-assertErrorMessage(() => wasmEvalText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))))'), TypeError, mismatchError("f32", "i32"));
 assertErrorMessage(() => wasmEvalText('(module (func (select (i32.const 0) (i32.const 0) (f32.const 0))))'), TypeError, mismatchError("f32", "i32"));
 
+assertEq(wasmEvalText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" 0))')(), undefined);
+assertEq(wasmEvalText('(module (func (select (block) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined);
+assertEq(wasmEvalText('(module (func (select (return) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined);
+assertEq(wasmEvalText('(module (func (i32.add (i32.const 0) (select (return) (i32.const 0) (i32.const 0)))) (export "" 0))')(), undefined);
+assertEq(wasmEvalText('(module (func (select (if (i32.const 1) (i32.const 0) (f32.const 0)) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined);
+assertEq(wasmEvalText('(module (func) (func (select (call 0) (call 0) (i32.const 0))) (export "" 0))')(), undefined);
+
 (function testSideEffects() {
 
 var numT = 0;
 var numF = 0;
 
 var imports = {
     ifTrue: () => 1 + numT++,
     ifFalse: () => -1 + numF++,