Bug 1136226 - Implement select for 8x16 and 16x8 SIMD types. r=sunfish
authorJakob Stoklund Olesen <jolesen@mozilla.com>
Tue, 31 May 2016 09:00:19 -0700
changeset 338729 5472bbbb12079f4ca2da7fb8048fd0787ef6f200
parent 338728 fa42a25f4124566158f812c0b796360dd239f814
child 338730 018f7422c57ec03d65f58802e4cbb6ee2fc25418
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1136226
milestone49.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 1136226 - Implement select for 8x16 and 16x8 SIMD types. r=sunfish Remove a normalizing shift of the boolean selector. Boolean SIMD types are guaranteed to be represented as all-ones.
js/src/asmjs/AsmJS.cpp
js/src/jit/TypePolicy.cpp
js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
js/src/jit/x86-shared/Lowering-x86-shared.cpp
--- a/js/src/asmjs/AsmJS.cpp
+++ b/js/src/asmjs/AsmJS.cpp
@@ -5000,32 +5000,30 @@ class CheckSimdScalarArgs
 
         return true;
     }
 };
 
 class CheckSimdSelectArgs
 {
     Type formalType_;
+    Type maskType_;
 
   public:
-    explicit CheckSimdSelectArgs(SimdType t) : formalType_(t) {}
+    explicit CheckSimdSelectArgs(SimdType t) : formalType_(t), maskType_(GetBooleanSimdType(t)) {}
 
     bool operator()(FunctionValidator& f, ParseNode* arg, unsigned argIndex, Type actualType) const
     {
-        if (argIndex == 0) {
-            // First argument of select is a bool32x4 mask.
-            if (!(actualType <= Type::Bool32x4))
-                return f.failf(arg, "%s is not a subtype of Bool32x4", actualType.toChars());
-            return true;
-        }
-
-        if (!(actualType <= formalType_)) {
+        // The first argument is the boolean selector, the next two are the
+        // values to choose from.
+        Type wantedType = argIndex == 0 ? maskType_ : formalType_;
+
+        if (!(actualType <= wantedType)) {
             return f.failf(arg, "%s is not a subtype of %s", actualType.toChars(),
-                           formalType_.toChars());
+                           wantedType.toChars());
         }
         return true;
     }
 };
 
 class CheckSimdVectorScalarArgs
 {
     SimdType formalSimdType_;
--- a/js/src/jit/TypePolicy.cpp
+++ b/js/src/jit/TypePolicy.cpp
@@ -858,18 +858,18 @@ SimdShufflePolicy::adjustInputs(TempAllo
     }
 
     return true;
 }
 
 bool
 SimdSelectPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
 {
-    // First input is the mask, which has to be a bool32x4.
-    MOZ_ASSERT(ins->getOperand(0)->type() == MIRType::Bool32x4);
+    // First input is the mask, which has to be a boolean.
+    MOZ_ASSERT(IsBooleanSimdType(ins->getOperand(0)->type()));
 
     // Next inputs are the two vectors of a particular type.
     for (unsigned i = 1; i < 3; i++)
         MOZ_ASSERT(ins->getOperand(i)->type() == ins->typePolicySpecialization());
 
     return true;
 }
 
--- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -3913,29 +3913,27 @@ CodeGeneratorX86Shared::visitSimdSelect(
     FloatRegister temp = ToFloatRegister(ins->temp());
 
     if (onTrue != output)
         masm.vmovaps(onTrue, output);
     if (mask != temp)
         masm.vmovaps(mask, temp);
 
     MSimdSelect* mir = ins->mir();
-
-    if (AssemblerX86Shared::HasAVX()) {
+    unsigned lanes = SimdTypeToLength(mir->type());
+
+    if (AssemblerX86Shared::HasAVX() && lanes == 4) {
+        // TBD: Use vpblendvb for lanes > 4, HasAVX.
         masm.vblendvps(mask, onTrue, onFalse, output);
         return;
     }
 
     // SSE4.1 has plain blendvps which can do this, but it is awkward
     // to use because it requires the mask to be in xmm0.
 
-    // Propagate sign to all bits of mask vector, if necessary.
-    if (!mir->mask()->isSimdBinaryComp())
-        masm.packedRightShiftByScalarInt32x4(Imm32(31), temp);
-
     masm.bitwiseAndSimd128(Operand(temp), output);
     masm.bitwiseAndNotSimd128(Operand(onFalse), temp);
     masm.bitwiseOrSimd128(Operand(temp), output);
 }
 
 void
 CodeGeneratorX86Shared::visitCompareExchangeTypedArrayElement(LCompareExchangeTypedArrayElement* lir)
 {
--- a/js/src/jit/x86-shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/x86-shared/Lowering-x86-shared.cpp
@@ -789,18 +789,16 @@ LIRGeneratorX86Shared::visitSimdBinarySa
     LSimdBinarySaturating* lir = new (alloc()) LSimdBinarySaturating();
     lowerForFPU(lir, ins, lhs, rhs);
 }
 
 void
 LIRGeneratorX86Shared::visitSimdSelect(MSimdSelect* ins)
 {
     MOZ_ASSERT(IsSimdType(ins->type()));
-    MOZ_ASSERT(ins->type() == MIRType::Int32x4 || ins->type() == MIRType::Float32x4,
-               "Unknown SIMD kind when doing bitwise operations");
 
     LSimdSelect* lins = new(alloc()) LSimdSelect;
     MDefinition* r0 = ins->getOperand(0);
     MDefinition* r1 = ins->getOperand(1);
     MDefinition* r2 = ins->getOperand(2);
 
     lins->setOperand(0, useRegister(r0));
     lins->setOperand(1, useRegister(r1));