[llvm] r340472 - [WebAssembly] Arbitrary BUILD_VECTOR and remove i64x2.mul

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 22 16:06:27 PDT 2018


Author: tlively
Date: Wed Aug 22 16:06:27 2018
New Revision: 340472

URL: http://llvm.org/viewvc/llvm-project?rev=340472&view=rev
Log:
[WebAssembly] Arbitrary BUILD_VECTOR and remove i64x2.mul

Summary:
This CL adds support for arbitrary BUILD_VECTORS, i.e. not splats and
not consts. This is the last feature needed to properly lower v2i64
multiplies without a i64x2.mul instruction (which is not in the spec),
so i64x2.mul is removed as well.

Reviewers: aheejin, dschuff

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

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

Remove unnecessary condition and fix whitespace

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
    llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll
    llvm/trunk/test/CodeGen/WebAssembly/simd.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=340472&r1=340471&r2=340472&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Wed Aug 22 16:06:27 2018
@@ -124,6 +124,9 @@ WebAssemblyTargetLowering::WebAssemblyTa
     }
   }
 
+  // There is no i64x2.mul instruction
+  setOperationAction(ISD::MUL, MVT::v2i64, Expand);
+
   // 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);

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=340472&r1=340471&r2=340472&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td Wed Aug 22 16:06:27 2018
@@ -119,7 +119,7 @@ multiclass BinaryFP<SDNode node, string
                 !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
                 !strconcat("f64.", name), f64Inst>;
 }
-multiclass SIMDBinaryInt<SDNode node, string name, bits<32> baseInst> {
+multiclass SIMDBinaryIntNoI64x2<SDNode node, string name, bits<32> baseInst> {
   defm _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
                        (outs), (ins),
                        [(set (v16i8 V128:$dst), (node V128:$lhs, V128:$rhs))],
@@ -138,6 +138,9 @@ multiclass SIMDBinaryInt<SDNode node, st
                        !strconcat("i32x4.",
                          !strconcat(name, "\t$dst, $lhs, $rhs")),
                        !strconcat("i32x4.", name), !add(baseInst, 2)>;
+}
+multiclass SIMDBinaryInt<SDNode node, string name, bits<32> baseInst> {
+  defm "" : SIMDBinaryIntNoI64x2<node, name, baseInst>;
   defm _I64x2 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
                        (outs), (ins),
                        [(set (v2i64 V128:$dst), (node V128:$lhs, V128:$rhs))],

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td?rev=340472&r1=340471&r2=340472&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td Wed Aug 22 16:06:27 2018
@@ -169,13 +169,126 @@ defm "" : Splat<v4f32, "f32x4", F32, spl
 defm "" : Splat<v2f64, "f64x2", F64, splat2, 8>;
 } // Defs = [ARGUMENTS]
 
+// arbitrary other BUILD_VECTOR patterns
+def : Pat<(v16i8 (build_vector
+            (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3),
+            (i32 I32:$x4), (i32 I32:$x5), (i32 I32:$x6), (i32 I32:$x7),
+            (i32 I32:$x8), (i32 I32:$x9), (i32 I32:$x10), (i32 I32:$x11),
+            (i32 I32:$x12), (i32 I32:$x13), (i32 I32:$x14), (i32 I32:$x15)
+          )),
+          (v16i8 (REPLACE_LANE_v16i8
+            (v16i8 (REPLACE_LANE_v16i8
+              (v16i8 (REPLACE_LANE_v16i8
+                (v16i8 (REPLACE_LANE_v16i8
+                  (v16i8 (REPLACE_LANE_v16i8
+                    (v16i8 (REPLACE_LANE_v16i8
+                      (v16i8 (REPLACE_LANE_v16i8
+                        (v16i8 (REPLACE_LANE_v16i8
+                          (v16i8 (REPLACE_LANE_v16i8
+                            (v16i8 (REPLACE_LANE_v16i8
+                              (v16i8 (REPLACE_LANE_v16i8
+                                (v16i8 (REPLACE_LANE_v16i8
+                                  (v16i8 (REPLACE_LANE_v16i8
+                                    (v16i8 (REPLACE_LANE_v16i8
+                                      (v16i8 (REPLACE_LANE_v16i8
+                                        (v16i8 (SPLAT_v16i8 (i32 I32:$x0))),
+                                        1, I32:$x1
+                                      )),
+                                      2, I32:$x2
+                                    )),
+                                    3, I32:$x3
+                                  )),
+                                  4, I32:$x4
+                                )),
+                                5, I32:$x5
+                              )),
+                              6, I32:$x6
+                            )),
+                            7, I32:$x7
+                          )),
+                          8, I32:$x8
+                        )),
+                        9, I32:$x9
+                      )),
+                      10, I32:$x10
+                    )),
+                    11, I32:$x11
+                  )),
+                  12, I32:$x12
+                )),
+                13, I32:$x13
+              )),
+              14, I32:$x14
+            )),
+            15, I32:$x15
+          ))>;
+def : Pat<(v8i16 (build_vector
+            (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3),
+            (i32 I32:$x4), (i32 I32:$x5), (i32 I32:$x6), (i32 I32:$x7)
+          )),
+          (v8i16 (REPLACE_LANE_v8i16
+            (v8i16 (REPLACE_LANE_v8i16
+              (v8i16 (REPLACE_LANE_v8i16
+                (v8i16 (REPLACE_LANE_v8i16
+                  (v8i16 (REPLACE_LANE_v8i16
+                    (v8i16 (REPLACE_LANE_v8i16
+                      (v8i16 (REPLACE_LANE_v8i16
+                        (v8i16 (SPLAT_v8i16 (i32 I32:$x0))),
+                        1, I32:$x1
+                      )),
+                      2, I32:$x2
+                    )),
+                    3, I32:$x3
+                  )),
+                  4, I32:$x4
+                )),
+                5, I32:$x5
+              )),
+              6, I32:$x6
+            )),
+            7, I32:$x7
+          ))>;
+def : Pat<(v4i32 (build_vector
+            (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3)
+          )),
+          (v4i32 (REPLACE_LANE_v4i32
+            (v4i32 (REPLACE_LANE_v4i32
+              (v4i32 (REPLACE_LANE_v4i32
+                (v4i32 (SPLAT_v4i32 (i32 I32:$x0))),
+                1, I32:$x1
+              )),
+              2, I32:$x2
+            )),
+            3, I32:$x3
+          ))>;
+def : Pat<(v2i64 (build_vector (i64 I64:$x0), (i64 I64:$x1))),
+          (v2i64 (REPLACE_LANE_v2i64
+            (v2i64 (SPLAT_v2i64 (i64 I64:$x0))), 1, I64:$x1))>;
+def : Pat<(v4f32 (build_vector
+            (f32 F32:$x0), (f32 F32:$x1), (f32 F32:$x2), (f32 F32:$x3)
+          )),
+          (v4f32 (REPLACE_LANE_v4f32
+            (v4f32 (REPLACE_LANE_v4f32
+              (v4f32 (REPLACE_LANE_v4f32
+                (v4f32 (SPLAT_v4f32 (f32 F32:$x0))),
+                1, F32:$x1
+              )),
+              2, F32:$x2
+            )),
+            3, F32:$x3
+          ))>;
+def : Pat<(v2f64 (build_vector (f64 F64:$x0), (f64 F64:$x1))),
+          (v2f64 (REPLACE_LANE_v2f64
+            (v2f64 (SPLAT_v2f64 (f64 F64:$x0))), 1, F64:$x1))>;
+
 // arithmetic
 let Defs = [ARGUMENTS] in {
 let isCommutable = 1 in
 defm ADD : SIMDBinaryInt<add, "add ", 24>;
 defm SUB : SIMDBinaryInt<sub, "sub ", 28>;
 let isCommutable = 1 in
-defm MUL : SIMDBinaryInt<mul, "mul ", 32>;
+defm MUL : SIMDBinaryIntNoI64x2<mul, "mul ", 32>;
+
 let isCommutable = 1 in
 defm ADD : SIMDBinaryFP<fadd, "add ", 122>;
 defm SUB : SIMDBinaryFP<fsub, "sub ", 124>;

Modified: llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll?rev=340472&r1=340471&r2=340472&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll Wed Aug 22 16:06:27 2018
@@ -145,13 +145,13 @@ define <2 x i64> @sub_v2i64(<2 x i64> %x
   ret <2 x i64> %a
 }
 
+; v2i64.mul is not in spec
 ; CHECK-LABEL: mul_v2i64
 ; NO-SIMD128-NOT: i64x2
 ; SIMD128-VM-NOT: i64x2
-; SIMD128: .param v128, v128{{$}}
-; SIMD128: .result v128{{$}}
-; SIMD128: i64x2.mul $push0=, $0, $1 # encoding: [0xfd,0x23]{{$}}
-; SIMD128: return $pop0 #
+; SIMD128-NOT: i64x2.mul
+; SIMD128: i64x2.extract_lane
+; SIMD128: i64.mul
 define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) {
   %a = mul <2 x i64> %x, %y
   ret <2 x i64> %a

Modified: llvm/trunk/test/CodeGen/WebAssembly/simd.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/simd.ll?rev=340472&r1=340471&r2=340472&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/simd.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/simd.ll Wed Aug 22 16:06:27 2018
@@ -83,6 +83,50 @@ define <16 x i8> @replace_v16i8(<16 x i8
   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{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i8x16.splat $push0=, $0 # encoding: [0xfd,0x03]
+; SIMD128: i8x16.replace_lane $push1=, $pop0, 1, $1 # encoding: [0xfd,0x11,0x01]
+; SIMD128: i8x16.replace_lane $push2=, $pop1, 2, $2 # encoding: [0xfd,0x11,0x02]
+; SIMD128: i8x16.replace_lane $push3=, $pop2, 3, $3 # encoding: [0xfd,0x11,0x03]
+; SIMD128: i8x16.replace_lane $push4=, $pop3, 4, $4 # encoding: [0xfd,0x11,0x04]
+; SIMD128: i8x16.replace_lane $push5=, $pop4, 5, $5 # encoding: [0xfd,0x11,0x05]
+; SIMD128: i8x16.replace_lane $push6=, $pop5, 6, $6 # encoding: [0xfd,0x11,0x06]
+; SIMD128: i8x16.replace_lane $push7=, $pop6, 7, $7 # encoding: [0xfd,0x11,0x07]
+; SIMD128: i8x16.replace_lane $push8=, $pop7, 8, $8 # encoding: [0xfd,0x11,0x08]
+; SIMD128: i8x16.replace_lane $push9=, $pop8, 9, $9 # encoding: [0xfd,0x11,0x09]
+; SIMD128: i8x16.replace_lane $push10=, $pop9, 10, $10 # encoding: [0xfd,0x11,0x0a]
+; SIMD128: i8x16.replace_lane $push11=, $pop10, 11, $11 # encoding: [0xfd,0x11,0x0b]
+; SIMD128: i8x16.replace_lane $push12=, $pop11, 12, $12 # encoding: [0xfd,0x11,0x0c]
+; SIMD128: i8x16.replace_lane $push13=, $pop12, 13, $13 # encoding: [0xfd,0x11,0x0d]
+; SIMD128: i8x16.replace_lane $push14=, $pop13, 14, $14 # encoding: [0xfd,0x11,0x0e]
+; SIMD128: i8x16.replace_lane $push15=, $pop14, 15, $15 # encoding: [0xfd,0x11,0x0f]
+; SIMD128: return $pop15 # encoding: [0x0f]
+define <16 x i8> @build_v16i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3,
+                              i8 %x4, i8 %x5, i8 %x6, i8 %x7,
+                              i8 %x8, i8 %x9, i8 %x10, i8 %x11,
+                              i8 %x12, i8 %x13, i8 %x14, i8 %x15) {
+  %t0 = insertelement <16 x i8> undef, i8 %x0, i32 0
+  %t1 = insertelement <16 x i8> %t0, i8 %x1, i32 1
+  %t2 = insertelement <16 x i8> %t1, i8 %x2, i32 2
+  %t3 = insertelement <16 x i8> %t2, i8 %x3, i32 3
+  %t4 = insertelement <16 x i8> %t3, i8 %x4, i32 4
+  %t5 = insertelement <16 x i8> %t4, i8 %x5, i32 5
+  %t6 = insertelement <16 x i8> %t5, i8 %x6, i32 6
+  %t7 = insertelement <16 x i8> %t6, i8 %x7, i32 7
+  %t8 = insertelement <16 x i8> %t7, i8 %x8, i32 8
+  %t9 = insertelement <16 x i8> %t8, i8 %x9, i32 9
+  %t10 = insertelement <16 x i8> %t9, i8 %x10, i32 10
+  %t11 = insertelement <16 x i8> %t10, i8 %x11, i32 11
+  %t12 = insertelement <16 x i8> %t11, i8 %x12, i32 12
+  %t13 = insertelement <16 x i8> %t12, i8 %x13, i32 13
+  %t14 = insertelement <16 x i8> %t13, i8 %x14, i32 14
+  %res = insertelement <16 x i8> %t14, i8 %x15, i32 15
+  ret <16 x i8> %res
+}
+
 ; ==============================================================================
 ; 8 x i16
 ; ==============================================================================
@@ -157,6 +201,32 @@ define <8 x i16> @replace_v8i16(<8 x i16
   ret <8 x i16> %res
 }
 
+; CHECK-LABEL: build_v8i16:
+; NO-SIMD128-NOT: i16x8
+; SIMD128: .param i32, i32, i32, i32, i32, i32, i32, i32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i16x8.splat $push0=, $0 # encoding: [0xfd,0x04]
+; SIMD128: i16x8.replace_lane $push1=, $pop0, 1, $1 # encoding: [0xfd,0x12,0x01]
+; SIMD128: i16x8.replace_lane $push2=, $pop1, 2, $2 # encoding: [0xfd,0x12,0x02]
+; SIMD128: i16x8.replace_lane $push3=, $pop2, 3, $3 # encoding: [0xfd,0x12,0x03]
+; SIMD128: i16x8.replace_lane $push4=, $pop3, 4, $4 # encoding: [0xfd,0x12,0x04]
+; SIMD128: i16x8.replace_lane $push5=, $pop4, 5, $5 # encoding: [0xfd,0x12,0x05]
+; SIMD128: i16x8.replace_lane $push6=, $pop5, 6, $6 # encoding: [0xfd,0x12,0x06]
+; SIMD128: i16x8.replace_lane $push7=, $pop6, 7, $7 # encoding: [0xfd,0x12,0x07]
+; SIMD128: return $pop7 # encoding: [0x0f]
+define <8 x i16> @build_v8i16(i16 %x0, i16 %x1, i16 %x2, i16 %x3,
+                              i16 %x4, i16 %x5, i16 %x6, i16 %x7) {
+  %t0 = insertelement <8 x i16> undef, i16 %x0, i32 0
+  %t1 = insertelement <8 x i16> %t0, i16 %x1, i32 1
+  %t2 = insertelement <8 x i16> %t1, i16 %x2, i32 2
+  %t3 = insertelement <8 x i16> %t2, i16 %x3, i32 3
+  %t4 = insertelement <8 x i16> %t3, i16 %x4, i32 4
+  %t5 = insertelement <8 x i16> %t4, i16 %x5, i32 5
+  %t6 = insertelement <8 x i16> %t5, i16 %x6, i32 6
+  %res = insertelement <8 x i16> %t6, i16 %x7, i32 7
+  ret <8 x i16> %res
+}
+
 ; ==============================================================================
 ; 4 x i32
 ; ==============================================================================
@@ -206,6 +276,23 @@ define <4 x i32> @replace_v4i32(<4 x i32
   ret <4 x i32> %res
 }
 
+; CHECK-LABEL: build_v4i32:
+; NO-SIMD128-NOT: i32x4
+; SIMD128: .param i32, i32, i32, i32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i32x4.splat $push0=, $0 # encoding: [0xfd,0x05]
+; SIMD128: i32x4.replace_lane $push1=, $pop0, 1, $1 # encoding: [0xfd,0x13,0x01]
+; SIMD128: i32x4.replace_lane $push2=, $pop1, 2, $2 # encoding: [0xfd,0x13,0x02]
+; SIMD128: i32x4.replace_lane $push3=, $pop2, 3, $3 # encoding: [0xfd,0x13,0x03]
+; SIMD128: return $pop3 # encoding: [0x0f]
+define <4 x i32> @build_v4i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
+  %t0 = insertelement <4 x i32> undef, i32 %x0, i32 0
+  %t1 = insertelement <4 x i32> %t0, i32 %x1, i32 1
+  %t2 = insertelement <4 x i32> %t1, i32 %x2, i32 2
+  %res = insertelement <4 x i32> %t2, i32 %x3, i32 3
+  ret <4 x i32> %res
+}
+
 ; ==============================================================================
 ; 2 x i64
 ; ==============================================================================
@@ -258,6 +345,20 @@ define <2 x i64> @replace_v2i64(<2 x i64
   ret <2 x i64> %res
 }
 
+; CHECK-LABEL: build_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-VM-NOT: i64x2
+; SIMD128: .param i64, i64{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i64x2.splat $push0=, $0 # encoding: [0xfd,0x06]
+; SIMD128: i64x2.replace_lane $push1=, $pop0, 1, $1 # encoding: [0xfd,0x14,0x01]
+; SIMD128: return $pop1 # encoding: [0x0f]
+define <2 x i64> @build_v2i64(i64 %x0, i64 %x1) {
+  %t0 = insertelement <2 x i64> undef, i64 %x0, i32 0
+  %res = insertelement <2 x i64> %t0, i64 %x1, i32 1
+  ret <2 x i64> %res
+}
+
 ; ==============================================================================
 ; 4 x f32
 ; ==============================================================================
@@ -309,6 +410,23 @@ define <4 x float> @replace_v4f32(<4 x f
   ret <4 x float> %res
 }
 
+; CHECK-LABEL: build_v4f32:
+; NO-SIMD128-NOT: f32x4
+; SIMD128: .param f32, f32, f32, f32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: f32x4.splat $push0=, $0 # encoding: [0xfd,0x07]
+; SIMD128: f32x4.replace_lane $push1=, $pop0, 1, $1 # encoding: [0xfd,0x15,0x01]
+; SIMD128: f32x4.replace_lane $push2=, $pop1, 2, $2 # encoding: [0xfd,0x15,0x02]
+; SIMD128: f32x4.replace_lane $push3=, $pop2, 3, $3 # encoding: [0xfd,0x15,0x03]
+; SIMD128: return $pop3 # encoding: [0x0f]
+define <4 x float> @build_v4f32(float %x0, float %x1, float %x2, float %x3) {
+  %t0 = insertelement <4 x float> undef, float %x0, i32 0
+  %t1 = insertelement <4 x float> %t0, float %x1, i32 1
+  %t2 = insertelement <4 x float> %t1, float %x2, i32 2
+  %res = insertelement <4 x float> %t2, float %x3, i32 3
+  ret <4 x float> %res
+}
+
 ; ==============================================================================
 ; 2 x f64
 ; ==============================================================================
@@ -359,3 +477,17 @@ define <2 x double> @replace_v2f64(<2 x
   %res = insertelement <2 x double> %v, double %x, i32 0
   ret <2 x double> %res
 }
+
+; CHECK-LABEL: build_v2f64:
+; NO-SIMD128-NOT: f64x2
+; SIMD128-VM-NOT: f64x2
+; SIMD128: .param f64, f64{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: f64x2.splat $push0=, $0 # encoding: [0xfd,0x08]
+; SIMD128: f64x2.replace_lane $push1=, $pop0, 1, $1 # encoding: [0xfd,0x16,0x01]
+; SIMD128: return $pop1 # encoding: [0x0f]
+define <2 x double> @build_v2f64(double %x0, double %x1) {
+  %t0 = insertelement <2 x double> undef, double %x0, i32 0
+  %res = insertelement <2 x double> %t0, double %x1, i32 1
+  ret <2 x double> %res
+}




More information about the llvm-commits mailing list