Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / trunc-extractelement.ll
blobba2d07009d9c78934caca390333e98be141e2de0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=ANY,LE
3 ; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=ANY,BE
5 define 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]], i64 0
9 ; LE-NEXT:    ret i32 [[T]]
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]], i64 1
14 ; BE-NEXT:    ret i32 [[T]]
16   %e = extractelement <3 x i64> %x, i32 0
17   %t = trunc i64 %e to i32
18   ret i32 %t
21 define i32 @shrinkShiftExtractElt_i64_to_i32_0(<3 x i64> %x) {
22 ; LE-LABEL: @shrinkShiftExtractElt_i64_to_i32_0(
23 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
24 ; LE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 1
25 ; LE-NEXT:    ret i32 [[T]]
27 ; BE-LABEL: @shrinkShiftExtractElt_i64_to_i32_0(
28 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
29 ; BE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 0
30 ; BE-NEXT:    ret i32 [[T]]
32   %e = extractelement <3 x i64> %x, i32 0
33   %s = lshr i64 %e, 32
34   %t = trunc i64 %s to i32
35   ret i32 %t
38 define i32 @vscale_shrinkExtractElt_i64_to_i32_0(<vscale x 3 x i64> %x) {
39 ; LE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0(
40 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>
41 ; LE-NEXT:    [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 0
42 ; LE-NEXT:    ret i32 [[T]]
44 ; BE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0(
45 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>
46 ; BE-NEXT:    [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 1
47 ; BE-NEXT:    ret i32 [[T]]
49   %e = extractelement <vscale x 3 x i64> %x, i32 0
50   %t = trunc i64 %e to i32
51   ret i32 %t
54 define i32 @vscale_shrinkShiftExtractElt_i64_to_i32_0(<vscale x 3 x i64> %x) {
55 ; LE-LABEL: @vscale_shrinkShiftExtractElt_i64_to_i32_0(
56 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>
57 ; LE-NEXT:    [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 1
58 ; LE-NEXT:    ret i32 [[T]]
60 ; BE-LABEL: @vscale_shrinkShiftExtractElt_i64_to_i32_0(
61 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>
62 ; BE-NEXT:    [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 0
63 ; BE-NEXT:    ret i32 [[T]]
65   %e = extractelement <vscale x 3 x i64> %x, i32 0
66   %s = lshr i64 %e, 32
67   %t = trunc i64 %s to i32
68   ret i32 %t
71 define i32 @shrinkExtractElt_i64_to_i32_1(<3 x i64> %x) {
72 ; LE-LABEL: @shrinkExtractElt_i64_to_i32_1(
73 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
74 ; LE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 2
75 ; LE-NEXT:    ret i32 [[T]]
77 ; BE-LABEL: @shrinkExtractElt_i64_to_i32_1(
78 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
79 ; BE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 3
80 ; BE-NEXT:    ret i32 [[T]]
82   %e = extractelement <3 x i64> %x, i32 1
83   %t = trunc i64 %e to i32
84   ret i32 %t
87 define i32 @shrinkExtractElt_i64_to_i32_2(<3 x i64> %x) {
88 ; LE-LABEL: @shrinkExtractElt_i64_to_i32_2(
89 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
90 ; LE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 4
91 ; LE-NEXT:    ret i32 [[T]]
93 ; BE-LABEL: @shrinkExtractElt_i64_to_i32_2(
94 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>
95 ; BE-NEXT:    [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 5
96 ; BE-NEXT:    ret i32 [[T]]
98   %e = extractelement <3 x i64> %x, i32 2
99   %t = trunc i64 %e to i32
100   ret i32 %t
103 define i16 @shrinkExtractElt_i64_to_i16_0(<3 x i64> %x) {
104 ; LE-LABEL: @shrinkExtractElt_i64_to_i16_0(
105 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
106 ; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 0
107 ; LE-NEXT:    ret i16 [[T]]
109 ; BE-LABEL: @shrinkExtractElt_i64_to_i16_0(
110 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
111 ; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 3
112 ; BE-NEXT:    ret i16 [[T]]
114   %e = extractelement <3 x i64> %x, i16 0
115   %t = trunc i64 %e to i16
116   ret i16 %t
119 define i16 @shrinkShiftExtractElt_i64_to_i16_0(<3 x i64> %x) {
120 ; LE-LABEL: @shrinkShiftExtractElt_i64_to_i16_0(
121 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
122 ; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 3
123 ; LE-NEXT:    ret i16 [[T]]
125 ; BE-LABEL: @shrinkShiftExtractElt_i64_to_i16_0(
126 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
127 ; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 0
128 ; BE-NEXT:    ret i16 [[T]]
130   %e = extractelement <3 x i64> %x, i16 0
131   %s = ashr i64 %e, 48
132   %t = trunc i64 %s to i16
133   ret i16 %t
136 define i16 @shrinkExtractElt_i64_to_i16_1(<3 x i64> %x) {
137 ; LE-LABEL: @shrinkExtractElt_i64_to_i16_1(
138 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
139 ; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 4
140 ; LE-NEXT:    ret i16 [[T]]
142 ; BE-LABEL: @shrinkExtractElt_i64_to_i16_1(
143 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
144 ; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 7
145 ; BE-NEXT:    ret i16 [[T]]
147   %e = extractelement <3 x i64> %x, i16 1
148   %t = trunc i64 %e to i16
149   ret i16 %t
152 define i16 @shrinkExtractElt_i64_to_i16_2(<3 x i64> %x) {
153 ; LE-LABEL: @shrinkExtractElt_i64_to_i16_2(
154 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
155 ; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 8
156 ; LE-NEXT:    ret i16 [[T]]
158 ; BE-LABEL: @shrinkExtractElt_i64_to_i16_2(
159 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>
160 ; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 11
161 ; BE-NEXT:    ret i16 [[T]]
163   %e = extractelement <3 x i64> %x, i16 2
164   %t = trunc i64 %e to i16
165   ret i16 %t
168 ; Crazy types may be ok.
169 define i11 @shrinkExtractElt_i33_to_11_2(<3 x i33> %x) {
170 ; LE-LABEL: @shrinkExtractElt_i33_to_11_2(
171 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11>
172 ; LE-NEXT:    [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i64 6
173 ; LE-NEXT:    ret i11 [[T]]
175 ; BE-LABEL: @shrinkExtractElt_i33_to_11_2(
176 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11>
177 ; BE-NEXT:    [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i64 8
178 ; BE-NEXT:    ret i11 [[T]]
180   %e = extractelement <3 x i33> %x, i16 2
181   %t = trunc i33 %e to i11
182   ret i11 %t
185 ; Do not optimize if it would result in an invalid bitcast instruction.
186 define i13 @shrinkExtractElt_i67_to_i13_2(<3 x i67> %x) {
187 ; ANY-LABEL: @shrinkExtractElt_i67_to_i13_2(
188 ; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i67> [[X:%.*]], i64 2
189 ; ANY-NEXT:    [[T:%.*]] = trunc i67 [[E]] to i13
190 ; ANY-NEXT:    ret i13 [[T]]
192   %e = extractelement <3 x i67> %x, i459 2
193   %t = trunc i67 %e to i13
194   ret i13 %t
197 ; Do not optimize if the bitcast instruction would be valid, but the
198 ; transform would be wrong.
199 define i30 @shrinkExtractElt_i40_to_i30_1(<3 x i40> %x) {
200 ; ANY-LABEL: @shrinkExtractElt_i40_to_i30_1(
201 ; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i40> [[X:%.*]], i64 1
202 ; ANY-NEXT:    [[T:%.*]] = trunc i40 [[E]] to i30
203 ; ANY-NEXT:    ret i30 [[T]]
205   %e = extractelement <3 x i40> %x, i32 1
206   %t = trunc i40 %e to i30
207   ret i30 %t
210 ; Do not optimize if the shift amount isn't a whole number of truncated bits.
211 define i16 @shrinkShiftExtractElt_i64_to_i16_0_badshift(<3 x i64> %x) {
212 ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_0_badshift(
213 ; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 0
214 ; ANY-NEXT:    [[S:%.*]] = lshr i64 [[E]], 31
215 ; ANY-NEXT:    [[T:%.*]] = trunc i64 [[S]] to i16
216 ; ANY-NEXT:    ret i16 [[T]]
218   %e = extractelement <3 x i64> %x, i16 0
219   %s = lshr i64 %e, 31
220   %t = trunc i64 %s to i16
221   ret i16 %t
224 ; Do not canonicalize if that would increase the instruction count.
225 declare void @use(i64)
226 define i16 @shrinkExtractElt_i64_to_i16_2_extra_use(<3 x i64> %x) {
227 ; ANY-LABEL: @shrinkExtractElt_i64_to_i16_2_extra_use(
228 ; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
229 ; ANY-NEXT:    call void @use(i64 [[E]])
230 ; ANY-NEXT:    [[T:%.*]] = trunc i64 [[E]] to i16
231 ; ANY-NEXT:    ret i16 [[T]]
233   %e = extractelement <3 x i64> %x, i64 2
234   call void @use(i64 %e)
235   %t = trunc i64 %e to i16
236   ret i16 %t
239 ; Do not canonicalize if that would increase the instruction count.
240 define i16 @shrinkShiftExtractElt_i64_to_i16_2_extra_shift_use(<3 x i64> %x) {
241 ; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_shift_use(
242 ; ANY-NEXT:    [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
243 ; ANY-NEXT:    [[S:%.*]] = lshr i64 [[E]], 48
244 ; ANY-NEXT:    call void @use(i64 [[S]])
245 ; ANY-NEXT:    [[T:%.*]] = trunc nuw i64 [[S]] to i16
246 ; ANY-NEXT:    ret i16 [[T]]
248   %e = extractelement <3 x i64> %x, i64 2
249   %s = lshr i64 %e, 48
250   call void @use(i64 %s)
251   %t = trunc i64 %s to i16
252   ret i16 %t
255 ; OK to reuse the extract if we remove the shift+trunc.
256 define i16 @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(<3 x i64> %x) {
257 ; LE-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(
258 ; LE-NEXT:    [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
259 ; LE-NEXT:    call void @use(i64 [[E]])
260 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X]] to <12 x i16>
261 ; LE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 11
262 ; LE-NEXT:    ret i16 [[T]]
264 ; BE-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(
265 ; BE-NEXT:    [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2
266 ; BE-NEXT:    call void @use(i64 [[E]])
267 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <3 x i64> [[X]] to <12 x i16>
268 ; BE-NEXT:    [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 8
269 ; BE-NEXT:    ret i16 [[T]]
271   %e = extractelement <3 x i64> %x, i64 2
272   call void @use(i64 %e)
273   %s = lshr i64 %e, 48
274   %t = trunc i64 %s to i16
275   ret i16 %t
278 ; Check to ensure PR45314 remains fixed.
279 define <4 x i64> @PR45314(<4 x i64> %x) {
280 ; LE-LABEL: @PR45314(
281 ; LE-NEXT:    [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32>
282 ; LE-NEXT:    [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <8 x i32> zeroinitializer
283 ; LE-NEXT:    [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64>
284 ; LE-NEXT:    ret <4 x i64> [[B]]
286 ; BE-LABEL: @PR45314(
287 ; BE-NEXT:    [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32>
288 ; BE-NEXT:    [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
289 ; BE-NEXT:    [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64>
290 ; BE-NEXT:    ret <4 x i64> [[B]]
292   %e = extractelement <4 x i64> %x, i32 0
293   %t = trunc i64 %e to i32
294   %i = insertelement <8 x i32> undef, i32 %t, i32 0
295   %s = shufflevector <8 x i32> %i, <8 x i32> undef, <8 x i32> zeroinitializer
296   %b = bitcast <8 x i32> %s to <4 x i64>
297   ret <4 x i64> %b