[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / extractelement.ll
blob2bd719e23613791db54b7930ed0c731576df72b7
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
7 define i32 @extractelement_out_of_range(<2 x i32> %x) {
8 ; ANY-LABEL: @extractelement_out_of_range(
9 ; ANY-NEXT:    ret i32 poison
11   %E1 = extractelement <2 x i32> %x, i8 16
12   ret i32 %E1
15 define i32 @extractelement_type_out_of_range(<2 x i32> %x) {
16 ; ANY-LABEL: @extractelement_type_out_of_range(
17 ; ANY-NEXT:    [[E1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
18 ; ANY-NEXT:    ret i32 [[E1]]
20   %E1 = extractelement <2 x i32> %x, i128 0
21   ret i32 %E1
24 define i32 @bitcasted_inselt_equal_num_elts(float %f) {
25 ; ANY-LABEL: @bitcasted_inselt_equal_num_elts(
26 ; ANY-NEXT:    [[R:%.*]] = bitcast float [[F:%.*]] to i32
27 ; ANY-NEXT:    ret i32 [[R]]
29   %vf = insertelement <4 x float> undef, float %f, i32 0
30   %vi = bitcast <4 x float> %vf to <4 x i32>
31   %r = extractelement <4 x i32> %vi, i32 0
32   ret i32 %r
35 define i64 @test2(i64 %in) {
36 ; ANY-LABEL: @test2(
37 ; ANY-NEXT:    ret i64 [[IN:%.*]]
39   %vec = insertelement <8 x i64> undef, i64 %in, i32 0
40   %splat = shufflevector <8 x i64> %vec, <8 x i64> undef, <8 x i32> zeroinitializer
41   %add = add <8 x i64> %splat, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
42   %r = extractelement <8 x i64> %add, i32 0
43   ret i64 %r
46 define i32 @bitcasted_inselt_wide_source_zero_elt(i64 %x) {
47 ; ANYLE-LABEL: @bitcasted_inselt_wide_source_zero_elt(
48 ; ANYLE-NEXT:    [[R:%.*]] = trunc i64 [[X:%.*]] to i32
49 ; ANYLE-NEXT:    ret i32 [[R]]
51 ; ANYBE-LABEL: @bitcasted_inselt_wide_source_zero_elt(
52 ; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32
53 ; ANYBE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP1]] to i32
54 ; ANYBE-NEXT:    ret i32 [[R]]
56   %i = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
57   %b = bitcast <2 x i64> %i to <4 x i32>
58   %r = extractelement <4 x i32> %b, i32 0
59   ret i32 %r
62 define i16 @bitcasted_inselt_wide_source_modulo_elt(i64 %x) {
63 ; ANYLE-LABEL: @bitcasted_inselt_wide_source_modulo_elt(
64 ; ANYLE-NEXT:    [[R:%.*]] = trunc i64 [[X:%.*]] to i16
65 ; ANYLE-NEXT:    ret i16 [[R]]
67 ; ANYBE-LABEL: @bitcasted_inselt_wide_source_modulo_elt(
68 ; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 48
69 ; ANYBE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP1]] to i16
70 ; ANYBE-NEXT:    ret i16 [[R]]
72   %i = insertelement <2 x i64> undef, i64 %x, i32 1
73   %b = bitcast <2 x i64> %i to <8 x i16>
74   %r = extractelement <8 x i16> %b, i32 4
75   ret i16 %r
78 define i32 @bitcasted_inselt_wide_source_not_modulo_elt(i64 %x) {
79 ; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt(
80 ; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32
81 ; ANYLE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP1]] to i32
82 ; ANYLE-NEXT:    ret i32 [[R]]
84 ; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt(
85 ; ANYBE-NEXT:    [[R:%.*]] = trunc i64 [[X:%.*]] to i32
86 ; ANYBE-NEXT:    ret i32 [[R]]
88   %i = insertelement <2 x i64> undef, i64 %x, i32 0
89   %b = bitcast <2 x i64> %i to <4 x i32>
90   %r = extractelement <4 x i32> %b, i32 1
91   ret i32 %r
94 define i8 @bitcasted_inselt_wide_source_not_modulo_elt_not_half(i32 %x) {
95 ; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half(
96 ; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16
97 ; ANYLE-NEXT:    [[R:%.*]] = trunc i32 [[TMP1]] to i8
98 ; ANYLE-NEXT:    ret i8 [[R]]
100 ; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half(
101 ; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
102 ; ANYBE-NEXT:    [[R:%.*]] = trunc i32 [[TMP1]] to i8
103 ; ANYBE-NEXT:    ret i8 [[R]]
105   %i = insertelement <2 x i32> undef, i32 %x, i32 0
106   %b = bitcast <2 x i32> %i to <8 x i8>
107   %r = extractelement <8 x i8> %b, i32 2
108   ret i8 %r
111 define i3 @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(i15 %x) {
112 ; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(
113 ; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i15 [[X:%.*]], 3
114 ; ANYLE-NEXT:    [[R:%.*]] = trunc i15 [[TMP1]] to i3
115 ; ANYLE-NEXT:    ret i3 [[R]]
117 ; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(
118 ; ANYBE-NEXT:    [[TMP1:%.*]] = lshr i15 [[X:%.*]], 9
119 ; ANYBE-NEXT:    [[R:%.*]] = trunc i15 [[TMP1]] to i3
120 ; ANYBE-NEXT:    ret i3 [[R]]
122   %i = insertelement <3 x i15> undef, i15 %x, i32 0
123   %b = bitcast <3 x i15> %i to <15 x i3>
124   %r = extractelement <15 x i3> %b, i32 1
125   ret i3 %r
128 ; Negative test for the above fold, but we can remove the insert here.
130 define i8 @bitcasted_inselt_wide_source_wrong_insert(<2 x i32> %v, i32 %x) {
131 ; ANY-LABEL: @bitcasted_inselt_wide_source_wrong_insert(
132 ; ANY-NEXT:    [[TMP1:%.*]] = bitcast <2 x i32> [[V:%.*]] to <8 x i8>
133 ; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i8> [[TMP1]], i64 2
134 ; ANY-NEXT:    ret i8 [[R]]
136   %i = insertelement <2 x i32> %v, i32 %x, i32 1
137   %b = bitcast <2 x i32> %i to <8 x i8>
138   %r = extractelement <8 x i8> %b, i32 2
139   ret i8 %r
142 ; Partial negative test for the above fold, extra uses are not allowed if shift is needed.
144 declare void @use(<8 x i8>)
146 define i8 @bitcasted_inselt_wide_source_uses(i32 %x) {
147 ; ANYLE-LABEL: @bitcasted_inselt_wide_source_uses(
148 ; ANYLE-NEXT:    [[I:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 0
149 ; ANYLE-NEXT:    [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8>
150 ; ANYLE-NEXT:    call void @use(<8 x i8> [[B]])
151 ; ANYLE-NEXT:    [[R:%.*]] = extractelement <8 x i8> [[B]], i64 3
152 ; ANYLE-NEXT:    ret i8 [[R]]
154 ; ANYBE-LABEL: @bitcasted_inselt_wide_source_uses(
155 ; ANYBE-NEXT:    [[I:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 0
156 ; ANYBE-NEXT:    [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8>
157 ; ANYBE-NEXT:    call void @use(<8 x i8> [[B]])
158 ; ANYBE-NEXT:    [[R:%.*]] = trunc i32 [[X]] to i8
159 ; ANYBE-NEXT:    ret i8 [[R]]
161   %i = insertelement <2 x i32> undef, i32 %x, i32 0
162   %b = bitcast <2 x i32> %i to <8 x i8>
163   call void @use(<8 x i8> %b)
164   %r = extractelement <8 x i8> %b, i32 3
165   ret i8 %r
168 define float @bitcasted_inselt_to_FP(i64 %x) {
169 ; ANYLE-LABEL: @bitcasted_inselt_to_FP(
170 ; ANYLE-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32
171 ; ANYLE-NEXT:    [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32
172 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP2]] to float
173 ; ANYLE-NEXT:    ret float [[R]]
175 ; ANYBE-LABEL: @bitcasted_inselt_to_FP(
176 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
177 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
178 ; ANYBE-NEXT:    ret float [[R]]
180   %i = insertelement <2 x i64> undef, i64 %x, i32 0
181   %b = bitcast <2 x i64> %i to <4 x float>
182   %r = extractelement <4 x float> %b, i32 1
183   ret float %r
186 declare void @use_v2i128(<2 x i128>)
187 declare void @use_v8f32(<8 x float>)
189 define float @bitcasted_inselt_to_FP_uses(i128 %x) {
190 ; ANY-LABEL: @bitcasted_inselt_to_FP_uses(
191 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x i128> <i128 poison, i128 undef>, i128 [[X:%.*]], i64 0
192 ; ANY-NEXT:    call void @use_v2i128(<2 x i128> [[I]])
193 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x i128> [[I]] to <8 x float>
194 ; ANY-NEXT:    [[R:%.*]] = extractelement <8 x float> [[B]], i64 1
195 ; ANY-NEXT:    ret float [[R]]
197   %i = insertelement <2 x i128> undef, i128 %x, i32 0
198   call void @use_v2i128(<2 x i128> %i)
199   %b = bitcast <2 x i128> %i to <8 x float>
200   %r = extractelement <8 x float> %b, i32 1
201   ret float %r
204 define float @bitcasted_inselt_to_FP_uses2(i128 %x) {
205 ; ANY-LABEL: @bitcasted_inselt_to_FP_uses2(
206 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x i128> <i128 poison, i128 undef>, i128 [[X:%.*]], i64 0
207 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x i128> [[I]] to <8 x float>
208 ; ANY-NEXT:    call void @use_v8f32(<8 x float> [[B]])
209 ; ANY-NEXT:    [[R:%.*]] = extractelement <8 x float> [[B]], i64 1
210 ; ANY-NEXT:    ret float [[R]]
212   %i = insertelement <2 x i128> undef, i128 %x, i32 0
213   %b = bitcast <2 x i128> %i to <8 x float>
214   call void @use_v8f32(<8 x float> %b)
215   %r = extractelement <8 x float> %b, i32 1
216   ret float %r
219 define i32 @bitcasted_inselt_from_FP(double %x) {
220 ; ANYLE-LABEL: @bitcasted_inselt_from_FP(
221 ; ANYLE-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
222 ; ANYLE-NEXT:    [[TMP2:%.*]] = lshr i64 [[TMP1]], 32
223 ; ANYLE-NEXT:    [[R:%.*]] = trunc nuw i64 [[TMP2]] to i32
224 ; ANYLE-NEXT:    ret i32 [[R]]
226 ; ANYBE-LABEL: @bitcasted_inselt_from_FP(
227 ; ANYBE-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
228 ; ANYBE-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
229 ; ANYBE-NEXT:    ret i32 [[R]]
231   %i = insertelement <2 x double> undef, double %x, i32 0
232   %b = bitcast <2 x double> %i to <4 x i32>
233   %r = extractelement <4 x i32> %b, i32 1
234   ret i32 %r
237 declare void @use_v2f64(<2 x double>)
238 declare void @use_v8i16(<8 x i16>)
240 define i16 @bitcasted_inselt_from_FP_uses(double %x) {
241 ; ANY-LABEL: @bitcasted_inselt_from_FP_uses(
242 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
243 ; ANY-NEXT:    call void @use_v2f64(<2 x double> [[I]])
244 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <8 x i16>
245 ; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i16> [[B]], i64 1
246 ; ANY-NEXT:    ret i16 [[R]]
248   %i = insertelement <2 x double> undef, double %x, i32 0
249   call void @use_v2f64(<2 x double> %i)
250   %b = bitcast <2 x double> %i to <8 x i16>
251   %r = extractelement <8 x i16> %b, i32 1
252   ret i16 %r
255 define i16 @bitcasted_inselt_from_FP_uses2(double %x) {
256 ; ANY-LABEL: @bitcasted_inselt_from_FP_uses2(
257 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
258 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <8 x i16>
259 ; ANY-NEXT:    call void @use_v8i16(<8 x i16> [[B]])
260 ; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i16> [[B]], i64 1
261 ; ANY-NEXT:    ret i16 [[R]]
263   %i = insertelement <2 x double> undef, double %x, i32 0
264   %b = bitcast <2 x double> %i to <8 x i16>
265   call void @use_v8i16(<8 x i16> %b)
266   %r = extractelement <8 x i16> %b, i32 1
267   ret i16 %r
270 define float @bitcasted_inselt_to_and_from_FP(double %x) {
271 ; ANY-LABEL: @bitcasted_inselt_to_and_from_FP(
272 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> poison, double [[X:%.*]], i64 0
273 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <4 x float>
274 ; ANY-NEXT:    [[R:%.*]] = extractelement <4 x float> [[B]], i64 1
275 ; ANY-NEXT:    ret float [[R]]
277   %i = insertelement <2 x double> undef, double %x, i32 0
278   %b = bitcast <2 x double> %i to <4 x float>
279   %r = extractelement <4 x float> %b, i32 1
280   ret float %r
283 define float @bitcasted_inselt_to_and_from_FP_uses(double %x) {
284 ; ANY-LABEL: @bitcasted_inselt_to_and_from_FP_uses(
285 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
286 ; ANY-NEXT:    call void @use_v2f64(<2 x double> [[I]])
287 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <4 x float>
288 ; ANY-NEXT:    [[R:%.*]] = extractelement <4 x float> [[B]], i64 1
289 ; ANY-NEXT:    ret float [[R]]
291   %i = insertelement <2 x double> undef, double %x, i32 0
292   call void @use_v2f64(<2 x double> %i)
293   %b = bitcast <2 x double> %i to <4 x float>
294   %r = extractelement <4 x float> %b, i32 1
295   ret float %r
298 declare void @use_v4f32(<4 x float>)
300 define float @bitcasted_inselt_to_and_from_FP_uses2(double %x) {
301 ; ANY-LABEL: @bitcasted_inselt_to_and_from_FP_uses2(
302 ; ANY-NEXT:    [[I:%.*]] = insertelement <2 x double> <double poison, double undef>, double [[X:%.*]], i64 0
303 ; ANY-NEXT:    [[B:%.*]] = bitcast <2 x double> [[I]] to <4 x float>
304 ; ANY-NEXT:    call void @use_v4f32(<4 x float> [[B]])
305 ; ANY-NEXT:    [[R:%.*]] = extractelement <4 x float> [[B]], i64 1
306 ; ANY-NEXT:    ret float [[R]]
308   %i = insertelement <2 x double> undef, double %x, i32 0
309   %b = bitcast <2 x double> %i to <4 x float>
310   call void @use_v4f32(<4 x float> %b)
311   %r = extractelement <4 x float> %b, i32 1
312   ret float %r
315 ; This would crash/assert because the logic for collectShuffleElements()
316 ; does not consider the possibility of invalid insert/extract operands.
318 define <4 x double> @invalid_extractelement(<2 x double> %a, <4 x double> %b, ptr %p) {
319 ; ANY-LABEL: @invalid_extractelement(
320 ; ANY-NEXT:    [[TMP1:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
321 ; ANY-NEXT:    [[T4:%.*]] = shufflevector <4 x double> [[B:%.*]], <4 x double> [[TMP1]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
322 ; ANY-NEXT:    [[E:%.*]] = extractelement <4 x double> [[B]], i64 1
323 ; ANY-NEXT:    store double [[E]], ptr [[P:%.*]], align 8
324 ; ANY-NEXT:    ret <4 x double> [[T4]]
326   %t3 = extractelement <2 x double> %a, i32 0
327   %t4 = insertelement <4 x double> %b, double %t3, i32 2
328   %e = extractelement <4 x double> %t4, i32 1
329   store double %e, ptr %p
330   %e1 = extractelement <2 x double> %a, i32 4 ; invalid index
331   %r = insertelement <4 x double> %t4, double %e1, i64 0
332   ret <4 x double> %r
335 ; i32 is a desirable/supported type independent of data layout.
337 define i8 @bitcast_scalar_supported_type_index0(i32 %x) {
338 ; ANYLE-LABEL: @bitcast_scalar_supported_type_index0(
339 ; ANYLE-NEXT:    [[R:%.*]] = trunc i32 [[X:%.*]] to i8
340 ; ANYLE-NEXT:    ret i8 [[R]]
342 ; ANYBE-LABEL: @bitcast_scalar_supported_type_index0(
343 ; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 24
344 ; ANYBE-NEXT:    [[R:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i8
345 ; ANYBE-NEXT:    ret i8 [[R]]
347   %v = bitcast i32 %x to <4 x i8>
348   %r = extractelement <4 x i8> %v, i8 0
349   ret i8 %r
352 define i8 @bitcast_scalar_supported_type_index2(i32 %x) {
353 ; ANYLE-LABEL: @bitcast_scalar_supported_type_index2(
354 ; ANYLE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
355 ; ANYLE-NEXT:    [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8
356 ; ANYLE-NEXT:    ret i8 [[R]]
358 ; ANYBE-LABEL: @bitcast_scalar_supported_type_index2(
359 ; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 8
360 ; ANYBE-NEXT:    [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8
361 ; ANYBE-NEXT:    ret i8 [[R]]
363   %v = bitcast i32 %x to <4 x i8>
364   %r = extractelement <4 x i8> %v, i64 2
365   ret i8 %r
368 ; i64 is legal based on data layout.
370 define i4 @bitcast_scalar_legal_type_index3(i64 %x) {
371 ; LE64-LABEL: @bitcast_scalar_legal_type_index3(
372 ; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 12
373 ; LE64-NEXT:    [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4
374 ; LE64-NEXT:    ret i4 [[R]]
376 ; LE128-LABEL: @bitcast_scalar_legal_type_index3(
377 ; LE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <16 x i4>
378 ; LE128-NEXT:    [[R:%.*]] = extractelement <16 x i4> [[V]], i64 3
379 ; LE128-NEXT:    ret i4 [[R]]
381 ; BE64-LABEL: @bitcast_scalar_legal_type_index3(
382 ; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 48
383 ; BE64-NEXT:    [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4
384 ; BE64-NEXT:    ret i4 [[R]]
386 ; BE128-LABEL: @bitcast_scalar_legal_type_index3(
387 ; BE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <16 x i4>
388 ; BE128-NEXT:    [[R:%.*]] = extractelement <16 x i4> [[V]], i64 3
389 ; BE128-NEXT:    ret i4 [[R]]
392   %v = bitcast i64 %x to <16 x i4>
393   %r = extractelement <16 x i4> %v, i64 3
394   ret i4 %r
397 ; negative test - don't create a shift for an illegal type.
399 define i8 @bitcast_scalar_illegal_type_index1(i128 %x) {
400 ; LE64-LABEL: @bitcast_scalar_illegal_type_index1(
401 ; LE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8>
402 ; LE64-NEXT:    [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1
403 ; LE64-NEXT:    ret i8 [[R]]
405 ; LE128-LABEL: @bitcast_scalar_illegal_type_index1(
406 ; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 8
407 ; LE128-NEXT:    [[R:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i8
408 ; LE128-NEXT:    ret i8 [[R]]
410 ; BE64-LABEL: @bitcast_scalar_illegal_type_index1(
411 ; BE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8>
412 ; BE64-NEXT:    [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1
413 ; BE64-NEXT:    ret i8 [[R]]
415 ; BE128-LABEL: @bitcast_scalar_illegal_type_index1(
416 ; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 112
417 ; BE128-NEXT:    [[R:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i8
418 ; BE128-NEXT:    ret i8 [[R]]
420   %v = bitcast i128 %x to <16 x i8>
421   %r = extractelement <16 x i8> %v, i64 1
422   ret i8 %r
425 ; negative test - can't use shift/trunc on FP
427 define i8 @bitcast_fp_index0(float %x) {
428 ; ANY-LABEL: @bitcast_fp_index0(
429 ; ANY-NEXT:    [[V:%.*]] = bitcast float [[X:%.*]] to <4 x i8>
430 ; ANY-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[V]], i64 0
431 ; ANY-NEXT:    ret i8 [[R]]
433   %v = bitcast float %x to <4 x i8>
434   %r = extractelement <4 x i8> %v, i8 0
435   ret i8 %r
438 define half @bitcast_fp16vec_index0(i32 %x) {
439 ; ANYLE-LABEL: @bitcast_fp16vec_index0(
440 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
441 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
442 ; ANYLE-NEXT:    ret half [[R]]
444 ; ANYBE-LABEL: @bitcast_fp16vec_index0(
445 ; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
446 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
447 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
448 ; ANYBE-NEXT:    ret half [[R]]
450   %v = bitcast i32 %x to <2 x half>
451   %r = extractelement <2 x half> %v, i8 0
452   ret half %r
455 define half @bitcast_fp16vec_index1(i32 %x) {
456 ; ANYLE-LABEL: @bitcast_fp16vec_index1(
457 ; ANYLE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
458 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
459 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
460 ; ANYLE-NEXT:    ret half [[R]]
462 ; ANYBE-LABEL: @bitcast_fp16vec_index1(
463 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
464 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
465 ; ANYBE-NEXT:    ret half [[R]]
467   %v = bitcast i32 %x to <2 x half>
468   %r = extractelement <2 x half> %v, i8 1
469   ret half %r
472 define bfloat @bitcast_bfp16vec_index0(i32 %x) {
473 ; ANYLE-LABEL: @bitcast_bfp16vec_index0(
474 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
475 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
476 ; ANYLE-NEXT:    ret bfloat [[R]]
478 ; ANYBE-LABEL: @bitcast_bfp16vec_index0(
479 ; ANYBE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
480 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
481 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
482 ; ANYBE-NEXT:    ret bfloat [[R]]
484   %v = bitcast i32 %x to <2 x bfloat>
485   %r = extractelement <2 x bfloat> %v, i8 0
486   ret bfloat %r
489 define bfloat @bitcast_bfp16vec_index1(i32 %x) {
490 ; ANYLE-LABEL: @bitcast_bfp16vec_index1(
491 ; ANYLE-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
492 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
493 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
494 ; ANYLE-NEXT:    ret bfloat [[R]]
496 ; ANYBE-LABEL: @bitcast_bfp16vec_index1(
497 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
498 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
499 ; ANYBE-NEXT:    ret bfloat [[R]]
501   %v = bitcast i32 %x to <2 x bfloat>
502   %r = extractelement <2 x bfloat> %v, i8 1
503   ret bfloat %r
506 define float @bitcast_fp32vec_index0(i64 %x) {
507 ; ANYLE-LABEL: @bitcast_fp32vec_index0(
508 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
509 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
510 ; ANYLE-NEXT:    ret float [[R]]
512 ; BE64-LABEL: @bitcast_fp32vec_index0(
513 ; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
514 ; BE64-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i32
515 ; BE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
516 ; BE64-NEXT:    ret float [[R]]
518 ; BE128-LABEL: @bitcast_fp32vec_index0(
519 ; BE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
520 ; BE128-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 0
521 ; BE128-NEXT:    ret float [[R]]
523   %v = bitcast i64 %x to <2 x float>
524   %r = extractelement <2 x float> %v, i8 0
525   ret float %r
528 define float @bitcast_fp32vec_index1(i64 %x) {
529 ; LE64-LABEL: @bitcast_fp32vec_index1(
530 ; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
531 ; LE64-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i32
532 ; LE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
533 ; LE64-NEXT:    ret float [[R]]
535 ; LE128-LABEL: @bitcast_fp32vec_index1(
536 ; LE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
537 ; LE128-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 1
538 ; LE128-NEXT:    ret float [[R]]
540 ; ANYBE-LABEL: @bitcast_fp32vec_index1(
541 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
542 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
543 ; ANYBE-NEXT:    ret float [[R]]
545   %v = bitcast i64 %x to <2 x float>
546   %r = extractelement <2 x float> %v, i8 1
547   ret float %r
550 define double @bitcast_fp64vec64_index0(i64 %x) {
551 ; ANY-LABEL: @bitcast_fp64vec64_index0(
552 ; ANY-NEXT:    [[R:%.*]] = bitcast i64 [[X:%.*]] to double
553 ; ANY-NEXT:    ret double [[R]]
555   %v = bitcast i64 %x to <1 x double>
556   %r = extractelement <1 x double> %v, i8 0
557   ret double %r
560 define double @bitcast_fp64vec_index0(i128 %x) {
561 ; ANYLE-LABEL: @bitcast_fp64vec_index0(
562 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
563 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
564 ; ANYLE-NEXT:    ret double [[R]]
566 ; BE64-LABEL: @bitcast_fp64vec_index0(
567 ; BE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
568 ; BE64-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 0
569 ; BE64-NEXT:    ret double [[R]]
571 ; BE128-LABEL: @bitcast_fp64vec_index0(
572 ; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 64
573 ; BE128-NEXT:    [[TMP1:%.*]] = trunc nuw i128 [[EXTELT_OFFSET]] to i64
574 ; BE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
575 ; BE128-NEXT:    ret double [[R]]
577   %v = bitcast i128 %x to <2 x double>
578   %r = extractelement <2 x double> %v, i8 0
579   ret double %r
582 define double @bitcast_fp64vec_index1(i128 %x) {
583 ; LE64-LABEL: @bitcast_fp64vec_index1(
584 ; LE64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
585 ; LE64-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 1
586 ; LE64-NEXT:    ret double [[R]]
588 ; LE128-LABEL: @bitcast_fp64vec_index1(
589 ; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 64
590 ; LE128-NEXT:    [[TMP1:%.*]] = trunc nuw i128 [[EXTELT_OFFSET]] to i64
591 ; LE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
592 ; LE128-NEXT:    ret double [[R]]
594 ; ANYBE-LABEL: @bitcast_fp64vec_index1(
595 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
596 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
597 ; ANYBE-NEXT:    ret double [[R]]
599   %v = bitcast i128 %x to <2 x double>
600   %r = extractelement <2 x double> %v, i8 1
601   ret double %r
604 ; negative test - input integer should be legal
606 define x86_fp80 @bitcast_x86fp80vec_index0(i160 %x) {
607 ; ANYLE-LABEL: @bitcast_x86fp80vec_index0(
608 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i160 [[X:%.*]] to i80
609 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i80 [[TMP1]] to x86_fp80
610 ; ANYLE-NEXT:    ret x86_fp80 [[R]]
612 ; ANYBE-LABEL: @bitcast_x86fp80vec_index0(
613 ; ANYBE-NEXT:    [[V:%.*]] = bitcast i160 [[X:%.*]] to <2 x x86_fp80>
614 ; ANYBE-NEXT:    [[R:%.*]] = extractelement <2 x x86_fp80> [[V]], i64 0
615 ; ANYBE-NEXT:    ret x86_fp80 [[R]]
617   %v = bitcast i160 %x to <2 x x86_fp80>
618   %r = extractelement <2 x x86_fp80> %v, i8 0
619   ret x86_fp80 %r
622 ; negative test - input integer should be legal
624 define x86_fp80 @bitcast_x86fp80vec_index1(i160 %x) {
625 ; ANYLE-LABEL: @bitcast_x86fp80vec_index1(
626 ; ANYLE-NEXT:    [[V:%.*]] = bitcast i160 [[X:%.*]] to <2 x x86_fp80>
627 ; ANYLE-NEXT:    [[R:%.*]] = extractelement <2 x x86_fp80> [[V]], i64 1
628 ; ANYLE-NEXT:    ret x86_fp80 [[R]]
630 ; ANYBE-LABEL: @bitcast_x86fp80vec_index1(
631 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i160 [[X:%.*]] to i80
632 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i80 [[TMP1]] to x86_fp80
633 ; ANYBE-NEXT:    ret x86_fp80 [[R]]
635   %v = bitcast i160 %x to <2 x x86_fp80>
636   %r = extractelement <2 x x86_fp80> %v, i8 1
637   ret x86_fp80 %r
640 ; negative test - input integer should be legal
642 define fp128 @bitcast_fp128vec_index0(i256 %x) {
643 ; ANYLE-LABEL: @bitcast_fp128vec_index0(
644 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
645 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to fp128
646 ; ANYLE-NEXT:    ret fp128 [[R]]
648 ; ANYBE-LABEL: @bitcast_fp128vec_index0(
649 ; ANYBE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x fp128>
650 ; ANYBE-NEXT:    [[R:%.*]] = extractelement <2 x fp128> [[V]], i64 0
651 ; ANYBE-NEXT:    ret fp128 [[R]]
653   %v = bitcast i256 %x to <2 x fp128>
654   %r = extractelement <2 x fp128> %v, i8 0
655   ret fp128 %r
658 ; negative test - input integer should be legal
660 define fp128 @bitcast_fp128vec_index1(i256 %x) {
661 ; ANYLE-LABEL: @bitcast_fp128vec_index1(
662 ; ANYLE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x fp128>
663 ; ANYLE-NEXT:    [[R:%.*]] = extractelement <2 x fp128> [[V]], i64 1
664 ; ANYLE-NEXT:    ret fp128 [[R]]
666 ; ANYBE-LABEL: @bitcast_fp128vec_index1(
667 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
668 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to fp128
669 ; ANYBE-NEXT:    ret fp128 [[R]]
671   %v = bitcast i256 %x to <2 x fp128>
672   %r = extractelement <2 x fp128> %v, i8 1
673   ret fp128 %r
676 ; negative test - input integer should be legal
678 define ppc_fp128 @bitcast_ppcfp128vec_index0(i256 %x) {
679 ; ANYLE-LABEL: @bitcast_ppcfp128vec_index0(
680 ; ANYLE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
681 ; ANYLE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to ppc_fp128
682 ; ANYLE-NEXT:    ret ppc_fp128 [[R]]
684 ; ANYBE-LABEL: @bitcast_ppcfp128vec_index0(
685 ; ANYBE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x ppc_fp128>
686 ; ANYBE-NEXT:    [[R:%.*]] = extractelement <2 x ppc_fp128> [[V]], i64 0
687 ; ANYBE-NEXT:    ret ppc_fp128 [[R]]
689   %v = bitcast i256 %x to <2 x ppc_fp128>
690   %r = extractelement <2 x ppc_fp128> %v, i8 0
691   ret ppc_fp128 %r
694 ; negative test -input integer should be legal
696 define ppc_fp128 @bitcast_ppcfp128vec_index1(i256 %x) {
697 ; ANYLE-LABEL: @bitcast_ppcfp128vec_index1(
698 ; ANYLE-NEXT:    [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x ppc_fp128>
699 ; ANYLE-NEXT:    [[R:%.*]] = extractelement <2 x ppc_fp128> [[V]], i64 1
700 ; ANYLE-NEXT:    ret ppc_fp128 [[R]]
702 ; ANYBE-LABEL: @bitcast_ppcfp128vec_index1(
703 ; ANYBE-NEXT:    [[TMP1:%.*]] = trunc i256 [[X:%.*]] to i128
704 ; ANYBE-NEXT:    [[R:%.*]] = bitcast i128 [[TMP1]] to ppc_fp128
705 ; ANYBE-NEXT:    ret ppc_fp128 [[R]]
707   %v = bitcast i256 %x to <2 x ppc_fp128>
708   %r = extractelement <2 x ppc_fp128> %v, i8 1
709   ret ppc_fp128 %r
712 ; negative test - input integer should be legal
714 define i8 @bitcast_scalar_index_variable(i32 %x, i64 %y) {
715 ; ANY-LABEL: @bitcast_scalar_index_variable(
716 ; ANY-NEXT:    [[V:%.*]] = bitcast i32 [[X:%.*]] to <4 x i8>
717 ; ANY-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[V]], i64 [[Y:%.*]]
718 ; ANY-NEXT:    ret i8 [[R]]
720   %v = bitcast i32 %x to <4 x i8>
721   %r = extractelement <4 x i8> %v, i64 %y
722   ret i8 %r
725 ; extra use is not ok, even if we don't need a shift
727 define i8 @bitcast_scalar_index0_use(i64 %x) {
728 ; ANY-LABEL: @bitcast_scalar_index0_use(
729 ; ANY-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8>
730 ; ANY-NEXT:    call void @use(<8 x i8> [[V]])
731 ; ANY-NEXT:    [[R:%.*]] = extractelement <8 x i8> [[V]], i64 0
732 ; ANY-NEXT:    ret i8 [[R]]
735   %v = bitcast i64 %x to <8 x i8>
736   call void @use(<8 x i8> %v)
737   %r = extractelement <8 x i8> %v, i64 0
738   ret i8 %r
741 define i1 @bit_extract_cmp(i64 %x) {
742 ; LE64-LABEL: @bit_extract_cmp(
743 ; LE64-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 9223372032559808512
744 ; LE64-NEXT:    [[R:%.*]] = icmp eq i64 [[TMP1]], 0
745 ; LE64-NEXT:    ret i1 [[R]]
747 ; LE128-LABEL: @bit_extract_cmp(
748 ; LE128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
749 ; LE128-NEXT:    [[E:%.*]] = extractelement <2 x float> [[V]], i64 1
750 ; LE128-NEXT:    [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
751 ; LE128-NEXT:    ret i1 [[R]]
753 ; ANYBE-LABEL: @bit_extract_cmp(
754 ; ANYBE-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 2147483647
755 ; ANYBE-NEXT:    [[R:%.*]] = icmp eq i64 [[TMP1]], 0
756 ; ANYBE-NEXT:    ret i1 [[R]]
758   %v = bitcast i64 %x to <2 x float>
759   %e = extractelement <2 x float> %v, i8 1
760   %r = fcmp oeq float %e, 0.0
761   ret i1 %r
764 define i32 @extelt_select_const_operand_vector(i1 %c) {
765 ; ANY-LABEL: @extelt_select_const_operand_vector(
766 ; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i32 4, i32 7
767 ; ANY-NEXT:    ret i32 [[R]]
769   %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
770   %r = extractelement <3 x i32> %s, i32 2
771   ret i32 %r
774 define float @extelt_select_const_operand_vector_float(i1 %c) {
775 ; ANY-LABEL: @extelt_select_const_operand_vector_float(
776 ; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], float 4.000000e+00, float 7.000000e+00
777 ; ANY-NEXT:    ret float [[R]]
779   %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>
780   %r = extractelement <3 x float> %s, i32 2
781   ret float %r
784 define i32 @extelt_vecselect_const_operand_vector(<3 x i1> %c) {
785 ; ANY-LABEL: @extelt_vecselect_const_operand_vector(
786 ; 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>
787 ; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i64 2
788 ; ANY-NEXT:    ret i32 [[R]]
790   %s = select <3 x i1> %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
791   %r = extractelement <3 x i32> %s, i32 2
792   ret i32 %r
795 define i32 @extelt_select_const_operand_extractelt_use(i1 %c) {
796 ; ANY-LABEL: @extelt_select_const_operand_extractelt_use(
797 ; ANY-NEXT:    [[E:%.*]] = select i1 [[C:%.*]], i32 4, i32 7
798 ; ANY-NEXT:    [[M:%.*]] = shl nuw nsw i32 [[E]], 1
799 ; ANY-NEXT:    [[M_2:%.*]] = shl nuw nsw i32 [[E]], 2
800 ; ANY-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[M]], [[M_2]]
801 ; ANY-NEXT:    ret i32 [[R]]
803   %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
804   %e = extractelement <3 x i32> %s, i32 2
805   %m = mul i32 %e, 2
806   %m.2 = mul i32 %e, 4
807   %r = mul i32 %m, %m.2
808   ret i32 %r
811 define i32 @extelt_select_const_operand_select_use(i1 %c) {
812 ; ANY-LABEL: @extelt_select_const_operand_select_use(
813 ; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 poison, i32 3, i32 4>, <3 x i32> <i32 poison, i32 6, i32 7>
814 ; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i32> [[S]], i64 2
815 ; ANY-NEXT:    [[E_2:%.*]] = extractelement <3 x i32> [[S]], i64 1
816 ; ANY-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[E]], [[E_2]]
817 ; ANY-NEXT:    ret i32 [[R]]
819   %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
820   %e = extractelement <3 x i32> %s, i32 2
821   %e.2 = extractelement <3 x i32> %s, i32 1
822   %r = mul i32 %e, %e.2
823   ret i32 %r
826 define i32 @extelt_select_const_operand_vector_cond_index(i1 %c) {
827 ; ANY-LABEL: @extelt_select_const_operand_vector_cond_index(
828 ; ANY-NEXT:    [[E:%.*]] = select i1 [[C:%.*]], i32 3, i32 4
829 ; ANY-NEXT:    [[S:%.*]] = select i1 [[C]], <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
830 ; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i32 [[E]]
831 ; ANY-NEXT:    ret i32 [[R]]
833   %e = select i1 %c, i32 3, i32 4
834   %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
835   %r = extractelement <3 x i32> %s, i32 %e
836   ret i32 %r
839 define i32 @extelt_select_const_operand_vector_var_index(i1 %c, i32 %e) {
840 ; ANY-LABEL: @extelt_select_const_operand_vector_var_index(
841 ; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
842 ; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i32 [[E:%.*]]
843 ; ANY-NEXT:    ret i32 [[R]]
845   %s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
846   %r = extractelement <3 x i32> %s, i32 %e
847   ret i32 %r
850 define i32 @extelt_select_var_const_operand_vector(i1 %c, <3 x i32> %v) {
851 ; ANY-LABEL: @extelt_select_var_const_operand_vector(
852 ; ANY-NEXT:    [[TMP1:%.*]] = extractelement <3 x i32> [[V:%.*]], i64 1
853 ; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 6
854 ; ANY-NEXT:    ret i32 [[R]]
856   %s = select i1 %c, <3 x i32> %v, <3 x i32> <i32 5, i32 6, i32 7>
857   %r = extractelement <3 x i32> %s, i32 1
858   ret i32 %r
861 define i32 @extelt_select_const_var_operand_vector(i1 %c, <3 x i32> %v) {
862 ; ANY-LABEL: @extelt_select_const_var_operand_vector(
863 ; ANY-NEXT:    [[TMP1:%.*]] = extractelement <3 x i32> [[V:%.*]], i64 0
864 ; ANY-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i32 5, i32 [[TMP1]]
865 ; ANY-NEXT:    ret i32 [[R]]
867   %s = select i1 %c, <3 x i32> <i32 5, i32 6, i32 7>, <3 x i32> %v
868   %r = extractelement <3 x i32> %s, i32 0
869   ret i32 %r
872 declare void @use_select(<3 x i32>)
874 define i32 @extelt_select_const_var_operands_vector_extra_use(i1 %c, <3 x i32> %x) {
875 ; ANY-LABEL: @extelt_select_const_var_operands_vector_extra_use(
876 ; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> [[X:%.*]]
877 ; ANY-NEXT:    call void @use_select(<3 x i32> [[S]])
878 ; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i64 0
879 ; ANY-NEXT:    ret i32 [[R]]
881   %s = select i1 %c, <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> %x
882   call void @use_select(<3 x i32> %s)
883   %r = extractelement <3 x i32> %s, i64 0
884   ret i32 %r
887 define i32 @extelt_select_const_operands_vector_extra_use_2(i1 %c) {
888 ; ANY-LABEL: @extelt_select_const_operands_vector_extra_use_2(
889 ; ANY-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
890 ; ANY-NEXT:    call void @use_select(<3 x i32> [[S]])
891 ; ANY-NEXT:    [[R:%.*]] = extractelement <3 x i32> [[S]], i64 0
892 ; ANY-NEXT:    ret i32 [[R]]
894   %s = select i1 %c, <3 x i32> <i32 42, i32 5, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
895   call void @use_select(<3 x i32> %s)
896   %r = extractelement <3 x i32> %s, i64 0
897   ret i32 %r
900 define float @crash_4b8320(<2 x float> %i1, float %i12) {
901 ; ANY-LABEL: @crash_4b8320(
902 ; ANY-NEXT:    [[I6:%.*]] = fmul reassoc <2 x float> [[I1:%.*]], <float 0.000000e+00, float poison>
903 ; ANY-NEXT:    [[TMP1:%.*]] = extractelement <2 x float> [[I6]], i64 0
904 ; ANY-NEXT:    [[TMP2:%.*]] = extractelement <2 x float> [[I6]], i64 0
905 ; ANY-NEXT:    [[TMP3:%.*]] = fadd float [[TMP1]], [[TMP2]]
906 ; ANY-NEXT:    [[I29:%.*]] = fadd float [[TMP3]], 0.000000e+00
907 ; ANY-NEXT:    ret float [[I29]]
909   %i5 = fmul <2 x float> zeroinitializer, %i1
910   %i6 = fmul reassoc <2 x float> zeroinitializer, %i5
911   %i147 = extractelement <2 x float> %i6, i64 0
912   %i15 = extractelement <2 x float> %i6, i64 0
913   %i16 = insertelement <4 x float> zeroinitializer, float %i147, i64 0
914   %i17 = insertelement <4 x float> %i16, float %i15, i64 1
915   %i18 = insertelement <4 x float> %i17, float %i12, i64 2
916   %i19 = shufflevector <4 x float> %i18, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
917   %i23 = fadd <4 x float> %i19, %i18
918   %i24 = shufflevector <4 x float> %i18, <4 x float> zeroinitializer, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
919   %i26 = fadd <4 x float> %i23, %i24
920   %i29 = extractelement <4 x float> %i26, i64 0
921   ret float %i29