xref: /llvm-project/llvm/test/Transforms/InstCombine/extractelement.ll (revision 4872ecf1cc3cb9c4939a9e6210a9b9e9a9032e9f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S -data-layout="e-n64" | FileCheck %s --check-prefixes=ANY,ANYLE,LE64
3; RUN: opt < %s -passes=instcombine -S -data-layout="e-n128" | FileCheck %s --check-prefixes=ANY,ANYLE,LE128
4; RUN: opt < %s -passes=instcombine -S -data-layout="E-n64" | FileCheck %s --check-prefixes=ANY,ANYBE,BE64
5; RUN: opt < %s -passes=instcombine -S -data-layout="E-n128" | FileCheck %s --check-prefixes=ANY,ANYBE,BE128
6
7; RUN: opt < %s -passes=instcombine -S -data-layout="e-n64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYLE,LE64
8; RUN: opt < %s -passes=instcombine -S -data-layout="e-n128" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYLE,LE128
9; RUN: opt < %s -passes=instcombine -S -data-layout="E-n64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYBE,BE64
10; RUN: opt < %s -passes=instcombine -S -data-layout="E-n128" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYBE,BE128
11
12define i32 @extractelement_out_of_range(<2 x i32> %x) {
13; ANY-LABEL: @extractelement_out_of_range(
14; ANY-NEXT:    ret i32 poison
15;
16  %E1 = extractelement <2 x i32> %x, i8 16
17  ret i32 %E1
18}
19
20define i32 @extractelement_type_out_of_range(<2 x i32> %x) {
21; ANY-LABEL: @extractelement_type_out_of_range(
22; ANY-NEXT:    [[E1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
23; ANY-NEXT:    ret i32 [[E1]]
24;
25  %E1 = extractelement <2 x i32> %x, i128 0
26  ret i32 %E1
27}
28
29define i32 @bitcasted_inselt_equal_num_elts(float %f) {
30; ANY-LABEL: @bitcasted_inselt_equal_num_elts(
31; ANY-NEXT:    [[R:%.*]] = bitcast float [[F:%.*]] to i32
32; ANY-NEXT:    ret i32 [[R]]
33;
34  %vf = insertelement <4 x float> undef, float %f, i32 0
35  %vi = bitcast <4 x float> %vf to <4 x i32>
36  %r = extractelement <4 x i32> %vi, i32 0
37  ret i32 %r
38}
39
40define i64 @test2(i64 %in) {
41; ANY-LABEL: @test2(
42; ANY-NEXT:    ret i64 [[IN:%.*]]
43;
44  %vec = insertelement <8 x i64> undef, i64 %in, i32 0
45  %splat = shufflevector <8 x i64> %vec, <8 x i64> undef, <8 x i32> zeroinitializer
46  %add = add <8 x i64> %splat, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
47  %r = extractelement <8 x i64> %add, i32 0
48  ret i64 %r
49}
50
51define i32 @bitcasted_inselt_wide_source_zero_elt(i64 %x) {
52; ANYLE-LABEL: @bitcasted_inselt_wide_source_zero_elt(
53; ANYLE-NEXT:    [[R:%.*]] = trunc i64 [[X:%.*]] to i32
54; ANYLE-NEXT:    ret i32 [[R]]
55;
56; ANYBE-LABEL: @bitcasted_inselt_wide_source_zero_elt(
57; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32
58; ANYBE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP1]] to i32
59; ANYBE-NEXT:    ret i32 [[R]]
60;
61  %i = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
62  %b = bitcast <2 x i64> %i to <4 x i32>
63  %r = extractelement <4 x i32> %b, i32 0
64  ret i32 %r
65}
66
67define i16 @bitcasted_inselt_wide_source_modulo_elt(i64 %x) {
68; ANYLE-LABEL: @bitcasted_inselt_wide_source_modulo_elt(
69; ANYLE-NEXT:    [[R:%.*]] = trunc i64 [[X:%.*]] to i16
70; ANYLE-NEXT:    ret i16 [[R]]
71;
72; ANYBE-LABEL: @bitcasted_inselt_wide_source_modulo_elt(
73; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 48
74; ANYBE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP1]] to i16
75; ANYBE-NEXT:    ret i16 [[R]]
76;
77  %i = insertelement <2 x i64> undef, i64 %x, i32 1
78  %b = bitcast <2 x i64> %i to <8 x i16>
79  %r = extractelement <8 x i16> %b, i32 4
80  ret i16 %r
81}
82
83define i32 @bitcasted_inselt_wide_source_not_modulo_elt(i64 %x) {
84; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt(
85; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32
86; ANYLE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP1]] to i32
87; ANYLE-NEXT:    ret i32 [[R]]
88;
89; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt(
90; ANYBE-NEXT:    [[R:%.*]] = trunc i64 [[X:%.*]] to i32
91; ANYBE-NEXT:    ret i32 [[R]]
92;
93  %i = insertelement <2 x i64> undef, i64 %x, i32 0
94  %b = bitcast <2 x i64> %i to <4 x i32>
95  %r = extractelement <4 x i32> %b, i32 1
96  ret i32 %r
97}
98
99define i8 @bitcasted_inselt_wide_source_not_modulo_elt_not_half(i32 %x) {
100; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half(
101; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16
102; ANYLE-NEXT:    [[R:%.*]] = trunc i32 [[TMP1]] to i8
103; ANYLE-NEXT:    ret i8 [[R]]
104;
105; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half(
106; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
107; ANYBE-NEXT:    [[R:%.*]] = trunc i32 [[TMP1]] to i8
108; ANYBE-NEXT:    ret i8 [[R]]
109;
110  %i = insertelement <2 x i32> undef, i32 %x, i32 0
111  %b = bitcast <2 x i32> %i to <8 x i8>
112  %r = extractelement <8 x i8> %b, i32 2
113  ret i8 %r
114}
115
116define i3 @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(i15 %x) {
117; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(
118; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i15 [[X:%.*]], 3
119; ANYLE-NEXT:    [[R:%.*]] = trunc i15 [[TMP1]] to i3
120; ANYLE-NEXT:    ret i3 [[R]]
121;
122; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(
123; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i15 [[X:%.*]], 9
124; ANYBE-NEXT:    [[R:%.*]] = trunc i15 [[TMP1]] to i3
125; ANYBE-NEXT:    ret i3 [[R]]
126;
127  %i = insertelement <3 x i15> undef, i15 %x, i32 0
128  %b = bitcast <3 x i15> %i to <15 x i3>
129  %r = extractelement <15 x i3> %b, i32 1
130  ret i3 %r
131}
132
133; Negative test for the above fold, but we can remove the insert here.
134
135define i8 @bitcasted_inselt_wide_source_wrong_insert(<2 x i32> %v, i32 %x) {
136; ANY-LABEL: @bitcasted_inselt_wide_source_wrong_insert(
137; ANY-NEXT:    [[TMP1:%.*]] = bitcast <2 x i32> [[V:%.*]] to <8 x i8>
138; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i8> [[TMP1]], i64 2
139; ANY-NEXT:    ret i8 [[R]]
140;
141  %i = insertelement <2 x i32> %v, i32 %x, i32 1
142  %b = bitcast <2 x i32> %i to <8 x i8>
143  %r = extractelement <8 x i8> %b, i32 2
144  ret i8 %r
145}
146
147; Partial negative test for the above fold, extra uses are not allowed if shift is needed.
148
149declare void @use(<8 x i8>)
150
151define i8 @bitcasted_inselt_wide_source_uses(i32 %x) {
152; ANYLE-LABEL: @bitcasted_inselt_wide_source_uses(
153; ANYLE-NEXT:    [[I:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 0
154; ANYLE-NEXT:    [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8>
155; ANYLE-NEXT:    call void @use(<8 x i8> [[B]])
156; ANYLE-NEXT:    [[R:%.*]] = extractelement <8 x i8> [[B]], i64 3
157; ANYLE-NEXT:    ret i8 [[R]]
158;
159; ANYBE-LABEL: @bitcasted_inselt_wide_source_uses(
160; ANYBE-NEXT:    [[I:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 0
161; ANYBE-NEXT:    [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8>
162; ANYBE-NEXT:    call void @use(<8 x i8> [[B]])
163; ANYBE-NEXT:    [[R:%.*]] = trunc i32 [[X]] to i8
164; ANYBE-NEXT:    ret i8 [[R]]
165;
166  %i = insertelement <2 x i32> undef, i32 %x, i32 0
167  %b = bitcast <2 x i32> %i to <8 x i8>
168  call void @use(<8 x i8> %b)
169  %r = extractelement <8 x i8> %b, i32 3
170  ret i8 %r
171}
172
173define float @bitcasted_inselt_to_FP(i64 %x) {
174; ANYLE-LABEL: @bitcasted_inselt_to_FP(
175; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32
176; ANYLE-NEXT:    [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32
177; ANYLE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP2]] to float
178; ANYLE-NEXT:    ret float [[R]]
179;
180; ANYBE-LABEL: @bitcasted_inselt_to_FP(
181; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
182; ANYBE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
183; ANYBE-NEXT:    ret float [[R]]
184;
185  %i = insertelement <2 x i64> undef, i64 %x, i32 0
186  %b = bitcast <2 x i64> %i to <4 x float>
187  %r = extractelement <4 x float> %b, i32 1
188  ret float %r
189}
190
191declare void @use_v2i128(<2 x i128>)
192declare void @use_v8f32(<8 x float>)
193
194define float @bitcasted_inselt_to_FP_uses(i128 %x) {
195; ANY-LABEL: @bitcasted_inselt_to_FP_uses(
196; ANY-NEXT:    [[I:%.*]] = insertelement <2 x i128> <i128 poison, i128 undef>, i128 [[X:%.*]], i64 0
197; ANY-NEXT:    call void @use_v2i128(<2 x i128> [[I]])
198; ANY-NEXT:    [[B:%.*]] = bitcast <2 x i128> [[I]] to <8 x float>
199; ANY-NEXT:    [[R:%.*]] = extractelement <8 x float> [[B]], i64 1
200; ANY-NEXT:    ret float [[R]]
201;
202  %i = insertelement <2 x i128> undef, i128 %x, i32 0
203  call void @use_v2i128(<2 x i128> %i)
204  %b = bitcast <2 x i128> %i to <8 x float>
205  %r = extractelement <8 x float> %b, i32 1
206  ret float %r
207}
208
209define float @bitcasted_inselt_to_FP_uses2(i128 %x) {
210; ANY-LABEL: @bitcasted_inselt_to_FP_uses2(
211; ANY-NEXT:    [[I:%.*]] = insertelement <2 x i128> <i128 poison, i128 undef>, i128 [[X:%.*]], i64 0
212; ANY-NEXT:    [[B:%.*]] = bitcast <2 x i128> [[I]] to <8 x float>
213; ANY-NEXT:    call void @use_v8f32(<8 x float> [[B]])
214; ANY-NEXT:    [[R:%.*]] = extractelement <8 x float> [[B]], i64 1
215; ANY-NEXT:    ret float [[R]]
216;
217  %i = insertelement <2 x i128> undef, i128 %x, i32 0
218  %b = bitcast <2 x i128> %i to <8 x float>
219  call void @use_v8f32(<8 x float> %b)
220  %r = extractelement <8 x float> %b, i32 1
221  ret float %r
222}
223
224define i32 @bitcasted_inselt_from_FP(double %x) {
225; ANYLE-LABEL: @bitcasted_inselt_from_FP(
226; ANYLE-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
227; ANYLE-NEXT:    [[TMP2:%.*]] = lshr i64 [[TMP1]], 32
228; ANYLE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP2]] to i32
229; ANYLE-NEXT:    ret i32 [[R]]
230;
231; ANYBE-LABEL: @bitcasted_inselt_from_FP(
232; ANYBE-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
233; ANYBE-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
234; ANYBE-NEXT:    ret i32 [[R]]
235;
236  %i = insertelement <2 x double> undef, double %x, i32 0
237  %b = bitcast <2 x double> %i to <4 x i32>
238  %r = extractelement <4 x i32> %b, i32 1
239  ret i32 %r
240}
241
242declare void @use_v2f64(<2 x double>)
243declare void @use_v8i16(<8 x i16>)
244
245define i16 @bitcasted_inselt_from_FP_uses(double %x) {
246; ANY-LABEL: @bitcasted_inselt_from_FP_uses(
247; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
248; ANY-NEXT:    call void @use_v2f64(<2 x double> [[I]])
249; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <8 x i16>
250; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i16> [[B]], i64 1
251; ANY-NEXT:    ret i16 [[R]]
252;
253  %i = insertelement <2 x double> undef, double %x, i32 0
254  call void @use_v2f64(<2 x double> %i)
255  %b = bitcast <2 x double> %i to <8 x i16>
256  %r = extractelement <8 x i16> %b, i32 1
257  ret i16 %r
258}
259
260define i16 @bitcasted_inselt_from_FP_uses2(double %x) {
261; ANY-LABEL: @bitcasted_inselt_from_FP_uses2(
262; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
263; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <8 x i16>
264; ANY-NEXT:    call void @use_v8i16(<8 x i16> [[B]])
265; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i16> [[B]], i64 1
266; ANY-NEXT:    ret i16 [[R]]
267;
268  %i = insertelement <2 x double> undef, double %x, i32 0
269  %b = bitcast <2 x double> %i to <8 x i16>
270  call void @use_v8i16(<8 x i16> %b)
271  %r = extractelement <8 x i16> %b, i32 1
272  ret i16 %r
273}
274
275define float @bitcasted_inselt_to_and_from_FP(double %x) {
276; ANY-LABEL: @bitcasted_inselt_to_and_from_FP(
277; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> poison, double [[X:%.*]], i64 0
278; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <4 x float>
279; ANY-NEXT:    [[R:%.*]] = extractelement <4 x float> [[B]], i64 1
280; ANY-NEXT:    ret float [[R]]
281;
282  %i = insertelement <2 x double> undef, double %x, i32 0
283  %b = bitcast <2 x double> %i to <4 x float>
284  %r = extractelement <4 x float> %b, i32 1
285  ret float %r
286}
287
288define float @bitcasted_inselt_to_and_from_FP_uses(double %x) {
289; ANY-LABEL: @bitcasted_inselt_to_and_from_FP_uses(
290; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
291; ANY-NEXT:    call void @use_v2f64(<2 x double> [[I]])
292; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <4 x float>
293; ANY-NEXT:    [[R:%.*]] = extractelement <4 x float> [[B]], i64 1
294; ANY-NEXT:    ret float [[R]]
295;
296  %i = insertelement <2 x double> undef, double %x, i32 0
297  call void @use_v2f64(<2 x double> %i)
298  %b = bitcast <2 x double> %i to <4 x float>
299  %r = extractelement <4 x float> %b, i32 1
300  ret float %r
301}
302
303declare void @use_v4f32(<4 x float>)
304
305define float @bitcasted_inselt_to_and_from_FP_uses2(double %x) {
306; ANY-LABEL: @bitcasted_inselt_to_and_from_FP_uses2(
307; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
308; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <4 x float>
309; ANY-NEXT:    call void @use_v4f32(<4 x float> [[B]])
310; ANY-NEXT:    [[R:%.*]] = extractelement <4 x float> [[B]], i64 1
311; ANY-NEXT:    ret float [[R]]
312;
313  %i = insertelement <2 x double> undef, double %x, i32 0
314  %b = bitcast <2 x double> %i to <4 x float>
315  call void @use_v4f32(<4 x float> %b)
316  %r = extractelement <4 x float> %b, i32 1
317  ret float %r
318}
319
320; This would crash/assert because the logic for collectShuffleElements()
321; does not consider the possibility of invalid insert/extract operands.
322
323define <4 x double> @invalid_extractelement(<2 x double> %a, <4 x double> %b, ptr %p) {
324; ANY-LABEL: @invalid_extractelement(
325; ANY-NEXT:    [[TMP1:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
326; ANY-NEXT:    [[T4:%.*]] = shufflevector <4 x double> [[B:%.*]], <4 x double> [[TMP1]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
327; ANY-NEXT:    [[E:%.*]] = extractelement <4 x double> [[B]], i64 1
328; ANY-NEXT:    store double [[E]], ptr [[P:%.*]], align 8
329; ANY-NEXT:    ret <4 x double> [[T4]]
330;
331  %t3 = extractelement <2 x double> %a, i32 0
332  %t4 = insertelement <4 x double> %b, double %t3, i32 2
333  %e = extractelement <4 x double> %t4, i32 1
334  store double %e, ptr %p
335  %e1 = extractelement <2 x double> %a, i32 4 ; invalid index
336  %r = insertelement <4 x double> %t4, double %e1, i64 0
337  ret <4 x double> %r
338}
339
340; i32 is a desirable/supported type independent of data layout.
341
342define i8 @bitcast_scalar_supported_type_index0(i32 %x) {
343; ANYLE-LABEL: @bitcast_scalar_supported_type_index0(
344; ANYLE-NEXT:    [[R:%.*]] = trunc i32 [[X:%.*]] to i8
345; ANYLE-NEXT:    ret i8 [[R]]
346;
347; ANYBE-LABEL: @bitcast_scalar_supported_type_index0(
348; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 24
349; ANYBE-NEXT:    [[R:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i8
350; ANYBE-NEXT:    ret i8 [[R]]
351;
352  %v = bitcast i32 %x to <4 x i8>
353  %r = extractelement <4 x i8> %v, i8 0
354  ret i8 %r
355}
356
357define i8 @bitcast_scalar_supported_type_index2(i32 %x) {
358; ANYLE-LABEL: @bitcast_scalar_supported_type_index2(
359; ANYLE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
360; ANYLE-NEXT:    [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8
361; ANYLE-NEXT:    ret i8 [[R]]
362;
363; ANYBE-LABEL: @bitcast_scalar_supported_type_index2(
364; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 8
365; ANYBE-NEXT:    [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8
366; ANYBE-NEXT:    ret i8 [[R]]
367;
368  %v = bitcast i32 %x to <4 x i8>
369  %r = extractelement <4 x i8> %v, i64 2
370  ret i8 %r
371}
372
373; i64 is legal based on data layout.
374
375define i4 @bitcast_scalar_legal_type_index3(i64 %x) {
376; LE64-LABEL: @bitcast_scalar_legal_type_index3(
377; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 12
378; LE64-NEXT:    [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4
379; LE64-NEXT:    ret i4 [[R]]
380;
381; LE128-LABEL: @bitcast_scalar_legal_type_index3(
382; LE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <16 x i4>
383; LE128-NEXT:    [[R:%.*]] = extractelement <16 x i4> [[V]], i64 3
384; LE128-NEXT:    ret i4 [[R]]
385;
386; BE64-LABEL: @bitcast_scalar_legal_type_index3(
387; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 48
388; BE64-NEXT:    [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4
389; BE64-NEXT:    ret i4 [[R]]
390;
391; BE128-LABEL: @bitcast_scalar_legal_type_index3(
392; BE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <16 x i4>
393; BE128-NEXT:    [[R:%.*]] = extractelement <16 x i4> [[V]], i64 3
394; BE128-NEXT:    ret i4 [[R]]
395;
396
397  %v = bitcast i64 %x to <16 x i4>
398  %r = extractelement <16 x i4> %v, i64 3
399  ret i4 %r
400}
401
402; negative test - don't create a shift for an illegal type.
403
404define i8 @bitcast_scalar_illegal_type_index1(i128 %x) {
405; LE64-LABEL: @bitcast_scalar_illegal_type_index1(
406; LE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8>
407; LE64-NEXT:    [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1
408; LE64-NEXT:    ret i8 [[R]]
409;
410; LE128-LABEL: @bitcast_scalar_illegal_type_index1(
411; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 8
412; LE128-NEXT:    [[R:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i8
413; LE128-NEXT:    ret i8 [[R]]
414;
415; BE64-LABEL: @bitcast_scalar_illegal_type_index1(
416; BE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8>
417; BE64-NEXT:    [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1
418; BE64-NEXT:    ret i8 [[R]]
419;
420; BE128-LABEL: @bitcast_scalar_illegal_type_index1(
421; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 112
422; BE128-NEXT:    [[R:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i8
423; BE128-NEXT:    ret i8 [[R]]
424;
425  %v = bitcast i128 %x to <16 x i8>
426  %r = extractelement <16 x i8> %v, i64 1
427  ret i8 %r
428}
429
430; negative test - can't use shift/trunc on FP
431
432define i8 @bitcast_fp_index0(float %x) {
433; ANY-LABEL: @bitcast_fp_index0(
434; ANY-NEXT:    [[V:%.*]] = bitcast float [[X:%.*]] to <4 x i8>
435; ANY-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[V]], i64 0
436; ANY-NEXT:    ret i8 [[R]]
437;
438  %v = bitcast float %x to <4 x i8>
439  %r = extractelement <4 x i8> %v, i8 0
440  ret i8 %r
441}
442
443define half @bitcast_fp16vec_index0(i32 %x) {
444; ANYLE-LABEL: @bitcast_fp16vec_index0(
445; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
446; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
447; ANYLE-NEXT:    ret half [[R]]
448;
449; ANYBE-LABEL: @bitcast_fp16vec_index0(
450; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
451; ANYBE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
452; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
453; ANYBE-NEXT:    ret half [[R]]
454;
455  %v = bitcast i32 %x to <2 x half>
456  %r = extractelement <2 x half> %v, i8 0
457  ret half %r
458}
459
460define half @bitcast_fp16vec_index1(i32 %x) {
461; ANYLE-LABEL: @bitcast_fp16vec_index1(
462; ANYLE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
463; ANYLE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
464; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
465; ANYLE-NEXT:    ret half [[R]]
466;
467; ANYBE-LABEL: @bitcast_fp16vec_index1(
468; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
469; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
470; ANYBE-NEXT:    ret half [[R]]
471;
472  %v = bitcast i32 %x to <2 x half>
473  %r = extractelement <2 x half> %v, i8 1
474  ret half %r
475}
476
477define bfloat @bitcast_bfp16vec_index0(i32 %x) {
478; ANYLE-LABEL: @bitcast_bfp16vec_index0(
479; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
480; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
481; ANYLE-NEXT:    ret bfloat [[R]]
482;
483; ANYBE-LABEL: @bitcast_bfp16vec_index0(
484; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
485; ANYBE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
486; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
487; ANYBE-NEXT:    ret bfloat [[R]]
488;
489  %v = bitcast i32 %x to <2 x bfloat>
490  %r = extractelement <2 x bfloat> %v, i8 0
491  ret bfloat %r
492}
493
494define bfloat @bitcast_bfp16vec_index1(i32 %x) {
495; ANYLE-LABEL: @bitcast_bfp16vec_index1(
496; ANYLE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
497; ANYLE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
498; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
499; ANYLE-NEXT:    ret bfloat [[R]]
500;
501; ANYBE-LABEL: @bitcast_bfp16vec_index1(
502; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
503; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
504; ANYBE-NEXT:    ret bfloat [[R]]
505;
506  %v = bitcast i32 %x to <2 x bfloat>
507  %r = extractelement <2 x bfloat> %v, i8 1
508  ret bfloat %r
509}
510
511define float @bitcast_fp32vec_index0(i64 %x) {
512; ANYLE-LABEL: @bitcast_fp32vec_index0(
513; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
514; ANYLE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
515; ANYLE-NEXT:    ret float [[R]]
516;
517; BE64-LABEL: @bitcast_fp32vec_index0(
518; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
519; BE64-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i32
520; BE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
521; BE64-NEXT:    ret float [[R]]
522;
523; BE128-LABEL: @bitcast_fp32vec_index0(
524; BE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
525; BE128-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 0
526; BE128-NEXT:    ret float [[R]]
527;
528  %v = bitcast i64 %x to <2 x float>
529  %r = extractelement <2 x float> %v, i8 0
530  ret float %r
531}
532
533define float @bitcast_fp32vec_index1(i64 %x) {
534; LE64-LABEL: @bitcast_fp32vec_index1(
535; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
536; LE64-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i32
537; LE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
538; LE64-NEXT:    ret float [[R]]
539;
540; LE128-LABEL: @bitcast_fp32vec_index1(
541; LE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
542; LE128-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 1
543; LE128-NEXT:    ret float [[R]]
544;
545; ANYBE-LABEL: @bitcast_fp32vec_index1(
546; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
547; ANYBE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
548; ANYBE-NEXT:    ret float [[R]]
549;
550  %v = bitcast i64 %x to <2 x float>
551  %r = extractelement <2 x float> %v, i8 1
552  ret float %r
553}
554
555define double @bitcast_fp64vec64_index0(i64 %x) {
556; ANY-LABEL: @bitcast_fp64vec64_index0(
557; ANY-NEXT:    [[R:%.*]] = bitcast i64 [[X:%.*]] to double
558; ANY-NEXT:    ret double [[R]]
559;
560  %v = bitcast i64 %x to <1 x double>
561  %r = extractelement <1 x double> %v, i8 0
562  ret double %r
563}
564
565define double @bitcast_fp64vec_index0(i128 %x) {
566; ANYLE-LABEL: @bitcast_fp64vec_index0(
567; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
568; ANYLE-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
569; ANYLE-NEXT:    ret double [[R]]
570;
571; BE64-LABEL: @bitcast_fp64vec_index0(
572; BE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
573; BE64-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 0
574; BE64-NEXT:    ret double [[R]]
575;
576; BE128-LABEL: @bitcast_fp64vec_index0(
577; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 64
578; BE128-NEXT:    [[TMP1:%.*]] = trunc nuw i128 [[EXTELT_OFFSET]] to i64
579; BE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
580; BE128-NEXT:    ret double [[R]]
581;
582  %v = bitcast i128 %x to <2 x double>
583  %r = extractelement <2 x double> %v, i8 0
584  ret double %r
585}
586
587define double @bitcast_fp64vec_index1(i128 %x) {
588; LE64-LABEL: @bitcast_fp64vec_index1(
589; LE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
590; LE64-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 1
591; LE64-NEXT:    ret double [[R]]
592;
593; LE128-LABEL: @bitcast_fp64vec_index1(
594; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 64
595; LE128-NEXT:    [[TMP1:%.*]] = trunc nuw i128 [[EXTELT_OFFSET]] to i64
596; LE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
597; LE128-NEXT:    ret double [[R]]
598;
599; ANYBE-LABEL: @bitcast_fp64vec_index1(
600; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
601; ANYBE-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
602; ANYBE-NEXT:    ret double [[R]]
603;
604  %v = bitcast i128 %x to <2 x double>
605  %r = extractelement <2 x double> %v, i8 1
606  ret double %r
607}
608
609; negative test - input integer should be legal
610
611define x86_fp80 @bitcast_x86fp80vec_index0(i160 %x) {
612; ANYLE-LABEL: @bitcast_x86fp80vec_index0(
613; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i160 [[X:%.*]] to i80
614; ANYLE-NEXT:    [[R:%.*]] = bitcast i80 [[TMP1]] to x86_fp80
615; ANYLE-NEXT:    ret x86_fp80 [[R]]
616;
617; ANYBE-LABEL: @bitcast_x86fp80vec_index0(
618; ANYBE-NEXT:    [[V:%.*]] = bitcast i160 [[X:%.*]] to <2 x x86_fp80>
619; ANYBE-NEXT:    [[R:%.*]] = extractelement <2 x x86_fp80> [[V]], i64 0
620; ANYBE-NEXT:    ret x86_fp80 [[R]]
621;
622  %v = bitcast i160 %x to <2 x x86_fp80>
623  %r = extractelement <2 x x86_fp80> %v, i8 0
624  ret x86_fp80 %r
625}
626
627; negative test - input integer should be legal
628
629define x86_fp80 @bitcast_x86fp80vec_index1(i160 %x) {
630; ANYLE-LABEL: @bitcast_x86fp80vec_index1(
631; ANYLE-NEXT:    [[V:%.*]] = bitcast i160 [[X:%.*]] to <2 x x86_fp80>
632; ANYLE-NEXT:    [[R:%.*]] = extractelement <2 x x86_fp80> [[V]], i64 1
633; ANYLE-NEXT:    ret x86_fp80 [[R]]
634;
635; ANYBE-LABEL: @bitcast_x86fp80vec_index1(
636; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i160 [[X:%.*]] to i80
637; ANYBE-NEXT:    [[R:%.*]] = bitcast i80 [[TMP1]] to x86_fp80
638; ANYBE-NEXT:    ret x86_fp80 [[R]]
639;
640  %v = bitcast i160 %x to <2 x x86_fp80>
641  %r = extractelement <2 x x86_fp80> %v, i8 1
642  ret x86_fp80 %r
643}
644
645; negative test - input integer should be legal
646
647define fp128 @bitcast_fp128vec_index0(i256 %x) {
648; ANYLE-LABEL: @bitcast_fp128vec_index0(
649; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
650; ANYLE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to fp128
651; ANYLE-NEXT:    ret fp128 [[R]]
652;
653; ANYBE-LABEL: @bitcast_fp128vec_index0(
654; ANYBE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x fp128>
655; ANYBE-NEXT:    [[R:%.*]] = extractelement <2 x fp128> [[V]], i64 0
656; ANYBE-NEXT:    ret fp128 [[R]]
657;
658  %v = bitcast i256 %x to <2 x fp128>
659  %r = extractelement <2 x fp128> %v, i8 0
660  ret fp128 %r
661}
662
663; negative test - input integer should be legal
664
665define fp128 @bitcast_fp128vec_index1(i256 %x) {
666; ANYLE-LABEL: @bitcast_fp128vec_index1(
667; ANYLE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x fp128>
668; ANYLE-NEXT:    [[R:%.*]] = extractelement <2 x fp128> [[V]], i64 1
669; ANYLE-NEXT:    ret fp128 [[R]]
670;
671; ANYBE-LABEL: @bitcast_fp128vec_index1(
672; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
673; ANYBE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to fp128
674; ANYBE-NEXT:    ret fp128 [[R]]
675;
676  %v = bitcast i256 %x to <2 x fp128>
677  %r = extractelement <2 x fp128> %v, i8 1
678  ret fp128 %r
679}
680
681; negative test - input integer should be legal
682
683define ppc_fp128 @bitcast_ppcfp128vec_index0(i256 %x) {
684; ANYLE-LABEL: @bitcast_ppcfp128vec_index0(
685; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
686; ANYLE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to ppc_fp128
687; ANYLE-NEXT:    ret ppc_fp128 [[R]]
688;
689; ANYBE-LABEL: @bitcast_ppcfp128vec_index0(
690; ANYBE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x ppc_fp128>
691; ANYBE-NEXT:    [[R:%.*]] = extractelement <2 x ppc_fp128> [[V]], i64 0
692; ANYBE-NEXT:    ret ppc_fp128 [[R]]
693;
694  %v = bitcast i256 %x to <2 x ppc_fp128>
695  %r = extractelement <2 x ppc_fp128> %v, i8 0
696  ret ppc_fp128 %r
697}
698
699; negative test -input integer should be legal
700
701define ppc_fp128 @bitcast_ppcfp128vec_index1(i256 %x) {
702; ANYLE-LABEL: @bitcast_ppcfp128vec_index1(
703; ANYLE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x ppc_fp128>
704; ANYLE-NEXT:    [[R:%.*]] = extractelement <2 x ppc_fp128> [[V]], i64 1
705; ANYLE-NEXT:    ret ppc_fp128 [[R]]
706;
707; ANYBE-LABEL: @bitcast_ppcfp128vec_index1(
708; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
709; ANYBE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to ppc_fp128
710; ANYBE-NEXT:    ret ppc_fp128 [[R]]
711;
712  %v = bitcast i256 %x to <2 x ppc_fp128>
713  %r = extractelement <2 x ppc_fp128> %v, i8 1
714  ret ppc_fp128 %r
715}
716
717; negative test - input integer should be legal
718
719define i8 @bitcast_scalar_index_variable(i32 %x, i64 %y) {
720; ANY-LABEL: @bitcast_scalar_index_variable(
721; ANY-NEXT:    [[V:%.*]] = bitcast i32 [[X:%.*]] to <4 x i8>
722; ANY-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[V]], i64 [[Y:%.*]]
723; ANY-NEXT:    ret i8 [[R]]
724;
725  %v = bitcast i32 %x to <4 x i8>
726  %r = extractelement <4 x i8> %v, i64 %y
727  ret i8 %r
728}
729
730; extra use is not ok, even if we don't need a shift
731
732define i8 @bitcast_scalar_index0_use(i64 %x) {
733; ANY-LABEL: @bitcast_scalar_index0_use(
734; ANY-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8>
735; ANY-NEXT:    call void @use(<8 x i8> [[V]])
736; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i8> [[V]], i64 0
737; ANY-NEXT:    ret i8 [[R]]
738;
739
740  %v = bitcast i64 %x to <8 x i8>
741  call void @use(<8 x i8> %v)
742  %r = extractelement <8 x i8> %v, i64 0
743  ret i8 %r
744}
745
746define i1 @bit_extract_cmp(i64 %x) {
747; LE64-LABEL: @bit_extract_cmp(
748; LE64-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 9223372032559808512
749; LE64-NEXT:    [[R:%.*]] = icmp eq i64 [[TMP1]], 0
750; LE64-NEXT:    ret i1 [[R]]
751;
752; LE128-LABEL: @bit_extract_cmp(
753; LE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
754; LE128-NEXT:    [[E:%.*]] = extractelement <2 x float> [[V]], i64 1
755; LE128-NEXT:    [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
756; LE128-NEXT:    ret i1 [[R]]
757;
758; ANYBE-LABEL: @bit_extract_cmp(
759; ANYBE-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 2147483647
760; ANYBE-NEXT:    [[R:%.*]] = icmp eq i64 [[TMP1]], 0
761; ANYBE-NEXT:    ret i1 [[R]]
762;
763  %v = bitcast i64 %x to <2 x float>
764  %e = extractelement <2 x float> %v, i8 1
765  %r = fcmp oeq float %e, 0.0
766  ret i1 %r
767}
768
769define i32 @extelt_select_const_operand_vector(i1 %c) {
770; ANY-LABEL: @extelt_select_const_operand_vector(
771; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i32 4, i32 7
772; ANY-NEXT:    ret i32 [[R]]
773;
774  %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
775  %r = extractelement <3 x i32> %s, i32 2
776  ret i32 %r
777}
778
779define float @extelt_select_const_operand_vector_float(i1 %c) {
780; ANY-LABEL: @extelt_select_const_operand_vector_float(
781; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], float 4.000000e+00, float 7.000000e+00
782; ANY-NEXT:    ret float [[R]]
783;
784  %s = select i1 %c, <3 x float> <float 2.0, float 3.0, float 4.0>, <3 x float> <float 5.0, float 6.0, float 7.0>
785  %r = extractelement <3 x float> %s, i32 2
786  ret float %r
787}
788
789define i32 @extelt_vecselect_const_operand_vector(<3 x i1> %c) {
790; ANY-LABEL: @extelt_vecselect_const_operand_vector(
791; ANY-NEXT:    [[S:%.*]] = select <3 x i1> [[C:%.*]], <3 x i32> <i32 poison, i32 poison, i32 4>, <3 x i32> <i32 poison, i32 poison, i32 7>
792; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i64 2
793; ANY-NEXT:    ret i32 [[R]]
794;
795  %s = select <3 x i1> %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
796  %r = extractelement <3 x i32> %s, i32 2
797  ret i32 %r
798}
799
800define i32 @extelt_select_const_operand_extractelt_use(i1 %c) {
801; ANY-LABEL: @extelt_select_const_operand_extractelt_use(
802; ANY-NEXT:    [[E:%.*]] = select i1 [[C:%.*]], i32 4, i32 7
803; ANY-NEXT:    [[M:%.*]] = shl nuw nsw i32 [[E]], 1
804; ANY-NEXT:    [[M_2:%.*]] = shl nuw nsw i32 [[E]], 2
805; ANY-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[M]], [[M_2]]
806; ANY-NEXT:    ret i32 [[R]]
807;
808  %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
809  %e = extractelement <3 x i32> %s, i32 2
810  %m = mul i32 %e, 2
811  %m.2 = mul i32 %e, 4
812  %r = mul i32 %m, %m.2
813  ret i32 %r
814}
815
816define i32 @extelt_select_const_operand_select_use(i1 %c) {
817; ANY-LABEL: @extelt_select_const_operand_select_use(
818; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 poison, i32 3, i32 4>, <3 x i32> <i32 poison, i32 6, i32 7>
819; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i32> [[S]], i64 2
820; ANY-NEXT:    [[E_2:%.*]] = extractelement <3 x i32> [[S]], i64 1
821; ANY-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[E]], [[E_2]]
822; ANY-NEXT:    ret i32 [[R]]
823;
824  %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
825  %e = extractelement <3 x i32> %s, i32 2
826  %e.2 = extractelement <3 x i32> %s, i32 1
827  %r = mul i32 %e, %e.2
828  ret i32 %r
829}
830
831define i32 @extelt_select_const_operand_vector_cond_index(i1 %c) {
832; ANY-LABEL: @extelt_select_const_operand_vector_cond_index(
833; ANY-NEXT:    [[E:%.*]] = select i1 [[C:%.*]], i32 3, i32 4
834; ANY-NEXT:    [[S:%.*]] = select i1 [[C]], <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
835; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i32 [[E]]
836; ANY-NEXT:    ret i32 [[R]]
837;
838  %e = select i1 %c, i32 3, i32 4
839  %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
840  %r = extractelement <3 x i32> %s, i32 %e
841  ret i32 %r
842}
843
844define i32 @extelt_select_const_operand_vector_var_index(i1 %c, i32 %e) {
845; ANY-LABEL: @extelt_select_const_operand_vector_var_index(
846; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
847; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i32 [[E:%.*]]
848; ANY-NEXT:    ret i32 [[R]]
849;
850  %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
851  %r = extractelement <3 x i32> %s, i32 %e
852  ret i32 %r
853}
854
855define i32 @extelt_select_var_const_operand_vector(i1 %c, <3 x i32> %v) {
856; ANY-LABEL: @extelt_select_var_const_operand_vector(
857; ANY-NEXT:    [[TMP1:%.*]] = extractelement <3 x i32> [[V:%.*]], i64 1
858; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 6
859; ANY-NEXT:    ret i32 [[R]]
860;
861  %s = select i1 %c, <3 x i32> %v, <3 x i32> <i32 5, i32 6, i32 7>
862  %r = extractelement <3 x i32> %s, i32 1
863  ret i32 %r
864}
865
866define i32 @extelt_select_const_var_operand_vector(i1 %c, <3 x i32> %v) {
867; ANY-LABEL: @extelt_select_const_var_operand_vector(
868; ANY-NEXT:    [[TMP1:%.*]] = extractelement <3 x i32> [[V:%.*]], i64 0
869; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i32 5, i32 [[TMP1]]
870; ANY-NEXT:    ret i32 [[R]]
871;
872  %s = select i1 %c, <3 x i32> <i32 5, i32 6, i32 7>, <3 x i32> %v
873  %r = extractelement <3 x i32> %s, i32 0
874  ret i32 %r
875}
876
877declare void @use_select(<3 x i32>)
878
879define i32 @extelt_select_const_var_operands_vector_extra_use(i1 %c, <3 x i32> %x) {
880; ANY-LABEL: @extelt_select_const_var_operands_vector_extra_use(
881; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> [[X:%.*]]
882; ANY-NEXT:    call void @use_select(<3 x i32> [[S]])
883; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i64 0
884; ANY-NEXT:    ret i32 [[R]]
885;
886  %s = select i1 %c, <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> %x
887  call void @use_select(<3 x i32> %s)
888  %r = extractelement <3 x i32> %s, i64 0
889  ret i32 %r
890}
891
892define i32 @extelt_select_const_operands_vector_extra_use_2(i1 %c) {
893; ANY-LABEL: @extelt_select_const_operands_vector_extra_use_2(
894; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
895; ANY-NEXT:    call void @use_select(<3 x i32> [[S]])
896; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i64 0
897; ANY-NEXT:    ret i32 [[R]]
898;
899  %s = select i1 %c, <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
900  call void @use_select(<3 x i32> %s)
901  %r = extractelement <3 x i32> %s, i64 0
902  ret i32 %r
903}
904
905define float @crash_4b8320(<2 x float> %i1, float %i12) {
906; ANY-LABEL: @crash_4b8320(
907; ANY-NEXT:    [[I6:%.*]] = fmul reassoc <2 x float> [[I1:%.*]], <float 0.000000e+00, float poison>
908; ANY-NEXT:    [[TMP1:%.*]] = extractelement <2 x float> [[I6]], i64 0
909; ANY-NEXT:    [[TMP2:%.*]] = extractelement <2 x float> [[I6]], i64 0
910; ANY-NEXT:    [[TMP3:%.*]] = fadd float [[TMP1]], [[TMP2]]
911; ANY-NEXT:    [[I29:%.*]] = fadd float [[TMP3]], 0.000000e+00
912; ANY-NEXT:    ret float [[I29]]
913;
914  %i5 = fmul <2 x float> zeroinitializer, %i1
915  %i6 = fmul reassoc <2 x float> zeroinitializer, %i5
916  %i147 = extractelement <2 x float> %i6, i64 0
917  %i15 = extractelement <2 x float> %i6, i64 0
918  %i16 = insertelement <4 x float> zeroinitializer, float %i147, i64 0
919  %i17 = insertelement <4 x float> %i16, float %i15, i64 1
920  %i18 = insertelement <4 x float> %i17, float %i12, i64 2
921  %i19 = shufflevector <4 x float> %i18, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
922  %i23 = fadd <4 x float> %i19, %i18
923  %i24 = shufflevector <4 x float> %i18, <4 x float> zeroinitializer, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
924  %i26 = fadd <4 x float> %i23, %i24
925  %i29 = extractelement <4 x float> %i26, i64 0
926  ret float %i29
927}
928