summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/WebAssembly
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2019-10-09 17:39:19 +0000
committerThomas Lively <tlively@google.com>2019-10-09 17:39:19 +0000
commitd5b7a4e2e8dc63b02129a29745c548613152a522 (patch)
tree20219c8248eb1428ff670be384c4e61a96055b52 /llvm/test/CodeGen/WebAssembly
parent0115c10328281567391855766fef8fbe57a1d4cc (diff)
downloadbcm5719-llvm-d5b7a4e2e8dc63b02129a29745c548613152a522.tar.gz
bcm5719-llvm-d5b7a4e2e8dc63b02129a29745c548613152a522.zip
[WebAssembly] v8x16.swizzle and rewrite BUILD_VECTOR lowering
Summary: Adds the new v8x16.swizzle SIMD instruction as specified at https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#swizzling-using-variable-indices. In addition to adding swizzles as a candidate lowering in LowerBUILD_VECTOR, also rewrites and simplifies the lowering to minimize the number of replace_lanes necessary rather than trying to minimize code size. This leads to more uses of v128.const instead of splats, which is expected to increase performance. The new code will be easier to tune once V8 implements all the vector construction operations, and it will also be easier to add new candidate instructions in the future if necessary. Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68527 llvm-svn: 374188
Diffstat (limited to 'llvm/test/CodeGen/WebAssembly')
-rw-r--r--llvm/test/CodeGen/WebAssembly/simd-build-vector.ll187
1 files changed, 165 insertions, 22 deletions
diff --git a/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll b/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
index 41a320c92f7..469c50ae271 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
@@ -7,13 +7,12 @@
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
-; CHECK-LABEL: same_const_one_replaced_i8x16:
-; CHECK-NEXT: .functype same_const_one_replaced_i8x16 (i32) -> (v128)
-; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 42
-; CHECK-NEXT: i16x8.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
-; CHECK-NEXT: i16x8.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 5, $0
-; CHECK-NEXT: return $pop[[L2]]
-define <8 x i16> @same_const_one_replaced_i8x16(i16 %x) {
+; CHECK-LABEL: same_const_one_replaced_i16x8:
+; CHECK-NEXT: .functype same_const_one_replaced_i16x8 (i32) -> (v128)
+; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 42, 42, 42, 42, 42, 0, 42, 42
+; CHECK-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 5, $0
+; CHECK-NEXT: return $pop[[L1]]
+define <8 x i16> @same_const_one_replaced_i16x8(i16 %x) {
%v = insertelement
<8 x i16> <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>,
i16 %x,
@@ -21,12 +20,12 @@ define <8 x i16> @same_const_one_replaced_i8x16(i16 %x) {
ret <8 x i16> %v
}
-; CHECK-LABEL: different_const_one_replaced_i8x16:
-; CHECK-NEXT: .functype different_const_one_replaced_i8x16 (i32) -> (v128)
+; CHECK-LABEL: different_const_one_replaced_i16x8:
+; CHECK-NEXT: .functype different_const_one_replaced_i16x8 (i32) -> (v128)
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 1, -2, 3, -4, 5, 0, 7, -8
; CHECK-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 5, $0
; CHECK-NEXT: return $pop[[L1]]
-define <8 x i16> @different_const_one_replaced_i8x16(i16 %x) {
+define <8 x i16> @different_const_one_replaced_i16x8(i16 %x) {
%v = insertelement
<8 x i16> <i16 1, i16 -2, i16 3, i16 -4, i16 5, i16 -6, i16 7, i16 -8>,
i16 %x,
@@ -36,10 +35,9 @@ define <8 x i16> @different_const_one_replaced_i8x16(i16 %x) {
; CHECK-LABEL: same_const_one_replaced_f32x4:
; CHECK-NEXT: .functype same_const_one_replaced_f32x4 (f32) -> (v128)
-; CHECK-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.5p5
-; CHECK-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
-; CHECK-NEXT: f32x4.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $0
-; CHECK-NEXT: return $pop[[L2]]
+; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x1.5p5, 0x1.5p5, 0x0p0, 0x1.5p5
+; CHECK-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 2, $0
+; CHECK-NEXT: return $pop[[L1]]
define <4 x float> @same_const_one_replaced_f32x4(float %x) {
%v = insertelement
<4 x float> <float 42., float 42., float 42., float 42.>,
@@ -63,11 +61,8 @@ define <4 x float> @different_const_one_replaced_f32x4(float %x) {
; CHECK-LABEL: splat_common_const_i32x4:
; CHECK-NEXT: .functype splat_common_const_i32x4 () -> (v128)
-; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 3
-; CHECK-NEXT: i32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
-; CHECK-NEXT: i32.const $push[[L2:[0-9]+]]=, 1
-; CHECK-NEXT: i32x4.replace_lane $push[[L3:[0-9]+]]=, $pop[[L1]], 3, $pop[[L2]]
-; CHECK-NEXT: return $pop[[L3]]
+; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0, 3, 3, 1
+; CHECK-NEXT: return $pop[[L0]]
define <4 x i32> @splat_common_const_i32x4() {
ret <4 x i32> <i32 undef, i32 3, i32 3, i32 1>
}
@@ -92,11 +87,159 @@ define <8 x i16> @splat_common_arg_i16x8(i16 %a, i16 %b, i16 %c) {
ret <8 x i16> %v7
}
+; CHECK-LABEL: swizzle_one_i8x16:
+; CHECK-NEXT: .functype swizzle_one_i8x16 (v128, v128) -> (v128)
+; CHECK-NEXT: v8x16.swizzle $push[[L0:[0-9]+]]=, $0, $1
+; CHECK-NEXT: return $pop[[L0]]
+define <16 x i8> @swizzle_one_i8x16(<16 x i8> %src, <16 x i8> %mask) {
+ %m0 = extractelement <16 x i8> %mask, i32 0
+ %s0 = extractelement <16 x i8> %src, i8 %m0
+ %v0 = insertelement <16 x i8> undef, i8 %s0, i32 0
+ ret <16 x i8> %v0
+}
+
+; CHECK-LABEL: swizzle_all_i8x16:
+; CHECK-NEXT: .functype swizzle_all_i8x16 (v128, v128) -> (v128)
+; CHECK-NEXT: v8x16.swizzle $push[[L0:[0-9]+]]=, $0, $1
+; CHECK-NEXT: return $pop[[L0]]
+define <16 x i8> @swizzle_all_i8x16(<16 x i8> %src, <16 x i8> %mask) {
+ %m0 = extractelement <16 x i8> %mask, i32 0
+ %s0 = extractelement <16 x i8> %src, i8 %m0
+ %v0 = insertelement <16 x i8> undef, i8 %s0, i32 0
+ %m1 = extractelement <16 x i8> %mask, i32 1
+ %s1 = extractelement <16 x i8> %src, i8 %m1
+ %v1 = insertelement <16 x i8> %v0, i8 %s1, i32 1
+ %m2 = extractelement <16 x i8> %mask, i32 2
+ %s2 = extractelement <16 x i8> %src, i8 %m2
+ %v2 = insertelement <16 x i8> %v1, i8 %s2, i32 2
+ %m3 = extractelement <16 x i8> %mask, i32 3
+ %s3 = extractelement <16 x i8> %src, i8 %m3
+ %v3 = insertelement <16 x i8> %v2, i8 %s3, i32 3
+ %m4 = extractelement <16 x i8> %mask, i32 4
+ %s4 = extractelement <16 x i8> %src, i8 %m4
+ %v4 = insertelement <16 x i8> %v3, i8 %s4, i32 4
+ %m5 = extractelement <16 x i8> %mask, i32 5
+ %s5 = extractelement <16 x i8> %src, i8 %m5
+ %v5 = insertelement <16 x i8> %v4, i8 %s5, i32 5
+ %m6 = extractelement <16 x i8> %mask, i32 6
+ %s6 = extractelement <16 x i8> %src, i8 %m6
+ %v6 = insertelement <16 x i8> %v5, i8 %s6, i32 6
+ %m7 = extractelement <16 x i8> %mask, i32 7
+ %s7 = extractelement <16 x i8> %src, i8 %m7
+ %v7 = insertelement <16 x i8> %v6, i8 %s7, i32 7
+ %m8 = extractelement <16 x i8> %mask, i32 8
+ %s8 = extractelement <16 x i8> %src, i8 %m8
+ %v8 = insertelement <16 x i8> %v7, i8 %s8, i32 8
+ %m9 = extractelement <16 x i8> %mask, i32 9
+ %s9 = extractelement <16 x i8> %src, i8 %m9
+ %v9 = insertelement <16 x i8> %v8, i8 %s9, i32 9
+ %m10 = extractelement <16 x i8> %mask, i32 10
+ %s10 = extractelement <16 x i8> %src, i8 %m10
+ %v10 = insertelement <16 x i8> %v9, i8 %s10, i32 10
+ %m11 = extractelement <16 x i8> %mask, i32 11
+ %s11 = extractelement <16 x i8> %src, i8 %m11
+ %v11 = insertelement <16 x i8> %v10, i8 %s11, i32 11
+ %m12 = extractelement <16 x i8> %mask, i32 12
+ %s12 = extractelement <16 x i8> %src, i8 %m12
+ %v12 = insertelement <16 x i8> %v11, i8 %s12, i32 12
+ %m13 = extractelement <16 x i8> %mask, i32 13
+ %s13 = extractelement <16 x i8> %src, i8 %m13
+ %v13 = insertelement <16 x i8> %v12, i8 %s13, i32 13
+ %m14 = extractelement <16 x i8> %mask, i32 14
+ %s14 = extractelement <16 x i8> %src, i8 %m14
+ %v14 = insertelement <16 x i8> %v13, i8 %s14, i32 14
+ %m15 = extractelement <16 x i8> %mask, i32 15
+ %s15 = extractelement <16 x i8> %src, i8 %m15
+ %v15 = insertelement <16 x i8> %v14, i8 %s15, i32 15
+ ret <16 x i8> %v15
+}
+
+; CHECK-LABEL: swizzle_one_i16x8:
+; CHECK-NEXT: .functype swizzle_one_i16x8 (v128, v128) -> (v128)
+; CHECK-NOT: swizzle
+; CHECK: return
+define <8 x i16> @swizzle_one_i16x8(<8 x i16> %src, <8 x i16> %mask) {
+ %m0 = extractelement <8 x i16> %mask, i32 0
+ %s0 = extractelement <8 x i16> %src, i16 %m0
+ %v0 = insertelement <8 x i16> undef, i16 %s0, i32 0
+ ret <8 x i16> %v0
+}
+
+; CHECK-LABEL: mashup_swizzle_i8x16:
+; CHECK-NEXT: .functype mashup_swizzle_i8x16 (v128, v128, i32) -> (v128)
+; CHECK-NEXT: v8x16.swizzle $push[[L0:[0-9]+]]=, $0, $1
+; CHECK: i8x16.replace_lane
+; CHECK: i8x16.replace_lane
+; CHECK: i8x16.replace_lane
+; CHECK: i8x16.replace_lane
+; CHECK: return
+define <16 x i8> @mashup_swizzle_i8x16(<16 x i8> %src, <16 x i8> %mask, i8 %splatted) {
+ ; swizzle 0
+ %m0 = extractelement <16 x i8> %mask, i32 0
+ %s0 = extractelement <16 x i8> %src, i8 %m0
+ %v0 = insertelement <16 x i8> undef, i8 %s0, i32 0
+ ; swizzle 7
+ %m1 = extractelement <16 x i8> %mask, i32 7
+ %s1 = extractelement <16 x i8> %src, i8 %m1
+ %v1 = insertelement <16 x i8> %v0, i8 %s1, i32 7
+ ; splat 3
+ %v2 = insertelement <16 x i8> %v1, i8 %splatted, i32 3
+ ; splat 12
+ %v3 = insertelement <16 x i8> %v2, i8 %splatted, i32 12
+ ; const 4
+ %v4 = insertelement <16 x i8> %v3, i8 42, i32 4
+ ; const 14
+ %v5 = insertelement <16 x i8> %v4, i8 42, i32 14
+ ret <16 x i8> %v5
+}
+
+; CHECK-LABEL: mashup_const_i8x16:
+; CHECK-NEXT: .functype mashup_const_i8x16 (v128, v128, i32) -> (v128)
+; CHECK: v128.const $push[[L0:[0-9]+]]=, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0
+; CHECK: i8x16.replace_lane
+; CHECK: i8x16.replace_lane
+; CHECK: i8x16.replace_lane
+; CHECK: return
+define <16 x i8> @mashup_const_i8x16(<16 x i8> %src, <16 x i8> %mask, i8 %splatted) {
+ ; swizzle 0
+ %m0 = extractelement <16 x i8> %mask, i32 0
+ %s0 = extractelement <16 x i8> %src, i8 %m0
+ %v0 = insertelement <16 x i8> undef, i8 %s0, i32 0
+ ; splat 3
+ %v1 = insertelement <16 x i8> %v0, i8 %splatted, i32 3
+ ; splat 12
+ %v2 = insertelement <16 x i8> %v1, i8 %splatted, i32 12
+ ; const 4
+ %v3 = insertelement <16 x i8> %v2, i8 42, i32 4
+ ; const 14
+ %v4 = insertelement <16 x i8> %v3, i8 42, i32 14
+ ret <16 x i8> %v4
+}
+
+; CHECK-LABEL: mashup_splat_i8x16:
+; CHECK-NEXT: .functype mashup_splat_i8x16 (v128, v128, i32) -> (v128)
+; CHECK: i8x16.splat $push[[L0:[0-9]+]]=, $2
+; CHECK: i8x16.replace_lane
+; CHECK: i8x16.replace_lane
+; CHECK: return
+define <16 x i8> @mashup_splat_i8x16(<16 x i8> %src, <16 x i8> %mask, i8 %splatted) {
+ ; swizzle 0
+ %m0 = extractelement <16 x i8> %mask, i32 0
+ %s0 = extractelement <16 x i8> %src, i8 %m0
+ %v0 = insertelement <16 x i8> undef, i8 %s0, i32 0
+ ; splat 3
+ %v1 = insertelement <16 x i8> %v0, i8 %splatted, i32 3
+ ; splat 12
+ %v2 = insertelement <16 x i8> %v1, i8 %splatted, i32 12
+ ; const 4
+ %v3 = insertelement <16 x i8> %v2, i8 42, i32 4
+ ret <16 x i8> %v3
+}
+
; CHECK-LABEL: undef_const_insert_f32x4:
; CHECK-NEXT: .functype undef_const_insert_f32x4 () -> (v128)
-; CHECK-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.5p5
-; CHECK-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
-; CHECK-NEXT: return $pop[[L1]]
+; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x0p0, 0x1.5p5, 0x0p0, 0x0p0
+; CHECK-NEXT: return $pop[[L0]]
define <4 x float> @undef_const_insert_f32x4() {
%v = insertelement <4 x float> undef, float 42., i32 1
ret <4 x float> %v
OpenPOWER on IntegriCloud