xref: /llvm-project/llvm/test/Transforms/InstCombine/udivrem-change-width.ll (revision 5918f62301788b53e7d3a23f3203c483e9d4d791)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target datalayout = "n8:32"
5
6; PR4548
7define i8 @udiv_i8(i8 %a, i8 %b) {
8; CHECK-LABEL: @udiv_i8(
9; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 [[A:%.*]], [[B:%.*]]
10; CHECK-NEXT:    ret i8 [[TMP1]]
11;
12  %za = zext i8 %a to i32
13  %zb = zext i8 %b to i32
14  %udiv = udiv i32 %za, %zb
15  %conv3 = trunc i32 %udiv to i8
16  ret i8 %conv3
17}
18
19define <2 x i8> @udiv_i8_vec(<2 x i8> %a, <2 x i8> %b) {
20; CHECK-LABEL: @udiv_i8_vec(
21; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i8> [[A:%.*]], [[B:%.*]]
22; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
23;
24  %za = zext <2 x i8> %a to <2 x i32>
25  %zb = zext <2 x i8> %b to <2 x i32>
26  %udiv = udiv <2 x i32> %za, %zb
27  %conv3 = trunc <2 x i32> %udiv to <2 x i8>
28  ret <2 x i8> %conv3
29}
30
31define i8 @urem_i8(i8 %a, i8 %b) {
32; CHECK-LABEL: @urem_i8(
33; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[A:%.*]], [[B:%.*]]
34; CHECK-NEXT:    ret i8 [[TMP1]]
35;
36  %za = zext i8 %a to i32
37  %zb = zext i8 %b to i32
38  %udiv = urem i32 %za, %zb
39  %conv3 = trunc i32 %udiv to i8
40  ret i8 %conv3
41}
42
43define <2 x i8> @urem_i8_vec(<2 x i8> %a, <2 x i8> %b) {
44; CHECK-LABEL: @urem_i8_vec(
45; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i8> [[A:%.*]], [[B:%.*]]
46; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
47;
48  %za = zext <2 x i8> %a to <2 x i32>
49  %zb = zext <2 x i8> %b to <2 x i32>
50  %udiv = urem <2 x i32> %za, %zb
51  %conv3 = trunc <2 x i32> %udiv to <2 x i8>
52  ret <2 x i8> %conv3
53}
54
55define i32 @udiv_i32(i8 %a, i8 %b) {
56; CHECK-LABEL: @udiv_i32(
57; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 [[A:%.*]], [[B:%.*]]
58; CHECK-NEXT:    [[UDIV:%.*]] = zext i8 [[TMP1]] to i32
59; CHECK-NEXT:    ret i32 [[UDIV]]
60;
61  %za = zext i8 %a to i32
62  %zb = zext i8 %b to i32
63  %udiv = udiv i32 %za, %zb
64  ret i32 %udiv
65}
66
67define <2 x i32> @udiv_i32_vec(<2 x i8> %a, <2 x i8> %b) {
68; CHECK-LABEL: @udiv_i32_vec(
69; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i8> [[A:%.*]], [[B:%.*]]
70; CHECK-NEXT:    [[UDIV:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
71; CHECK-NEXT:    ret <2 x i32> [[UDIV]]
72;
73  %za = zext <2 x i8> %a to <2 x i32>
74  %zb = zext <2 x i8> %b to <2 x i32>
75  %udiv = udiv <2 x i32> %za, %zb
76  ret <2 x i32> %udiv
77}
78
79define i32 @udiv_i32_multiuse(i8 %a, i8 %b) {
80; CHECK-LABEL: @udiv_i32_multiuse(
81; CHECK-NEXT:    [[ZA:%.*]] = zext i8 [[A:%.*]] to i32
82; CHECK-NEXT:    [[ZB:%.*]] = zext i8 [[B:%.*]] to i32
83; CHECK-NEXT:    [[UDIV:%.*]] = udiv i32 [[ZA]], [[ZB]]
84; CHECK-NEXT:    [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]]
85; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[UDIV]], [[EXTRA_USES]]
86; CHECK-NEXT:    ret i32 [[R]]
87;
88  %za = zext i8 %a to i32
89  %zb = zext i8 %b to i32
90  %udiv = udiv i32 %za, %zb
91  %extra_uses = add i32 %za, %zb
92  %r = mul i32 %udiv, %extra_uses
93  ret i32 %r
94}
95
96define i32 @udiv_illegal_type(i9 %a, i9 %b) {
97; CHECK-LABEL: @udiv_illegal_type(
98; CHECK-NEXT:    [[TMP1:%.*]] = udiv i9 [[A:%.*]], [[B:%.*]]
99; CHECK-NEXT:    [[UDIV:%.*]] = zext i9 [[TMP1]] to i32
100; CHECK-NEXT:    ret i32 [[UDIV]]
101;
102  %za = zext i9 %a to i32
103  %zb = zext i9 %b to i32
104  %udiv = udiv i32 %za, %zb
105  ret i32 %udiv
106}
107
108define i32 @urem_i32(i8 %a, i8 %b) {
109; CHECK-LABEL: @urem_i32(
110; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[A:%.*]], [[B:%.*]]
111; CHECK-NEXT:    [[UREM:%.*]] = zext i8 [[TMP1]] to i32
112; CHECK-NEXT:    ret i32 [[UREM]]
113;
114  %za = zext i8 %a to i32
115  %zb = zext i8 %b to i32
116  %urem = urem i32 %za, %zb
117  ret i32 %urem
118}
119
120define <2 x i32> @urem_i32_vec(<2 x i8> %a, <2 x i8> %b) {
121; CHECK-LABEL: @urem_i32_vec(
122; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i8> [[A:%.*]], [[B:%.*]]
123; CHECK-NEXT:    [[UREM:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
124; CHECK-NEXT:    ret <2 x i32> [[UREM]]
125;
126  %za = zext <2 x i8> %a to <2 x i32>
127  %zb = zext <2 x i8> %b to <2 x i32>
128  %urem = urem <2 x i32> %za, %zb
129  ret <2 x i32> %urem
130}
131
132define i32 @urem_i32_multiuse(i8 %a, i8 %b) {
133; CHECK-LABEL: @urem_i32_multiuse(
134; CHECK-NEXT:    [[ZA:%.*]] = zext i8 [[A:%.*]] to i32
135; CHECK-NEXT:    [[ZB:%.*]] = zext i8 [[B:%.*]] to i32
136; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[ZA]], [[ZB]]
137; CHECK-NEXT:    [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]]
138; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[UREM]], [[EXTRA_USES]]
139; CHECK-NEXT:    ret i32 [[R]]
140;
141  %za = zext i8 %a to i32
142  %zb = zext i8 %b to i32
143  %urem = urem i32 %za, %zb
144  %extra_uses = add i32 %za, %zb
145  %r = mul i32 %urem, %extra_uses
146  ret i32 %r
147}
148
149define i32 @urem_illegal_type(i9 %a, i9 %b) {
150; CHECK-LABEL: @urem_illegal_type(
151; CHECK-NEXT:    [[TMP1:%.*]] = urem i9 [[A:%.*]], [[B:%.*]]
152; CHECK-NEXT:    [[UREM:%.*]] = zext i9 [[TMP1]] to i32
153; CHECK-NEXT:    ret i32 [[UREM]]
154;
155  %za = zext i9 %a to i32
156  %zb = zext i9 %b to i32
157  %urem = urem i32 %za, %zb
158  ret i32 %urem
159}
160
161define i32 @udiv_i32_c(i8 %a) {
162; CHECK-LABEL: @udiv_i32_c(
163; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 [[A:%.*]], 10
164; CHECK-NEXT:    [[UDIV:%.*]] = zext nneg i8 [[TMP1]] to i32
165; CHECK-NEXT:    ret i32 [[UDIV]]
166;
167  %za = zext i8 %a to i32
168  %udiv = udiv i32 %za, 10
169  ret i32 %udiv
170}
171
172define <2 x i32> @udiv_i32_c_vec(<2 x i8> %a) {
173; CHECK-LABEL: @udiv_i32_c_vec(
174; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i8> [[A:%.*]], <i8 10, i8 17>
175; CHECK-NEXT:    [[UDIV:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
176; CHECK-NEXT:    ret <2 x i32> [[UDIV]]
177;
178  %za = zext <2 x i8> %a to <2 x i32>
179  %udiv = udiv <2 x i32> %za, <i32 10, i32 17>
180  ret <2 x i32> %udiv
181}
182
183define i32 @udiv_i32_c_multiuse(i8 %a) {
184; CHECK-LABEL: @udiv_i32_c_multiuse(
185; CHECK-NEXT:    [[ZA:%.*]] = zext i8 [[A:%.*]] to i32
186; CHECK-NEXT:    [[UDIV:%.*]] = udiv i32 [[ZA]], 10
187; CHECK-NEXT:    [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UDIV]], [[ZA]]
188; CHECK-NEXT:    ret i32 [[EXTRA_USE]]
189;
190  %za = zext i8 %a to i32
191  %udiv = udiv i32 %za, 10
192  %extra_use = add i32 %za, %udiv
193  ret i32 %extra_use
194}
195
196define i32 @udiv_illegal_type_c(i9 %a) {
197; CHECK-LABEL: @udiv_illegal_type_c(
198; CHECK-NEXT:    [[TMP1:%.*]] = udiv i9 [[A:%.*]], 10
199; CHECK-NEXT:    [[UDIV:%.*]] = zext nneg i9 [[TMP1]] to i32
200; CHECK-NEXT:    ret i32 [[UDIV]]
201;
202  %za = zext i9 %a to i32
203  %udiv = udiv i32 %za, 10
204  ret i32 %udiv
205}
206
207define i32 @urem_i32_c(i8 %a) {
208; CHECK-LABEL: @urem_i32_c(
209; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[A:%.*]], 10
210; CHECK-NEXT:    [[UREM:%.*]] = zext nneg i8 [[TMP1]] to i32
211; CHECK-NEXT:    ret i32 [[UREM]]
212;
213  %za = zext i8 %a to i32
214  %urem = urem i32 %za, 10
215  ret i32 %urem
216}
217
218define <2 x i32> @urem_i32_c_vec(<2 x i8> %a) {
219; CHECK-LABEL: @urem_i32_c_vec(
220; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i8> [[A:%.*]], <i8 10, i8 17>
221; CHECK-NEXT:    [[UREM:%.*]] = zext nneg <2 x i8> [[TMP1]] to <2 x i32>
222; CHECK-NEXT:    ret <2 x i32> [[UREM]]
223;
224  %za = zext <2 x i8> %a to <2 x i32>
225  %urem = urem <2 x i32> %za, <i32 10, i32 17>
226  ret <2 x i32> %urem
227}
228
229define i32 @urem_i32_c_multiuse(i8 %a) {
230; CHECK-LABEL: @urem_i32_c_multiuse(
231; CHECK-NEXT:    [[ZA:%.*]] = zext i8 [[A:%.*]] to i32
232; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[ZA]], 10
233; CHECK-NEXT:    [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UREM]], [[ZA]]
234; CHECK-NEXT:    ret i32 [[EXTRA_USE]]
235;
236  %za = zext i8 %a to i32
237  %urem = urem i32 %za, 10
238  %extra_use = add i32 %za, %urem
239  ret i32 %extra_use
240}
241
242define i32 @urem_illegal_type_c(i9 %a) {
243; CHECK-LABEL: @urem_illegal_type_c(
244; CHECK-NEXT:    [[TMP1:%.*]] = urem i9 [[A:%.*]], 10
245; CHECK-NEXT:    [[UREM:%.*]] = zext nneg i9 [[TMP1]] to i32
246; CHECK-NEXT:    ret i32 [[UREM]]
247;
248  %za = zext i9 %a to i32
249  %urem = urem i32 %za, 10
250  ret i32 %urem
251}
252
253define i32 @udiv_c_i32(i8 %a) {
254; CHECK-LABEL: @udiv_c_i32(
255; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 10, [[A:%.*]]
256; CHECK-NEXT:    [[UDIV:%.*]] = zext nneg i8 [[TMP1]] to i32
257; CHECK-NEXT:    ret i32 [[UDIV]]
258;
259  %za = zext i8 %a to i32
260  %udiv = udiv i32 10, %za
261  ret i32 %udiv
262}
263
264define i32 @urem_c_i32(i8 %a) {
265; CHECK-LABEL: @urem_c_i32(
266; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 10, [[A:%.*]]
267; CHECK-NEXT:    [[UREM:%.*]] = zext nneg i8 [[TMP1]] to i32
268; CHECK-NEXT:    ret i32 [[UREM]]
269;
270  %za = zext i8 %a to i32
271  %urem = urem i32 10, %za
272  ret i32 %urem
273}
274
275; Make sure constexpr is handled.
276
277@b = external global [1 x i8]
278
279define i32 @udiv_constexpr(i8 %a) {
280; CHECK-LABEL: @udiv_constexpr(
281; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 [[A:%.*]], ptrtoint (ptr @b to i8)
282; CHECK-NEXT:    [[D:%.*]] = zext i8 [[TMP1]] to i32
283; CHECK-NEXT:    ret i32 [[D]]
284;
285  %za = zext i8 %a to i32
286  %zb = zext i8 ptrtoint (ptr @b to i8) to i32
287  %d = udiv i32 %za, %zb
288  ret i32 %d
289}
290
291; minimal form of PR56810
292
293@g1 = external global [1 x i8]
294
295define i32 @udiv_const_constexpr(i8 %a) {
296; CHECK-LABEL: @udiv_const_constexpr(
297; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 42, ptrtoint (ptr @g1 to i8)
298; CHECK-NEXT:    [[D:%.*]] = zext nneg i8 [[TMP1]] to i32
299; CHECK-NEXT:    ret i32 [[D]]
300;
301  %z = zext i8 ptrtoint (ptr @g1 to i8) to i32
302  %d = udiv i32 42, %z
303  ret i32 %d
304}
305
306; minimal form of PR56810
307
308@g2 = external global [1 x i8]
309
310define i32 @urem_const_constexpr(i8 %a) {
311; CHECK-LABEL: @urem_const_constexpr(
312; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 42, ptrtoint (ptr @g2 to i8)
313; CHECK-NEXT:    [[D:%.*]] = zext nneg i8 [[TMP1]] to i32
314; CHECK-NEXT:    ret i32 [[D]]
315;
316  %z = zext i8 ptrtoint (ptr @g2 to i8) to i32
317  %d = urem i32 42, %z
318  ret i32 %d
319}
320
321@g3 = external global [1 x i8]
322
323define i32 @udiv_constexpr_const(i8 %a) {
324; CHECK-LABEL: @udiv_constexpr_const(
325; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 ptrtoint (ptr @g3 to i8), 42
326; CHECK-NEXT:    [[D:%.*]] = zext nneg i8 [[TMP1]] to i32
327; CHECK-NEXT:    ret i32 [[D]]
328;
329  %z = zext i8 ptrtoint (ptr @g3 to i8) to i32
330  %d = udiv i32 %z, 42
331  ret i32 %d
332}
333
334@g4 = external global [1 x i8]
335
336define i32 @urem_constexpr_const(i8 %a) {
337; CHECK-LABEL: @urem_constexpr_const(
338; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 ptrtoint (ptr @g4 to i8), 42
339; CHECK-NEXT:    [[D:%.*]] = zext nneg i8 [[TMP1]] to i32
340; CHECK-NEXT:    ret i32 [[D]]
341;
342  %z = zext i8 ptrtoint (ptr @g4 to i8) to i32
343  %d = urem i32 %z, 42
344  ret i32 %d
345}
346