10d7286a6SThomas Lively; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s
20d7286a6SThomas Lively
30d7286a6SThomas Lively; Test that SIMD shifts can be lowered correctly even with shift
40d7286a6SThomas Lively; values that are more complex than plain splats.
50d7286a6SThomas Lively
60d7286a6SThomas Livelytarget datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
70d7286a6SThomas Livelytarget triple = "wasm32-unknown-unknown"
80d7286a6SThomas Lively
90d7286a6SThomas Lively;; TODO: Optimize this further by scalarizing the add
100d7286a6SThomas Lively
110d7286a6SThomas Lively; CHECK-LABEL: shl_add:
120d7286a6SThomas Lively; CHECK-NEXT: .functype shl_add (v128, i32, i32) -> (v128)
130d7286a6SThomas Lively; CHECK-NEXT: i8x16.splat $push1=, $1
140d7286a6SThomas Lively; CHECK-NEXT: i8x16.splat $push0=, $2
150d7286a6SThomas Lively; CHECK-NEXT: i8x16.add $push2=, $pop1, $pop0
160d7286a6SThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push3=, $pop2, 0
170d7286a6SThomas Lively; CHECK-NEXT: i8x16.shl $push4=, $0, $pop3
180d7286a6SThomas Lively; CHECK-NEXT: return $pop4
190d7286a6SThomas Livelydefine <16 x i8> @shl_add(<16 x i8> %v, i8 %a, i8 %b) {
200d7286a6SThomas Lively  %t1 = insertelement <16 x i8> undef, i8 %a, i32 0
210d7286a6SThomas Lively  %va = shufflevector <16 x i8> %t1, <16 x i8> undef, <16 x i32> zeroinitializer
220d7286a6SThomas Lively  %t2 = insertelement <16 x i8> undef, i8 %b, i32 0
230d7286a6SThomas Lively  %vb = shufflevector <16 x i8> %t2, <16 x i8> undef, <16 x i32> zeroinitializer
240d7286a6SThomas Lively  %shift = add <16 x i8> %va, %vb
250d7286a6SThomas Lively  %r = shl <16 x i8> %v, %shift
260d7286a6SThomas Lively  ret <16 x i8> %r
270d7286a6SThomas Lively}
28043eaa9aSThomas Lively
29043eaa9aSThomas Lively; CHECK-LABEL: shl_abs:
30043eaa9aSThomas Lively; CHECK-NEXT: .functype shl_abs (v128, i32) -> (v128)
31043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push8=, $0, 0
32043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push0=, $1
33043eaa9aSThomas Lively; CHECK-NEXT: i8x16.abs $push98=, $pop0
34043eaa9aSThomas Lively; CHECK-NEXT: local.tee $push97=, $2=, $pop98
35043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push6=, $pop97, 0
36043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push2=, 7
37043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push7=, $pop6, $pop2
38043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push9=, $pop8, $pop7
39043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push10=, $pop9
40043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push4=, $0, 1
41043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push1=, $2, 1
42043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push96=, 7
43043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push3=, $pop1, $pop96
44043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push5=, $pop4, $pop3
45043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push11=, $pop10, 1, $pop5
46043eaa9aSThomas Lively; ...
47043eaa9aSThomas Lively; CHECK:      i8x16.extract_lane_u $push79=, $0, 15
48043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push77=, $2, 15
49043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push82=, 7
50043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push78=, $pop77, $pop82
51043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push80=, $pop79, $pop78
52043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push81=, $pop76, 15, $pop80
53043eaa9aSThomas Lively; CHECK-NEXT: return $pop81
54043eaa9aSThomas Livelydefine <16 x i8> @shl_abs(<16 x i8> %v, i8 %a) {
55043eaa9aSThomas Lively  %t1 = insertelement <16 x i8> undef, i8 %a, i32 0
56043eaa9aSThomas Lively  %va = shufflevector <16 x i8> %t1, <16 x i8> undef, <16 x i32> zeroinitializer
57043eaa9aSThomas Lively  %nva = sub <16 x i8> zeroinitializer, %va
58043eaa9aSThomas Lively  %c = icmp sgt <16 x i8> %va, zeroinitializer
59043eaa9aSThomas Lively  %shift = select <16 x i1> %c, <16 x i8> %va, <16 x i8> %nva
60043eaa9aSThomas Lively  %r = shl <16 x i8> %v, %shift
61043eaa9aSThomas Lively  ret <16 x i8> %r
62043eaa9aSThomas Lively}
63043eaa9aSThomas Lively
64043eaa9aSThomas Lively; CHECK-LABEL: shl_abs_add:
65043eaa9aSThomas Lively; CHECK-NEXT: .functype shl_abs_add (v128, i32, i32) -> (v128)
66043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push11=, $0, 0
67043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push1=, $1
68043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push0=, $2
69043eaa9aSThomas Lively; CHECK-NEXT: i8x16.add $push2=, $pop1, $pop0
70*a781a706SThomas Lively; CHECK-NEXT: i8x16.shuffle $push3=, $pop2, $0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
71043eaa9aSThomas Lively; CHECK-NEXT: i8x16.abs $push101=, $pop3
72043eaa9aSThomas Lively; CHECK-NEXT: local.tee $push100=, $3=, $pop101
73043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push9=, $pop100, 0
74043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push5=, 7
75043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push10=, $pop9, $pop5
76043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push12=, $pop11, $pop10
77043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push13=, $pop12
78043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push7=, $0, 1
79043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push4=, $3, 1
80043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push99=, 7
81043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push6=, $pop4, $pop99
82043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push8=, $pop7, $pop6
83043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push14=, $pop13, 1, $pop8
84043eaa9aSThomas Lively; ...
85043eaa9aSThomas Lively; CHECK:      i8x16.extract_lane_u $push82=, $0, 15
86043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push80=, $3, 15
87043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push85=, 7
88043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push81=, $pop80, $pop85
89043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push83=, $pop82, $pop81
90043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push84=, $pop79, 15, $pop83
91043eaa9aSThomas Lively; CHECK-NEXT: return $pop84
92043eaa9aSThomas Livelydefine <16 x i8> @shl_abs_add(<16 x i8> %v, i8 %a, i8 %b) {
93043eaa9aSThomas Lively  %t1 = insertelement <16 x i8> undef, i8 %a, i32 0
94043eaa9aSThomas Lively  %va = shufflevector <16 x i8> %t1, <16 x i8> undef, <16 x i32> zeroinitializer
95043eaa9aSThomas Lively  %t2 = insertelement <16 x i8> undef, i8 %b, i32 0
96043eaa9aSThomas Lively  %vb = shufflevector <16 x i8> %t2, <16 x i8> undef, <16 x i32> zeroinitializer
97043eaa9aSThomas Lively  %vadd = add <16 x i8> %va, %vb
98043eaa9aSThomas Lively  %nvadd = sub <16 x i8> zeroinitializer, %vadd
99043eaa9aSThomas Lively  %c = icmp sgt <16 x i8> %vadd, zeroinitializer
100043eaa9aSThomas Lively  %shift = select <16 x i1> %c, <16 x i8> %vadd, <16 x i8> %nvadd
101043eaa9aSThomas Lively  %r = shl <16 x i8> %v, %shift
102043eaa9aSThomas Lively  ret <16 x i8> %r
103043eaa9aSThomas Lively}
104