[llvm] r341718 - [WebAssembly] v8x16.shuffle

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 7 14:54:46 PDT 2018


Author: tlively
Date: Fri Sep  7 14:54:46 2018
New Revision: 341718

URL: http://llvm.org/viewvc/llvm-project?rev=341718&view=rev
Log:
[WebAssembly] v8x16.shuffle

Summary:
Since the shuffle mask is not exposed as an operand in the native ISel
DAG, create a new WebAssembly ISD node exposing the mask. The mask is
lowered as sixteen immediate byte indices no matter what type the
original vector shuffle was operating on.

This CL depends on D51656

Reviewers: aheejin, dschuff

Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D51659

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
    llvm/trunk/test/CodeGen/WebAssembly/simd.ll
    llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def?rev=341718&r1=341717&r2=341718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def Fri Sep  7 14:54:46 2018
@@ -21,5 +21,6 @@ HANDLE_NODETYPE(ARGUMENT)
 HANDLE_NODETYPE(Wrapper)
 HANDLE_NODETYPE(BR_IF)
 HANDLE_NODETYPE(BR_TABLE)
+HANDLE_NODETYPE(SHUFFLE)
 
 // add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=341718&r1=341717&r2=341718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Fri Sep  7 14:54:46 2018
@@ -126,6 +126,17 @@ WebAssemblyTargetLowering::WebAssemblyTa
   // There is no i64x2.mul instruction
   setOperationAction(ISD::MUL, MVT::v2i64, Expand);
 
+  // We have custom shuffle lowering to expose the shuffle mask
+  if (Subtarget->hasSIMD128()) {
+    for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32}) {
+      setOperationAction(ISD::VECTOR_SHUFFLE, T, Custom);
+    }
+    if (EnableUnimplementedWasmSIMDInstrs) {
+      setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Custom);
+      setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2f64, Custom);
+    }
+  }
+
   // As a special case, these operators use the type to mean the type to
   // sign-extend from.
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
@@ -804,6 +815,8 @@ SDValue WebAssemblyTargetLowering::Lower
     return LowerCopyToReg(Op, DAG);
   case ISD::INTRINSIC_WO_CHAIN:
     return LowerINTRINSIC_WO_CHAIN(Op, DAG);
+  case ISD::VECTOR_SHUFFLE:
+    return LowerVECTOR_SHUFFLE(Op, DAG);
   }
 }
 
@@ -953,6 +966,32 @@ WebAssemblyTargetLowering::LowerINTRINSI
   }
 }
 
+SDValue
+WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
+                                               SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op.getNode())->getMask();
+  MVT VecType = Op.getOperand(0).getSimpleValueType();
+  assert(VecType.is128BitVector() && "Unexpected shuffle vector type");
+  size_t LaneBytes = VecType.getVectorElementType().getSizeInBits() / 8;
+
+  // Space for two vector args and sixteen mask indices
+  SDValue Ops[18];
+  size_t OpIdx = 0;
+  Ops[OpIdx++] = Op.getOperand(0);
+  Ops[OpIdx++] = Op.getOperand(1);
+
+  // Expand mask indices to byte indices and materialize them as operands
+  for (size_t I = 0, Lanes = Mask.size(); I < Lanes; ++I) {
+    for (size_t J = 0; J < LaneBytes; ++J) {
+      Ops[OpIdx++] =
+          DAG.getConstant((uint64_t)Mask[I] * LaneBytes + J, DL, MVT::i32);
+    }
+  }
+
+  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, MVT::v16i8, Ops);
+}
+
 //===----------------------------------------------------------------------===//
 //                          WebAssembly Optimization Hooks
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=341718&r1=341717&r2=341718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Fri Sep  7 14:54:46 2018
@@ -98,6 +98,7 @@ private:
   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerCopyToReg(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
 };
 
 namespace WebAssembly {

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td?rev=341718&r1=341717&r2=341718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td Fri Sep  7 14:54:46 2018
@@ -218,6 +218,36 @@ defm "" : Splat<v2i64, "i64x2", I64, spl
 defm "" : Splat<v4f32, "f32x4", F32, splat4, 7>;
 defm "" : Splat<v2f64, "f64x2", F64, splat2, 8>;
 
+defm SHUFFLE_v16i8 :
+  SIMD_I<(outs V128:$dst),
+         (ins V128:$x, V128:$y,
+           vec_i8imm_op:$m0, vec_i8imm_op:$m1,
+           vec_i8imm_op:$m2, vec_i8imm_op:$m3,
+           vec_i8imm_op:$m4, vec_i8imm_op:$m5,
+           vec_i8imm_op:$m6, vec_i8imm_op:$m7,
+           vec_i8imm_op:$m8, vec_i8imm_op:$m9,
+           vec_i8imm_op:$mA, vec_i8imm_op:$mB,
+           vec_i8imm_op:$mC, vec_i8imm_op:$mD,
+           vec_i8imm_op:$mE, vec_i8imm_op:$mF),
+         (outs),
+         (ins
+           vec_i8imm_op:$m0, vec_i8imm_op:$m1,
+           vec_i8imm_op:$m2, vec_i8imm_op:$m3,
+           vec_i8imm_op:$m4, vec_i8imm_op:$m5,
+           vec_i8imm_op:$m6, vec_i8imm_op:$m7,
+           vec_i8imm_op:$m8, vec_i8imm_op:$m9,
+           vec_i8imm_op:$mA, vec_i8imm_op:$mB,
+           vec_i8imm_op:$mC, vec_i8imm_op:$mD,
+           vec_i8imm_op:$mE, vec_i8imm_op:$mF),
+         [],
+         "v8x16.shuffle\t$dst, $x, $y, "#
+           "$m0, $m1, $m2, $m3, $m4, $m5, $m6, $m7, "#
+           "$m8, $m9, $mA, $mB, $mC, $mD, $mE, $mF",
+         "v8x16.shuffle\t"#
+           "$m0, $m1, $m2, $m3, $m4, $m5, $m6, $m7, "#
+           "$m8, $m9, $mA, $mB, $mC, $mD, $mE, $mF",
+         23>;
+
 let isCommutable = 1 in {
 defm ADD : SIMDBinaryInt<add, "add", 24>;
 defm ADD : SIMDBinaryFP<fadd, "add", 122>;
@@ -282,6 +312,30 @@ foreach t2 = !foldl(
 ) in
 def : Pat<(t1 (bitconvert (t2 V128:$v))), (t1 V128:$v)>;
 
+// Shuffles after custom lowering
+def wasm_shuffle_t : SDTypeProfile<1, 18, []>;
+def wasm_shuffle : SDNode<"WebAssemblyISD::SHUFFLE", wasm_shuffle_t>;
+foreach vec_t = [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64] in {
+def : Pat<(v16i8 (wasm_shuffle (vec_t V128:$x), (vec_t V128:$y),
+            (i32 LaneIdx32:$m0), (i32 LaneIdx32:$m1),
+            (i32 LaneIdx32:$m2), (i32 LaneIdx32:$m3),
+            (i32 LaneIdx32:$m4), (i32 LaneIdx32:$m5),
+            (i32 LaneIdx32:$m6), (i32 LaneIdx32:$m7),
+            (i32 LaneIdx32:$m8), (i32 LaneIdx32:$m9),
+            (i32 LaneIdx32:$mA), (i32 LaneIdx32:$mB),
+            (i32 LaneIdx32:$mC), (i32 LaneIdx32:$mD),
+            (i32 LaneIdx32:$mE), (i32 LaneIdx32:$mF))),
+          (v16i8 (SHUFFLE_v16i8 (vec_t V128:$x), (vec_t V128:$y),
+            (i32 LaneIdx32:$m0), (i32 LaneIdx32:$m1),
+            (i32 LaneIdx32:$m2), (i32 LaneIdx32:$m3),
+            (i32 LaneIdx32:$m4), (i32 LaneIdx32:$m5),
+            (i32 LaneIdx32:$m6), (i32 LaneIdx32:$m7),
+            (i32 LaneIdx32:$m8), (i32 LaneIdx32:$m9),
+            (i32 LaneIdx32:$mA), (i32 LaneIdx32:$mB),
+            (i32 LaneIdx32:$mC), (i32 LaneIdx32:$mD),
+            (i32 LaneIdx32:$mE), (i32 LaneIdx32:$mF)))>;
+}
+
 // arbitrary other BUILD_VECTOR patterns
 def : Pat<(v16i8 (build_vector
             (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3),

Modified: llvm/trunk/test/CodeGen/WebAssembly/simd.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/simd.ll?rev=341718&r1=341717&r2=341718&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/simd.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/simd.ll Fri Sep  7 14:54:46 2018
@@ -90,6 +90,23 @@ define <16 x i8> @replace_v16i8(<16 x i8
   ret <16 x i8> %res
 }
 
+; CHECK-LABEL: shuffle_v16i8:
+; NO-SIMD128-NOT: v8x16
+; SIMD128: .param v128, v128{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: v8x16.shuffle $push0=, $0, $1,
+; SIMD128-SAME: 0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31
+; SIMD128-SAME: # encoding: [0xfd,0x17,
+; SIMD128-SAME: 0x00,0x11,0x02,0x13,0x04,0x15,0x06,0x17,
+; SIMD128-SAME: 0x08,0x19,0x0a,0x1b,0x0c,0x1d,0x0e,0x1f]
+; SIMD128: return $pop0 #
+define <16 x i8> @shuffle_v16i8(<16 x i8> %x, <16 x i8> %y) {
+  %res = shufflevector <16 x i8> %x, <16 x i8> %y,
+    <16 x i32> <i32 0, i32 17, i32 2, i32 19, i32 4, i32 21, i32 6, i32 23,
+                i32 8, i32 25, i32 10, i32 27, i32 12, i32 29, i32 14, i32 31>
+  ret <16 x i8> %res
+}
+
 ; CHECK-LABEL: build_v16i8:
 ; NO-SIMD128-NOT: i8x16
 ; SIMD128: .param i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32{{$}}
@@ -214,6 +231,22 @@ define <8 x i16> @replace_v8i16(<8 x i16
   ret <8 x i16> %res
 }
 
+; CHECK-LABEL: shuffle_v8i16:
+; NO-SIMD128-NOT: v8x16
+; SIMD128: .param v128, v128{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: v8x16.shuffle $push0=, $0, $1,
+; SIMD128-SAME: 0, 1, 18, 19, 4, 5, 22, 23, 8, 9, 26, 27, 12, 13, 30, 31
+; SIMD128-SAME: # encoding: [0xfd,0x17,
+; SIMD128-SAME: 0x00,0x01,0x12,0x13,0x04,0x05,0x16,0x17,
+; SIMD128-SAME: 0x08,0x09,0x1a,0x1b,0x0c,0x0d,0x1e,0x1f]
+; SIMD128: return $pop0 #
+define <8 x i16> @shuffle_v8i16(<8 x i16> %x, <8 x i16> %y) {
+  %res = shufflevector <8 x i16> %x, <8 x i16> %y,
+    <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
+  ret <8 x i16> %res
+}
+
 ; CHECK-LABEL: build_v8i16:
 ; NO-SIMD128-NOT: i16x8
 ; SIMD128: .param i32, i32, i32, i32, i32, i32, i32, i32{{$}}
@@ -295,6 +328,22 @@ define <4 x i32> @replace_v4i32(<4 x i32
   ret <4 x i32> %res
 }
 
+; CHECK-LABEL: shuffle_v4i32:
+; NO-SIMD128-NOT: v8x16
+; SIMD128: .param v128, v128{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: v8x16.shuffle $push0=, $0, $1,
+; SIMD128-SAME: 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31
+; SIMD128-SAME: # encoding: [0xfd,0x17,
+; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x14,0x15,0x16,0x17,
+; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x1c,0x1d,0x1e,0x1f]
+; SIMD128: return $pop0 #
+define <4 x i32> @shuffle_v4i32(<4 x i32> %x, <4 x i32> %y) {
+  %res = shufflevector <4 x i32> %x, <4 x i32> %y,
+    <4 x i32> <i32 0, i32 5, i32 2, i32 7>
+  ret <4 x i32> %res
+}
+
 ; CHECK-LABEL: build_v4i32:
 ; NO-SIMD128-NOT: i32x4
 ; SIMD128: .param i32, i32, i32, i32{{$}}
@@ -370,6 +419,21 @@ define <2 x i64> @replace_v2i64(<2 x i64
   ret <2 x i64> %res
 }
 
+; CHECK-LABEL: shuffle_v2i64:
+; NO-SIMD128-NOT: v8x16
+; SIMD128: .param v128, v128{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: v8x16.shuffle $push0=, $0, $1,
+; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31
+; SIMD128-SAME: # encoding: [0xfd,0x17,
+; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+; SIMD128-SAME: 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f]
+; SIMD128: return $pop0 #
+define <2 x i64> @shuffle_v2i64(<2 x i64> %x, <2 x i64> %y) {
+  %res = shufflevector <2 x i64> %x, <2 x i64> %y, <2 x i32> <i32 0, i32 3>
+  ret <2 x i64> %res
+}
+
 ; CHECK-LABEL: build_v2i64:
 ; NO-SIMD128-NOT: i64x2
 ; SIMD128-VM-NOT: i64x2
@@ -441,6 +505,22 @@ define <4 x float> @replace_v4f32(<4 x f
   ret <4 x float> %res
 }
 
+; CHECK-LABEL: shuffle_v4f32:
+; NO-SIMD128-NOT: v8x16
+; SIMD128: .param v128, v128{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: v8x16.shuffle $push0=, $0, $1,
+; SIMD128-SAME: 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31
+; SIMD128-SAME: # encoding: [0xfd,0x17,
+; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x14,0x15,0x16,0x17,
+; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x1c,0x1d,0x1e,0x1f]
+; SIMD128: return $pop0 #
+define <4 x float> @shuffle_v4f32(<4 x float> %x, <4 x float> %y) {
+  %res = shufflevector <4 x float> %x, <4 x float> %y,
+    <4 x i32> <i32 0, i32 5, i32 2, i32 7>
+  ret <4 x float> %res
+}
+
 ; CHECK-LABEL: build_v4f32:
 ; NO-SIMD128-NOT: f32x4
 ; SIMD128: .param f32, f32, f32, f32{{$}}
@@ -515,6 +595,22 @@ define <2 x double> @replace_v2f64(<2 x
   ret <2 x double> %res
 }
 
+; CHECK-LABEL: shuffle_v2f64:
+; NO-SIMD128-NOT: v8x16
+; SIMD128: .param v128, v128{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: v8x16.shuffle $push0=, $0, $1,
+; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31
+; SIMD128-SAME: # encoding: [0xfd,0x17,
+; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+; SIMD128-SAME: 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f]
+; SIMD128: return $pop0 #
+define <2 x double> @shuffle_v2f64(<2 x double> %x, <2 x double> %y) {
+  %res = shufflevector <2 x double> %x, <2 x double> %y,
+    <2 x i32> <i32 0, i32 3>
+  ret <2 x double> %res
+}
+
 ; CHECK-LABEL: build_v2f64:
 ; NO-SIMD128-NOT: f64x2
 ; SIMD128-VM-NOT: f64x2

Modified: llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt?rev=341718&r1=341717&r2=341718&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt Fri Sep  7 14:54:46 2018
@@ -34,3 +34,6 @@
 # v128.const is arbitrarily disassembled as v16i8
 # CHECK: v128.const 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 0xFD 0x00 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
+
+# CHECK: v8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+0xFD 0x17 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F




More information about the llvm-commits mailing list