@@ -18,6 +18,19 @@ define i32 @shrinkExtractElt_i64_to_i32_0(<3 x i64> %x) {
1818 ret i32 %t
1919}
2020
21+ define i32 @shrinkShiftExtractElt_i64_to_i32_0 (<3 x i64 > %x ) {
22+ ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i32_0(
23+ ; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 0
24+ ; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 32
25+ ; ANY-NEXT: [[T:%.*]] = trunc nuw i64 [[S]] to i32
26+ ; ANY-NEXT: ret i32 [[T]]
27+ ;
28+ %e = extractelement <3 x i64 > %x , i32 0
29+ %s = lshr i64 %e , 32
30+ %t = trunc i64 %s to i32
31+ ret i32 %t
32+ }
33+
2134define i32 @vscale_shrinkExtractElt_i64_to_i32_0 (<vscale x 3 x i64 > %x ) {
2235; LE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0(
2336; LE-NEXT: [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>
@@ -34,6 +47,18 @@ define i32 @vscale_shrinkExtractElt_i64_to_i32_0(<vscale x 3 x i64> %x) {
3447 ret i32 %t
3548}
3649
50+ define i32 @vscale_shrinkShiftExtractElt_i64_to_i32_0 (<vscale x 3 x i64 > %x ) {
51+ ; ANY-LABEL: @vscale_shrinkShiftExtractElt_i64_to_i32_0(
52+ ; ANY-NEXT: [[E:%.*]] = extractelement <vscale x 3 x i64> [[X:%.*]], i64 0
53+ ; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 32
54+ ; ANY-NEXT: [[T:%.*]] = trunc nuw i64 [[S]] to i32
55+ ; ANY-NEXT: ret i32 [[T]]
56+ ;
57+ %e = extractelement <vscale x 3 x i64 > %x , i32 0
58+ %s = lshr i64 %e , 32
59+ %t = trunc i64 %s to i32
60+ ret i32 %t
61+ }
3762
3863define i32 @shrinkExtractElt_i64_to_i32_1 (<3 x i64 > %x ) {
3964; LE-LABEL: @shrinkExtractElt_i64_to_i32_1(
@@ -83,6 +108,19 @@ define i16 @shrinkExtractElt_i64_to_i16_0(<3 x i64> %x) {
83108 ret i16 %t
84109}
85110
111+ define i16 @shrinkShiftExtractElt_i64_to_i16_0 (<3 x i64 > %x ) {
112+ ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_0(
113+ ; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 0
114+ ; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 48
115+ ; ANY-NEXT: [[T:%.*]] = trunc nuw i64 [[S]] to i16
116+ ; ANY-NEXT: ret i16 [[T]]
117+ ;
118+ %e = extractelement <3 x i64 > %x , i16 0
119+ %s = ashr i64 %e , 48
120+ %t = trunc i64 %s to i16
121+ ret i16 %t
122+ }
123+
86124define i16 @shrinkExtractElt_i64_to_i16_1 (<3 x i64 > %x ) {
87125; LE-LABEL: @shrinkExtractElt_i64_to_i16_1(
88126; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
@@ -157,6 +195,20 @@ define i30 @shrinkExtractElt_i40_to_i30_1(<3 x i40> %x) {
157195 ret i30 %t
158196}
159197
198+ ; Do not optimize if the shift amount isn't a whole number of truncated bits.
199+ define i16 @shrinkShiftExtractElt_i64_to_i16_0_badshift (<3 x i64 > %x ) {
200+ ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_0_badshift(
201+ ; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 0
202+ ; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 31
203+ ; ANY-NEXT: [[T:%.*]] = trunc i64 [[S]] to i16
204+ ; ANY-NEXT: ret i16 [[T]]
205+ ;
206+ %e = extractelement <3 x i64 > %x , i16 0
207+ %s = lshr i64 %e , 31
208+ %t = trunc i64 %s to i16
209+ ret i16 %t
210+ }
211+
160212; Do not canonicalize if that would increase the instruction count.
161213declare void @use (i64 )
162214define i16 @shrinkExtractElt_i64_to_i16_2_extra_use (<3 x i64 > %x ) {
@@ -172,6 +224,38 @@ define i16 @shrinkExtractElt_i64_to_i16_2_extra_use(<3 x i64> %x) {
172224 ret i16 %t
173225}
174226
227+ ; Do not canonicalize if that would increase the instruction count.
228+ define i16 @shrinkShiftExtractElt_i64_to_i16_2_extra_shift_use (<3 x i64 > %x ) {
229+ ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_shift_use(
230+ ; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
231+ ; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 48
232+ ; ANY-NEXT: call void @use(i64 [[S]])
233+ ; ANY-NEXT: [[T:%.*]] = trunc nuw i64 [[S]] to i16
234+ ; ANY-NEXT: ret i16 [[T]]
235+ ;
236+ %e = extractelement <3 x i64 > %x , i64 2
237+ %s = lshr i64 %e , 48
238+ call void @use (i64 %s )
239+ %t = trunc i64 %s to i16
240+ ret i16 %t
241+ }
242+
243+ ; OK to reuse the extract if we remove the shift+trunc.
244+ define i16 @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use (<3 x i64 > %x ) {
245+ ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(
246+ ; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
247+ ; ANY-NEXT: call void @use(i64 [[E]])
248+ ; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 48
249+ ; ANY-NEXT: [[T:%.*]] = trunc nuw i64 [[S]] to i16
250+ ; ANY-NEXT: ret i16 [[T]]
251+ ;
252+ %e = extractelement <3 x i64 > %x , i64 2
253+ call void @use (i64 %e )
254+ %s = lshr i64 %e , 48
255+ %t = trunc i64 %s to i16
256+ ret i16 %t
257+ }
258+
175259; Check to ensure PR45314 remains fixed.
176260define <4 x i64 > @PR45314 (<4 x i64 > %x ) {
177261; LE-LABEL: @PR45314(
0 commit comments