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}
28*043eaa9aSThomas Lively
29*043eaa9aSThomas Lively; CHECK-LABEL: shl_abs:
30*043eaa9aSThomas Lively; CHECK-NEXT: .functype shl_abs (v128, i32) -> (v128)
31*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push8=, $0, 0
32*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push0=, $1
33*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.abs $push98=, $pop0
34*043eaa9aSThomas Lively; CHECK-NEXT: local.tee $push97=, $2=, $pop98
35*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push6=, $pop97, 0
36*043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push2=, 7
37*043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push7=, $pop6, $pop2
38*043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push9=, $pop8, $pop7
39*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push10=, $pop9
40*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push4=, $0, 1
41*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push1=, $2, 1
42*043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push96=, 7
43*043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push3=, $pop1, $pop96
44*043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push5=, $pop4, $pop3
45*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push11=, $pop10, 1, $pop5
46*043eaa9aSThomas Lively; ...
47*043eaa9aSThomas Lively; CHECK:      i8x16.extract_lane_u $push79=, $0, 15
48*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push77=, $2, 15
49*043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push82=, 7
50*043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push78=, $pop77, $pop82
51*043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push80=, $pop79, $pop78
52*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push81=, $pop76, 15, $pop80
53*043eaa9aSThomas Lively; CHECK-NEXT: return $pop81
54*043eaa9aSThomas Livelydefine <16 x i8> @shl_abs(<16 x i8> %v, i8 %a) {
55*043eaa9aSThomas Lively  %t1 = insertelement <16 x i8> undef, i8 %a, i32 0
56*043eaa9aSThomas Lively  %va = shufflevector <16 x i8> %t1, <16 x i8> undef, <16 x i32> zeroinitializer
57*043eaa9aSThomas Lively  %nva = sub <16 x i8> zeroinitializer, %va
58*043eaa9aSThomas Lively  %c = icmp sgt <16 x i8> %va, zeroinitializer
59*043eaa9aSThomas Lively  %shift = select <16 x i1> %c, <16 x i8> %va, <16 x i8> %nva
60*043eaa9aSThomas Lively  %r = shl <16 x i8> %v, %shift
61*043eaa9aSThomas Lively  ret <16 x i8> %r
62*043eaa9aSThomas Lively}
63*043eaa9aSThomas Lively
64*043eaa9aSThomas Lively; CHECK-LABEL: shl_abs_add:
65*043eaa9aSThomas Lively; CHECK-NEXT: .functype shl_abs_add (v128, i32, i32) -> (v128)
66*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push11=, $0, 0
67*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push1=, $1
68*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push0=, $2
69*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.add $push2=, $pop1, $pop0
70*043eaa9aSThomas Lively; CHECK-NEXT: v8x16.shuffle $push3=, $pop2, $0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
71*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.abs $push101=, $pop3
72*043eaa9aSThomas Lively; CHECK-NEXT: local.tee $push100=, $3=, $pop101
73*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push9=, $pop100, 0
74*043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push5=, 7
75*043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push10=, $pop9, $pop5
76*043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push12=, $pop11, $pop10
77*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.splat $push13=, $pop12
78*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push7=, $0, 1
79*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push4=, $3, 1
80*043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push99=, 7
81*043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push6=, $pop4, $pop99
82*043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push8=, $pop7, $pop6
83*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push14=, $pop13, 1, $pop8
84*043eaa9aSThomas Lively; ...
85*043eaa9aSThomas Lively; CHECK:      i8x16.extract_lane_u $push82=, $0, 15
86*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.extract_lane_u $push80=, $3, 15
87*043eaa9aSThomas Lively; CHECK-NEXT: i32.const $push85=, 7
88*043eaa9aSThomas Lively; CHECK-NEXT: i32.and $push81=, $pop80, $pop85
89*043eaa9aSThomas Lively; CHECK-NEXT: i32.shl $push83=, $pop82, $pop81
90*043eaa9aSThomas Lively; CHECK-NEXT: i8x16.replace_lane $push84=, $pop79, 15, $pop83
91*043eaa9aSThomas Lively; CHECK-NEXT: return $pop84
92*043eaa9aSThomas Livelydefine <16 x i8> @shl_abs_add(<16 x i8> %v, i8 %a, i8 %b) {
93*043eaa9aSThomas Lively  %t1 = insertelement <16 x i8> undef, i8 %a, i32 0
94*043eaa9aSThomas Lively  %va = shufflevector <16 x i8> %t1, <16 x i8> undef, <16 x i32> zeroinitializer
95*043eaa9aSThomas Lively  %t2 = insertelement <16 x i8> undef, i8 %b, i32 0
96*043eaa9aSThomas Lively  %vb = shufflevector <16 x i8> %t2, <16 x i8> undef, <16 x i32> zeroinitializer
97*043eaa9aSThomas Lively  %vadd = add <16 x i8> %va, %vb
98*043eaa9aSThomas Lively  %nvadd = sub <16 x i8> zeroinitializer, %vadd
99*043eaa9aSThomas Lively  %c = icmp sgt <16 x i8> %vadd, zeroinitializer
100*043eaa9aSThomas Lively  %shift = select <16 x i1> %c, <16 x i8> %vadd, <16 x i8> %nvadd
101*043eaa9aSThomas Lively  %r = shl <16 x i8> %v, %shift
102*043eaa9aSThomas Lively  ret <16 x i8> %r
103*043eaa9aSThomas Lively}
104