1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix-xcoff -vec-extabi -mcpu=pwr9 < %s | FileCheck %s -check-prefix=CHECK-64
3; RUN: llc -verify-machineinstrs -mtriple=powerpc-ibm-aix-xcoff -vec-extabi -mcpu=pwr9 < %s | FileCheck %s -check-prefix=CHECK-32
4
5define zeroext i8 @test_add1(<16 x i8> %a, i32 signext %index, i8 zeroext %c) {
6; CHECK-64-LABEL: test_add1:
7; CHECK-64:       # %bb.0: # %entry
8; CHECK-64-NEXT:    vextublx 3, 3, 2
9; CHECK-64-NEXT:    add 3, 3, 4
10; CHECK-64-NEXT:    clrldi 3, 3, 56
11; CHECK-64-NEXT:    blr
12;
13; CHECK-32-LABEL: test_add1:
14; CHECK-32:       # %bb.0: # %entry
15; CHECK-32-NEXT:    addi 5, 1, -16
16; CHECK-32-NEXT:    clrlwi 3, 3, 28
17; CHECK-32-NEXT:    stxv 34, -16(1)
18; CHECK-32-NEXT:    lbzx 3, 5, 3
19; CHECK-32-NEXT:    add 3, 3, 4
20; CHECK-32-NEXT:    clrlwi 3, 3, 24
21; CHECK-32-NEXT:    blr
22entry:
23  %vecext = extractelement <16 x i8> %a, i32 %index
24  %conv = zext i8 %vecext to i32
25  %conv1 = zext i8 %c to i32
26  %add = add nuw nsw i32 %conv, %conv1
27  %conv2 = trunc i32 %add to i8
28  ret i8 %conv2
29}
30
31define signext i8 @test_add2(<16 x i8> %a, i32 signext %index, i8 signext %c) {
32; CHECK-64-LABEL: test_add2:
33; CHECK-64:       # %bb.0: # %entry
34; CHECK-64-NEXT:    vextublx 3, 3, 2
35; CHECK-64-NEXT:    add 3, 3, 4
36; CHECK-64-NEXT:    extsb 3, 3
37; CHECK-64-NEXT:    blr
38;
39; CHECK-32-LABEL: test_add2:
40; CHECK-32:       # %bb.0: # %entry
41; CHECK-32-NEXT:    addi 5, 1, -16
42; CHECK-32-NEXT:    clrlwi 3, 3, 28
43; CHECK-32-NEXT:    stxv 34, -16(1)
44; CHECK-32-NEXT:    lbzx 3, 5, 3
45; CHECK-32-NEXT:    add 3, 3, 4
46; CHECK-32-NEXT:    extsb 3, 3
47; CHECK-32-NEXT:    blr
48entry:
49  %vecext = extractelement <16 x i8> %a, i32 %index
50  %conv3 = zext i8 %vecext to i32
51  %conv14 = zext i8 %c to i32
52  %add = add nuw nsw i32 %conv3, %conv14
53  %conv2 = trunc i32 %add to i8
54  ret i8 %conv2
55}
56
57define zeroext i16 @test_add3(<8 x i16> %a, i32 signext %index, i16 zeroext %c) {
58; CHECK-64-LABEL: test_add3:
59; CHECK-64:       # %bb.0: # %entry
60; CHECK-64-NEXT:    rlwinm 3, 3, 1, 28, 30
61; CHECK-64-NEXT:    vextuhlx 3, 3, 2
62; CHECK-64-NEXT:    add 3, 3, 4
63; CHECK-64-NEXT:    clrldi 3, 3, 48
64; CHECK-64-NEXT:    blr
65;
66; CHECK-32-LABEL: test_add3:
67; CHECK-32:       # %bb.0: # %entry
68; CHECK-32-NEXT:    addi 5, 1, -16
69; CHECK-32-NEXT:    rlwinm 3, 3, 1, 28, 30
70; CHECK-32-NEXT:    stxv 34, -16(1)
71; CHECK-32-NEXT:    lhzx 3, 5, 3
72; CHECK-32-NEXT:    add 3, 3, 4
73; CHECK-32-NEXT:    clrlwi 3, 3, 16
74; CHECK-32-NEXT:    blr
75entry:
76  %vecext = extractelement <8 x i16> %a, i32 %index
77  %conv = zext i16 %vecext to i32
78  %conv1 = zext i16 %c to i32
79  %add = add nuw nsw i32 %conv, %conv1
80  %conv2 = trunc i32 %add to i16
81  ret i16 %conv2
82}
83
84define signext i16 @test_add4(<8 x i16> %a, i32 signext %index, i16 signext %c) {
85; CHECK-64-LABEL: test_add4:
86; CHECK-64:       # %bb.0: # %entry
87; CHECK-64-NEXT:    rlwinm 3, 3, 1, 28, 30
88; CHECK-64-NEXT:    vextuhlx 3, 3, 2
89; CHECK-64-NEXT:    add 3, 3, 4
90; CHECK-64-NEXT:    extsh 3, 3
91; CHECK-64-NEXT:    blr
92;
93; CHECK-32-LABEL: test_add4:
94; CHECK-32:       # %bb.0: # %entry
95; CHECK-32-NEXT:    addi 5, 1, -16
96; CHECK-32-NEXT:    rlwinm 3, 3, 1, 28, 30
97; CHECK-32-NEXT:    stxv 34, -16(1)
98; CHECK-32-NEXT:    lhzx 3, 5, 3
99; CHECK-32-NEXT:    add 3, 3, 4
100; CHECK-32-NEXT:    extsh 3, 3
101; CHECK-32-NEXT:    blr
102entry:
103  %vecext = extractelement <8 x i16> %a, i32 %index
104  %conv5 = zext i16 %vecext to i32
105  %conv16 = zext i16 %c to i32
106  %add = add nuw nsw i32 %conv5, %conv16
107  %conv2 = trunc i32 %add to i16
108  ret i16 %conv2
109}
110
111define zeroext i32 @test_add5(<4 x i32> %a, i32 signext %index, i32 zeroext %c) {
112; CHECK-64-LABEL: test_add5:
113; CHECK-64:       # %bb.0: # %entry
114; CHECK-64-NEXT:    rlwinm 3, 3, 2, 28, 29
115; CHECK-64-NEXT:    vextuwlx 3, 3, 2
116; CHECK-64-NEXT:    add 3, 3, 4
117; CHECK-64-NEXT:    clrldi 3, 3, 32
118; CHECK-64-NEXT:    blr
119;
120; CHECK-32-LABEL: test_add5:
121; CHECK-32:       # %bb.0: # %entry
122; CHECK-32-NEXT:    addi 5, 1, -16
123; CHECK-32-NEXT:    rlwinm 3, 3, 2, 28, 29
124; CHECK-32-NEXT:    stxv 34, -16(1)
125; CHECK-32-NEXT:    lwzx 3, 5, 3
126; CHECK-32-NEXT:    add 3, 3, 4
127; CHECK-32-NEXT:    blr
128entry:
129  %vecext = extractelement <4 x i32> %a, i32 %index
130  %add = add i32 %vecext, %c
131  ret i32 %add
132}
133
134define signext i32 @test_add6(<4 x i32> %a, i32 signext %index, i32 signext %c) {
135; CHECK-64-LABEL: test_add6:
136; CHECK-64:       # %bb.0: # %entry
137; CHECK-64-NEXT:    rlwinm 3, 3, 2, 28, 29
138; CHECK-64-NEXT:    vextuwlx 3, 3, 2
139; CHECK-64-NEXT:    add 3, 3, 4
140; CHECK-64-NEXT:    extsw 3, 3
141; CHECK-64-NEXT:    blr
142;
143; CHECK-32-LABEL: test_add6:
144; CHECK-32:       # %bb.0: # %entry
145; CHECK-32-NEXT:    addi 5, 1, -16
146; CHECK-32-NEXT:    rlwinm 3, 3, 2, 28, 29
147; CHECK-32-NEXT:    stxv 34, -16(1)
148; CHECK-32-NEXT:    lwzx 3, 5, 3
149; CHECK-32-NEXT:    add 3, 3, 4
150; CHECK-32-NEXT:    blr
151entry:
152  %vecext = extractelement <4 x i32> %a, i32 %index
153  %add = add nsw i32 %vecext, %c
154  ret i32 %add
155}
156
157; When extracting word element 2 on LE, it's better to use mfvsrwz rather than vextuwrx
158define zeroext i32 @test7(<4 x i32> %a) {
159; CHECK-64-LABEL: test7:
160; CHECK-64:       # %bb.0: # %entry
161; CHECK-64-NEXT:    li 3, 8
162; CHECK-64-NEXT:    vextuwlx 3, 3, 2
163; CHECK-64-NEXT:    blr
164;
165; CHECK-32-LABEL: test7:
166; CHECK-32:       # %bb.0: # %entry
167; CHECK-32-NEXT:    stxv 34, -16(1)
168; CHECK-32-NEXT:    lwz 3, -8(1)
169; CHECK-32-NEXT:    blr
170entry:
171  %vecext = extractelement <4 x i32> %a, i32 2
172  ret i32 %vecext
173}
174
175define zeroext i32 @testadd_7(<4 x i32> %a, i32 zeroext %c) {
176; CHECK-64-LABEL: testadd_7:
177; CHECK-64:       # %bb.0: # %entry
178; CHECK-64-NEXT:    li 4, 8
179; CHECK-64-NEXT:    vextuwlx 4, 4, 2
180; CHECK-64-NEXT:    add 3, 4, 3
181; CHECK-64-NEXT:    clrldi 3, 3, 32
182; CHECK-64-NEXT:    blr
183;
184; CHECK-32-LABEL: testadd_7:
185; CHECK-32:       # %bb.0: # %entry
186; CHECK-32-NEXT:    stxv 34, -16(1)
187; CHECK-32-NEXT:    lwz 4, -8(1)
188; CHECK-32-NEXT:    add 3, 4, 3
189; CHECK-32-NEXT:    blr
190entry:
191  %vecext = extractelement <4 x i32> %a, i32 2
192  %add = add i32 %vecext, %c
193  ret i32 %add
194}
195
196define signext i32 @test8(<4 x i32> %a) {
197; CHECK-64-LABEL: test8:
198; CHECK-64:       # %bb.0: # %entry
199; CHECK-64-NEXT:    li 3, 8
200; CHECK-64-NEXT:    vextuwlx 3, 3, 2
201; CHECK-64-NEXT:    extsw 3, 3
202; CHECK-64-NEXT:    blr
203;
204; CHECK-32-LABEL: test8:
205; CHECK-32:       # %bb.0: # %entry
206; CHECK-32-NEXT:    stxv 34, -16(1)
207; CHECK-32-NEXT:    lwz 3, -8(1)
208; CHECK-32-NEXT:    blr
209entry:
210  %vecext = extractelement <4 x i32> %a, i32 2
211  ret i32 %vecext
212}
213
214define signext i32 @testadd_8(<4 x i32> %a, i32 signext %c) {
215; CHECK-64-LABEL: testadd_8:
216; CHECK-64:       # %bb.0: # %entry
217; CHECK-64-NEXT:    li 4, 8
218; CHECK-64-NEXT:    vextuwlx 4, 4, 2
219; CHECK-64-NEXT:    add 3, 4, 3
220; CHECK-64-NEXT:    extsw 3, 3
221; CHECK-64-NEXT:    blr
222;
223; CHECK-32-LABEL: testadd_8:
224; CHECK-32:       # %bb.0: # %entry
225; CHECK-32-NEXT:    stxv 34, -16(1)
226; CHECK-32-NEXT:    lwz 4, -8(1)
227; CHECK-32-NEXT:    add 3, 4, 3
228; CHECK-32-NEXT:    blr
229entry:
230  %vecext = extractelement <4 x i32> %a, i32 2
231  %add = add nsw i32 %vecext, %c
232  ret i32 %add
233}
234
235; When extracting word element 1 on BE, it's better to use mfvsrwz rather than vextuwlx
236define signext i32 @test9(<4 x i32> %a) {
237; CHECK-64-LABEL: test9:
238; CHECK-64:       # %bb.0: # %entry
239; CHECK-64-NEXT:    mfvsrwz 3, 34
240; CHECK-64-NEXT:    extsw 3, 3
241; CHECK-64-NEXT:    blr
242;
243; CHECK-32-LABEL: test9:
244; CHECK-32:       # %bb.0: # %entry
245; CHECK-32-NEXT:    stxv 34, -16(1)
246; CHECK-32-NEXT:    lwz 3, -12(1)
247; CHECK-32-NEXT:    blr
248entry:
249  %vecext = extractelement <4 x i32> %a, i32 1
250  ret i32 %vecext
251}
252
253define signext i32 @testadd_9(<4 x i32> %a, i32 signext %c) {
254; CHECK-64-LABEL: testadd_9:
255; CHECK-64:       # %bb.0: # %entry
256; CHECK-64-NEXT:    mfvsrwz 4, 34
257; CHECK-64-NEXT:    add 3, 4, 3
258; CHECK-64-NEXT:    extsw 3, 3
259; CHECK-64-NEXT:    blr
260;
261; CHECK-32-LABEL: testadd_9:
262; CHECK-32:       # %bb.0: # %entry
263; CHECK-32-NEXT:    stxv 34, -16(1)
264; CHECK-32-NEXT:    lwz 4, -12(1)
265; CHECK-32-NEXT:    add 3, 4, 3
266; CHECK-32-NEXT:    blr
267entry:
268  %vecext = extractelement <4 x i32> %a, i32 1
269  %add = add nsw i32 %vecext, %c
270  ret i32 %add
271}
272