1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=ANY,LE
3; RUN: opt < %s -instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=ANY,BE
4
5define i32 @shrinkExtractElt_i64_to_i32_0(<3 x i64> %x) {
6; LE-LABEL: @shrinkExtractElt_i64_to_i32_0(
7; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
8; LE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 0
9; LE-NEXT:    ret i32 [[T]]
10;
11; BE-LABEL: @shrinkExtractElt_i64_to_i32_0(
12; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
13; BE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 1
14; BE-NEXT:    ret i32 [[T]]
15;
16  %e = extractelement <3 x i64> %x, i32 0
17  %t = trunc i64 %e to i32
18  ret i32 %t
19}
20
21define i32 @shrinkExtractElt_i64_to_i32_1(<3 x i64> %x) {
22; LE-LABEL: @shrinkExtractElt_i64_to_i32_1(
23; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
24; LE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 2
25; LE-NEXT:    ret i32 [[T]]
26;
27; BE-LABEL: @shrinkExtractElt_i64_to_i32_1(
28; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
29; BE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 3
30; BE-NEXT:    ret i32 [[T]]
31;
32  %e = extractelement <3 x i64> %x, i32 1
33  %t = trunc i64 %e to i32
34  ret i32 %t
35}
36
37define i32 @shrinkExtractElt_i64_to_i32_2(<3 x i64> %x) {
38; LE-LABEL: @shrinkExtractElt_i64_to_i32_2(
39; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
40; LE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 4
41; LE-NEXT:    ret i32 [[T]]
42;
43; BE-LABEL: @shrinkExtractElt_i64_to_i32_2(
44; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
45; BE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 5
46; BE-NEXT:    ret i32 [[T]]
47;
48  %e = extractelement <3 x i64> %x, i32 2
49  %t = trunc i64 %e to i32
50  ret i32 %t
51}
52
53define i16 @shrinkExtractElt_i64_to_i16_0(<3 x i64> %x) {
54; LE-LABEL: @shrinkExtractElt_i64_to_i16_0(
55; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
56; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 0
57; LE-NEXT:    ret i16 [[T]]
58;
59; BE-LABEL: @shrinkExtractElt_i64_to_i16_0(
60; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
61; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 3
62; BE-NEXT:    ret i16 [[T]]
63;
64  %e = extractelement <3 x i64> %x, i16 0
65  %t = trunc i64 %e to i16
66  ret i16 %t
67}
68
69define i16 @shrinkExtractElt_i64_to_i16_1(<3 x i64> %x) {
70; LE-LABEL: @shrinkExtractElt_i64_to_i16_1(
71; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
72; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 4
73; LE-NEXT:    ret i16 [[T]]
74;
75; BE-LABEL: @shrinkExtractElt_i64_to_i16_1(
76; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
77; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 7
78; BE-NEXT:    ret i16 [[T]]
79;
80  %e = extractelement <3 x i64> %x, i16 1
81  %t = trunc i64 %e to i16
82  ret i16 %t
83}
84
85define i16 @shrinkExtractElt_i64_to_i16_2(<3 x i64> %x) {
86; LE-LABEL: @shrinkExtractElt_i64_to_i16_2(
87; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
88; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 8
89; LE-NEXT:    ret i16 [[T]]
90;
91; BE-LABEL: @shrinkExtractElt_i64_to_i16_2(
92; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
93; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 11
94; BE-NEXT:    ret i16 [[T]]
95;
96  %e = extractelement <3 x i64> %x, i16 2
97  %t = trunc i64 %e to i16
98  ret i16 %t
99}
100
101; Crazy types may be ok.
102define i11 @shrinkExtractElt_i33_to_11_2(<3 x i33> %x) {
103; LE-LABEL: @shrinkExtractElt_i33_to_11_2(
104; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11>
105; LE-NEXT:    [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i32 6
106; LE-NEXT:    ret i11 [[T]]
107;
108; BE-LABEL: @shrinkExtractElt_i33_to_11_2(
109; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11>
110; BE-NEXT:    [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i32 8
111; BE-NEXT:    ret i11 [[T]]
112;
113  %e = extractelement <3 x i33> %x, i16 2
114  %t = trunc i33 %e to i11
115  ret i11 %t
116}
117
118; Do not optimize if it would result in an invalid bitcast instruction.
119define i13 @shrinkExtractElt_i67_to_i13_2(<3 x i67> %x) {
120; ANY-LABEL: @shrinkExtractElt_i67_to_i13_2(
121; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i67> [[X:%.*]], i459 2
122; ANY-NEXT:    [[T:%.*]] = trunc i67 [[E]] to i13
123; ANY-NEXT:    ret i13 [[T]]
124;
125  %e = extractelement <3 x i67> %x, i459 2
126  %t = trunc i67 %e to i13
127  ret i13 %t
128}
129
130; Do not optimize if the bitcast instruction would be valid, but the
131; transform would be wrong.
132define i30 @shrinkExtractElt_i40_to_i30_1(<3 x i40> %x) {
133; ANY-LABEL: @shrinkExtractElt_i40_to_i30_1(
134; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i40> [[X:%.*]], i32 1
135; ANY-NEXT:    [[T:%.*]] = trunc i40 [[E]] to i30
136; ANY-NEXT:    ret i30 [[T]]
137;
138  %e = extractelement <3 x i40> %x, i32 1
139  %t = trunc i40 %e to i30
140  ret i30 %t
141}
142
143; Do not canonicalize if that would increase the instruction count.
144declare void @use(i64)
145define i16 @shrinkExtractElt_i64_to_i16_2_extra_use(<3 x i64> %x) {
146; ANY-LABEL: @shrinkExtractElt_i64_to_i16_2_extra_use(
147; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
148; ANY-NEXT:    call void @use(i64 [[E]])
149; ANY-NEXT:    [[T:%.*]] = trunc i64 [[E]] to i16
150; ANY-NEXT:    ret i16 [[T]]
151;
152  %e = extractelement <3 x i64> %x, i64 2
153  call void @use(i64 %e)
154  %t = trunc i64 %e to i16
155  ret i16 %t
156}
157
158; Check to ensure PR45314 remains fixed.
159define <4 x i64> @PR45314(<4 x i64> %x) {
160; LE-LABEL: @PR45314(
161; LE-NEXT:    [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32>
162; LE-NEXT:    [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> zeroinitializer
163; LE-NEXT:    [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64>
164; LE-NEXT:    ret <4 x i64> [[B]]
165;
166; BE-LABEL: @PR45314(
167; BE-NEXT:    [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32>
168; BE-NEXT:    [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
169; BE-NEXT:    [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64>
170; BE-NEXT:    ret <4 x i64> [[B]]
171;
172  %e = extractelement <4 x i64> %x, i32 0
173  %t = trunc i64 %e to i32
174  %i = insertelement <8 x i32> undef, i32 %t, i32 0
175  %s = shufflevector <8 x i32> %i, <8 x i32> undef, <8 x i32> zeroinitializer
176  %b = bitcast <8 x i32> %s to <4 x i64>
177  ret <4 x i64> %b
178}
179