Skip to content

Commit 729626b

Browse files
committed
[InstCombine] Add tests for trunc+lshr+extractlement -> extractelement+bitcast fold for #107404
1 parent 122fe3d commit 729626b

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

llvm/test/Transforms/InstCombine/trunc-extractelement-inseltpoison.ll

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2134
define 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

3863
define 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+
86124
define 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.
161213
declare void @use(i64)
162214
define 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.
176260
define <4 x i64> @PR45314(<4 x i64> %x) {
177261
; LE-LABEL: @PR45314(

llvm/test/Transforms/InstCombine/trunc-extractelement.ll

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2134
define 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

3863
define 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+
86124
define 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.
161213
declare void @use(i64)
162214
define 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.
176260
define <4 x i64> @PR45314(<4 x i64> %x) {
177261
; LE-LABEL: @PR45314(

0 commit comments

Comments
 (0)