1; RUN: opt < %s -instcombine -S | FileCheck %s
2
3target datalayout = "n8:32"
4
5; PR4548
6define i8 @udiv_i8(i8 %a, i8 %b) {
7; CHECK-LABEL: @udiv_i8(
8; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 %a, %b
9; CHECK-NEXT:    ret i8 [[DIV]]
10;
11  %za = zext i8 %a to i32
12  %zb = zext i8 %b to i32
13  %udiv = udiv i32 %za, %zb
14  %conv3 = trunc i32 %udiv to i8
15  ret i8 %conv3
16}
17
18define <2 x i8> @udiv_i8_vec(<2 x i8> %a, <2 x i8> %b) {
19; CHECK-LABEL: @udiv_i8_vec(
20; CHECK-NEXT:    [[DIV:%.*]] = udiv <2 x i8> %a, %b
21; CHECK-NEXT:    ret <2 x i8> [[DIV]]
22;
23  %za = zext <2 x i8> %a to <2 x i32>
24  %zb = zext <2 x i8> %b to <2 x i32>
25  %udiv = udiv <2 x i32> %za, %zb
26  %conv3 = trunc <2 x i32> %udiv to <2 x i8>
27  ret <2 x i8> %conv3
28}
29
30define i8 @urem_i8(i8 %a, i8 %b) {
31; CHECK-LABEL: @urem_i8(
32; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 %a, %b
33; CHECK-NEXT:    ret i8 [[TMP1]]
34;
35  %za = zext i8 %a to i32
36  %zb = zext i8 %b to i32
37  %udiv = urem i32 %za, %zb
38  %conv3 = trunc i32 %udiv to i8
39  ret i8 %conv3
40}
41
42define <2 x i8> @urem_i8_vec(<2 x i8> %a, <2 x i8> %b) {
43; CHECK-LABEL: @urem_i8_vec(
44; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i8> %a, %b
45; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
46;
47  %za = zext <2 x i8> %a to <2 x i32>
48  %zb = zext <2 x i8> %b to <2 x i32>
49  %udiv = urem <2 x i32> %za, %zb
50  %conv3 = trunc <2 x i32> %udiv to <2 x i8>
51  ret <2 x i8> %conv3
52}
53
54define i32 @udiv_i32(i8 %a, i8 %b) {
55; CHECK-LABEL: @udiv_i32(
56; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 %a, %b
57; CHECK-NEXT:    [[UDIV:%.*]] = zext i8 [[DIV]] to i32
58; CHECK-NEXT:    ret i32 [[UDIV]]
59;
60  %za = zext i8 %a to i32
61  %zb = zext i8 %b to i32
62  %udiv = udiv i32 %za, %zb
63  ret i32 %udiv
64}
65
66define <2 x i32> @udiv_i32_vec(<2 x i8> %a, <2 x i8> %b) {
67; CHECK-LABEL: @udiv_i32_vec(
68; CHECK-NEXT:    [[DIV:%.*]] = udiv <2 x i8> %a, %b
69; CHECK-NEXT:    [[UDIV:%.*]] = zext <2 x i8> [[DIV]] to <2 x i32>
70; CHECK-NEXT:    ret <2 x i32> [[UDIV]]
71;
72  %za = zext <2 x i8> %a to <2 x i32>
73  %zb = zext <2 x i8> %b to <2 x i32>
74  %udiv = udiv <2 x i32> %za, %zb
75  ret <2 x i32> %udiv
76}
77
78define i32 @udiv_i32_multiuse(i8 %a, i8 %b) {
79; CHECK-LABEL: @udiv_i32_multiuse(
80; CHECK-NEXT:    [[ZA:%.*]] = zext i8 %a to i32
81; CHECK-NEXT:    [[ZB:%.*]] = zext i8 %b to i32
82; CHECK-NEXT:    [[UDIV:%.*]] = udiv i32 [[ZA]], [[ZB]]
83; CHECK-NEXT:    [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]]
84; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[UDIV]], [[EXTRA_USES]]
85; CHECK-NEXT:    ret i32 [[R]]
86;
87  %za = zext i8 %a to i32
88  %zb = zext i8 %b to i32
89  %udiv = udiv i32 %za, %zb
90  %extra_uses = add i32 %za, %zb
91  %r = mul i32 %udiv, %extra_uses
92  ret i32 %r
93}
94
95define i32 @udiv_illegal_type(i9 %a, i9 %b) {
96; CHECK-LABEL: @udiv_illegal_type(
97; CHECK-NEXT:    [[DIV:%.*]] = udiv i9 %a, %b
98; CHECK-NEXT:    [[UDIV:%.*]] = zext i9 [[DIV]] to i32
99; CHECK-NEXT:    ret i32 [[UDIV]]
100;
101  %za = zext i9 %a to i32
102  %zb = zext i9 %b to i32
103  %udiv = udiv i32 %za, %zb
104  ret i32 %udiv
105}
106
107define i32 @urem_i32(i8 %a, i8 %b) {
108; CHECK-LABEL: @urem_i32(
109; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 %a, %b
110; CHECK-NEXT:    [[UREM:%.*]] = zext i8 [[TMP1]] to i32
111; CHECK-NEXT:    ret i32 [[UREM]]
112;
113  %za = zext i8 %a to i32
114  %zb = zext i8 %b to i32
115  %urem = urem i32 %za, %zb
116  ret i32 %urem
117}
118
119define <2 x i32> @urem_i32_vec(<2 x i8> %a, <2 x i8> %b) {
120; CHECK-LABEL: @urem_i32_vec(
121; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i8> %a, %b
122; CHECK-NEXT:    [[UREM:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
123; CHECK-NEXT:    ret <2 x i32> [[UREM]]
124;
125  %za = zext <2 x i8> %a to <2 x i32>
126  %zb = zext <2 x i8> %b to <2 x i32>
127  %urem = urem <2 x i32> %za, %zb
128  ret <2 x i32> %urem
129}
130
131define i32 @urem_i32_multiuse(i8 %a, i8 %b) {
132; CHECK-LABEL: @urem_i32_multiuse(
133; CHECK-NEXT:    [[ZA:%.*]] = zext i8 %a to i32
134; CHECK-NEXT:    [[ZB:%.*]] = zext i8 %b to i32
135; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[ZA]], [[ZB]]
136; CHECK-NEXT:    [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]]
137; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[UREM]], [[EXTRA_USES]]
138; CHECK-NEXT:    ret i32 [[R]]
139;
140  %za = zext i8 %a to i32
141  %zb = zext i8 %b to i32
142  %urem = urem i32 %za, %zb
143  %extra_uses = add i32 %za, %zb
144  %r = mul i32 %urem, %extra_uses
145  ret i32 %r
146}
147
148define i32 @urem_illegal_type(i9 %a, i9 %b) {
149; CHECK-LABEL: @urem_illegal_type(
150; CHECK-NEXT:    [[TMP1:%.*]] = urem i9 %a, %b
151; CHECK-NEXT:    [[UREM:%.*]] = zext i9 [[TMP1]] to i32
152; CHECK-NEXT:    ret i32 [[UREM]]
153;
154  %za = zext i9 %a to i32
155  %zb = zext i9 %b to i32
156  %urem = urem i32 %za, %zb
157  ret i32 %urem
158}
159
160define i32 @udiv_i32_c(i8 %a) {
161; CHECK-LABEL: @udiv_i32_c(
162; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 %a, 10
163; CHECK-NEXT:    [[UDIV:%.*]] = zext i8 [[DIV]] to i32
164; CHECK-NEXT:    ret i32 [[UDIV]]
165;
166  %za = zext i8 %a to i32
167  %udiv = udiv i32 %za, 10
168  ret i32 %udiv
169}
170
171define <2 x i32> @udiv_i32_c_vec(<2 x i8> %a) {
172; CHECK-LABEL: @udiv_i32_c_vec(
173; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i8> %a, <i8 10, i8 17>
174; CHECK-NEXT:    [[UDIV:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
175; CHECK-NEXT:    ret <2 x i32> [[UDIV]]
176;
177  %za = zext <2 x i8> %a to <2 x i32>
178  %udiv = udiv <2 x i32> %za, <i32 10, i32 17>
179  ret <2 x i32> %udiv
180}
181
182define i32 @udiv_i32_c_multiuse(i8 %a) {
183; CHECK-LABEL: @udiv_i32_c_multiuse(
184; CHECK-NEXT:    [[ZA:%.*]] = zext i8 %a to i32
185; CHECK-NEXT:    [[UDIV:%.*]] = udiv i32 [[ZA]], 10
186; CHECK-NEXT:    [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UDIV]], [[ZA]]
187; CHECK-NEXT:    ret i32 [[EXTRA_USE]]
188;
189  %za = zext i8 %a to i32
190  %udiv = udiv i32 %za, 10
191  %extra_use = add i32 %za, %udiv
192  ret i32 %extra_use
193}
194
195define i32 @udiv_illegal_type_c(i9 %a) {
196; CHECK-LABEL: @udiv_illegal_type_c(
197; CHECK-NEXT:    [[DIV:%.*]] = udiv i9 %a, 10
198; CHECK-NEXT:    [[UDIV:%.*]] = zext i9 [[DIV]] to i32
199; CHECK-NEXT:    ret i32 [[UDIV]]
200;
201  %za = zext i9 %a to i32
202  %udiv = udiv i32 %za, 10
203  ret i32 %udiv
204}
205
206define i32 @urem_i32_c(i8 %a) {
207; CHECK-LABEL: @urem_i32_c(
208; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 %a, 10
209; CHECK-NEXT:    [[UREM:%.*]] = zext i8 [[TMP1]] to i32
210; CHECK-NEXT:    ret i32 [[UREM]]
211;
212  %za = zext i8 %a to i32
213  %urem = urem i32 %za, 10
214  ret i32 %urem
215}
216
217define <2 x i32> @urem_i32_c_vec(<2 x i8> %a) {
218; CHECK-LABEL: @urem_i32_c_vec(
219; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i8> %a, <i8 10, i8 17>
220; CHECK-NEXT:    [[UREM:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
221; CHECK-NEXT:    ret <2 x i32> [[UREM]]
222;
223  %za = zext <2 x i8> %a to <2 x i32>
224  %urem = urem <2 x i32> %za, <i32 10, i32 17>
225  ret <2 x i32> %urem
226}
227
228define i32 @urem_i32_c_multiuse(i8 %a) {
229; CHECK-LABEL: @urem_i32_c_multiuse(
230; CHECK-NEXT:    [[ZA:%.*]] = zext i8 %a to i32
231; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[ZA]], 10
232; CHECK-NEXT:    [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UREM]], [[ZA]]
233; CHECK-NEXT:    ret i32 [[EXTRA_USE]]
234;
235  %za = zext i8 %a to i32
236  %urem = urem i32 %za, 10
237  %extra_use = add i32 %za, %urem
238  ret i32 %extra_use
239}
240
241define i32 @urem_illegal_type_c(i9 %a) {
242; CHECK-LABEL: @urem_illegal_type_c(
243; CHECK-NEXT:    [[TMP1:%.*]] = urem i9 %a, 10
244; CHECK-NEXT:    [[UREM:%.*]] = zext i9 [[TMP1]] to i32
245; CHECK-NEXT:    ret i32 [[UREM]]
246;
247  %za = zext i9 %a to i32
248  %urem = urem i32 %za, 10
249  ret i32 %urem
250}
251
252define i32 @udiv_c_i32(i8 %a) {
253; CHECK-LABEL: @udiv_c_i32(
254; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 10, %a
255; CHECK-NEXT:    [[UDIV:%.*]] = zext i8 [[TMP1]] to i32
256; CHECK-NEXT:    ret i32 [[UDIV]]
257;
258  %za = zext i8 %a to i32
259  %udiv = udiv i32 10, %za
260  ret i32 %udiv
261}
262
263define i32 @urem_c_i32(i8 %a) {
264; CHECK-LABEL: @urem_c_i32(
265; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 10, %a
266; CHECK-NEXT:    [[UREM:%.*]] = zext i8 [[TMP1]] to i32
267; CHECK-NEXT:    ret i32 [[UREM]]
268;
269  %za = zext i8 %a to i32
270  %urem = urem i32 10, %za
271  ret i32 %urem
272}
273
274; Make sure constexpr is handled.
275
276@b = external global [1 x i8]
277
278define i32 @udiv_constexpr(i8 %a) {
279; CHECK-LABEL: @udiv_constexpr(
280; CHECK-NEXT:    [[TMP1:%.*]] = udiv i8 %a, ptrtoint ([1 x i8]* @b to i8)
281; CHECK-NEXT:    [[D:%.*]] = zext i8 [[TMP1]] to i32
282; CHECK-NEXT:    ret i32 [[D]]
283;
284  %za = zext i8 %a to i32
285  %d = udiv i32 %za, zext (i8 ptrtoint ([1 x i8]* @b to i8) to i32)
286  ret i32 %d
287}
288
289