Reland [OffloadBundler] Compress bundles over 4GB (#122307)
[llvm-project.git] / llvm / test / Transforms / InstCombine / extractelement.ll
blob04a35e19fb0bb562ea5758d8de29b1a318dd7e50
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 ; 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
12 define i32 @extractelement_out_of_range(<2 x i32> %x) {
13 ; ANY-LABEL: @extractelement_out_of_range(
14 ; ANY-NEXT:    ret i32 poison
16   %E1 = extractelement <2 x i32> %x, i8 16
17   ret i32 %E1
20 define 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]]
25   %E1 = extractelement <2 x i32> %x, i128 0
26   ret i32 %E1
29 define 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]]
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
40 define i64 @test2(i64 %in) {
41 ; ANY-LABEL: @test2(
42 ; ANY-NEXT:    ret i64 [[IN:%.*]]
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
51 define 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]]
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]]
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
67 define 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]]
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]]
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
83 define 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]]
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]]
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
99 define 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]]
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]]
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
116 define 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]]
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]]
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
133 ; Negative test for the above fold, but we can remove the insert here.
135 define 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]]
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
147 ; Partial negative test for the above fold, extra uses are not allowed if shift is needed.
149 declare void @use(<8 x i8>)
151 define 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]]
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]]
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
173 define 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]]
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]]
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
191 declare void @use_v2i128(<2 x i128>)
192 declare void @use_v8f32(<8 x float>)
194 define 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]]
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
209 define 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]]
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
224 define 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]]
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]]
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
242 declare void @use_v2f64(<2 x double>)
243 declare void @use_v8i16(<8 x i16>)
245 define 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]]
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
260 define 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]]
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
275 define 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]]
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
288 define 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]]
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
303 declare void @use_v4f32(<4 x float>)
305 define 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]]
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
320 ; This would crash/assert because the logic for collectShuffleElements()
321 ; does not consider the possibility of invalid insert/extract operands.
323 define <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]]
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
340 ; i32 is a desirable/supported type independent of data layout.
342 define 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]]
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]]
352   %v = bitcast i32 %x to <4 x i8>
353   %r = extractelement <4 x i8> %v, i8 0
354   ret i8 %r
357 define 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]]
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]]
368   %v = bitcast i32 %x to <4 x i8>
369   %r = extractelement <4 x i8> %v, i64 2
370   ret i8 %r
373 ; i64 is legal based on data layout.
375 define 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]]
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]]
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]]
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]]
397   %v = bitcast i64 %x to <16 x i4>
398   %r = extractelement <16 x i4> %v, i64 3
399   ret i4 %r
402 ; negative test - don't create a shift for an illegal type.
404 define 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]]
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]]
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]]
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]]
425   %v = bitcast i128 %x to <16 x i8>
426   %r = extractelement <16 x i8> %v, i64 1
427   ret i8 %r
430 ; negative test - can't use shift/trunc on FP
432 define 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]]
438   %v = bitcast float %x to <4 x i8>
439   %r = extractelement <4 x i8> %v, i8 0
440   ret i8 %r
443 define 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]]
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]]
455   %v = bitcast i32 %x to <2 x half>
456   %r = extractelement <2 x half> %v, i8 0
457   ret half %r
460 define 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]]
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]]
472   %v = bitcast i32 %x to <2 x half>
473   %r = extractelement <2 x half> %v, i8 1
474   ret half %r
477 define 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]]
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]]
489   %v = bitcast i32 %x to <2 x bfloat>
490   %r = extractelement <2 x bfloat> %v, i8 0
491   ret bfloat %r
494 define 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]]
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]]
506   %v = bitcast i32 %x to <2 x bfloat>
507   %r = extractelement <2 x bfloat> %v, i8 1
508   ret bfloat %r
511 define 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]]
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]]
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]]
528   %v = bitcast i64 %x to <2 x float>
529   %r = extractelement <2 x float> %v, i8 0
530   ret float %r
533 define 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]]
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]]
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]]
550   %v = bitcast i64 %x to <2 x float>
551   %r = extractelement <2 x float> %v, i8 1
552   ret float %r
555 define 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]]
560   %v = bitcast i64 %x to <1 x double>
561   %r = extractelement <1 x double> %v, i8 0
562   ret double %r
565 define 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]]
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]]
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]]
582   %v = bitcast i128 %x to <2 x double>
583   %r = extractelement <2 x double> %v, i8 0
584   ret double %r
587 define 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]]
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]]
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]]
604   %v = bitcast i128 %x to <2 x double>
605   %r = extractelement <2 x double> %v, i8 1
606   ret double %r
609 ; negative test - input integer should be legal
611 define 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]]
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]]
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
627 ; negative test - input integer should be legal
629 define 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]]
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]]
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
645 ; negative test - input integer should be legal
647 define 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]]
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]]
658   %v = bitcast i256 %x to <2 x fp128>
659   %r = extractelement <2 x fp128> %v, i8 0
660   ret fp128 %r
663 ; negative test - input integer should be legal
665 define 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]]
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]]
676   %v = bitcast i256 %x to <2 x fp128>
677   %r = extractelement <2 x fp128> %v, i8 1
678   ret fp128 %r
681 ; negative test - input integer should be legal
683 define 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]]
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]]
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
699 ; negative test -input integer should be legal
701 define 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]]
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]]
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
717 ; negative test - input integer should be legal
719 define 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]]
725   %v = bitcast i32 %x to <4 x i8>
726   %r = extractelement <4 x i8> %v, i64 %y
727   ret i8 %r
730 ; extra use is not ok, even if we don't need a shift
732 define 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]]
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
746 define 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]]
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]]
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]]
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
769 define 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]]
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
779 define 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]]
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
789 define 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]]
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
800 define 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]]
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
816 define 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]]
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
831 define 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]]
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
844 define 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]]
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
855 define 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]]
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
866 define 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]]
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
877 declare void @use_select(<3 x i32>)
879 define 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]]
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
892 define 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]]
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
905 define 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]]
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