1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4define i64 @test_shl_nuw_nsw__all_are_safe(i32 %x, i64 %y) {
5; CHECK-LABEL: @test_shl_nuw_nsw__all_are_safe(
6; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
7; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
8; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
9; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
10; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
11; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
12; CHECK-NEXT:    ret i64 [[TMP5]]
13;
14  %1 = and i32 %x, 15
15  %2 = shl nuw nsw i32 %1, 2
16  %3 = zext i32 %2 to i64
17  %4 = icmp eq i32 %1, 0
18  %5 = ashr i64 %y, %3
19  %6 = select i1 %4, i64 %y, i64 %5
20  ret i64 %6
21}
22
23define i64 @test_shl_nuw__all_are_safe(i32 %x, i64 %y) {
24; CHECK-LABEL: @test_shl_nuw__all_are_safe(
25; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
26; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
27; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
28; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
29; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
30; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
31; CHECK-NEXT:    ret i64 [[TMP5]]
32;
33  %1 = and i32 %x, 15
34  %2 = shl nuw i32 %1, 2
35  %3 = zext i32 %2 to i64
36  %4 = icmp eq i32 %1, 0
37  %5 = ashr i64 %y, %3
38  %6 = select i1 %4, i64 %y, i64 %5
39  ret i64 %6
40}
41
42define i64 @test_shl_nsw__all_are_safe(i32 %x, i64 %y) {
43; CHECK-LABEL: @test_shl_nsw__all_are_safe(
44; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
45; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
46; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
47; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
48; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
49; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
50; CHECK-NEXT:    ret i64 [[TMP5]]
51;
52  %1 = and i32 %x, 15
53  %2 = shl nsw i32 %1, 2
54  %3 = zext i32 %2 to i64
55  %4 = icmp eq i32 %1, 0
56  %5 = ashr i64 %y, %3
57  %6 = select i1 %4, i64 %y, i64 %5
58  ret i64 %6
59}
60
61define i64 @test_shl__all_are_safe(i32 %x, i64 %y) {
62; CHECK-LABEL: @test_shl__all_are_safe(
63; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
64; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
65; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
66; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
67; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
68; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
69; CHECK-NEXT:    ret i64 [[TMP5]]
70;
71  %1 = and i32 %x, 15
72  %2 = shl i32 %1, 2
73  %3 = zext i32 %2 to i64
74  %4 = icmp eq i32 %1, 0
75  %5 = ashr i64 %y, %3
76  %6 = select i1 %4, i64 %y, i64 %5
77  ret i64 %6
78}
79
80define i64 @test_shl_nuw_nsw__nuw_is_safe(i32 %x, i64 %y) {
81; CHECK-LABEL: @test_shl_nuw_nsw__nuw_is_safe(
82; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
83; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
84; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
85; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
86; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
87; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
88; CHECK-NEXT:    ret i64 [[TMP5]]
89;
90  %1 = and i32 %x, 1073741822
91  %2 = shl nuw nsw i32 %1, 2
92  %3 = zext i32 %2 to i64
93  %4 = icmp eq i32 %1, 0
94  %5 = ashr i64 %y, %3
95  %6 = select i1 %4, i64 %y, i64 %5
96  ret i64 %6
97}
98
99define i64 @test_shl_nuw__nuw_is_safe(i32 %x, i64 %y) {
100; CHECK-LABEL: @test_shl_nuw__nuw_is_safe(
101; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
102; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 2
103; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
104; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
105; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
106; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
107; CHECK-NEXT:    ret i64 [[TMP5]]
108;
109  %1 = and i32 %x, 1073741822
110  %2 = shl nuw i32 %1, 2
111  %3 = zext i32 %2 to i64
112  %4 = icmp eq i32 %1, 0
113  %5 = ashr i64 %y, %3
114  %6 = select i1 %4, i64 %y, i64 %5
115  ret i64 %6
116}
117
118define i64 @test_shl_nsw__nuw_is_safe(i32 %x, i64 %y) {
119; CHECK-LABEL: @test_shl_nsw__nuw_is_safe(
120; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
121; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
122; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
123; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
124; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
125; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
126; CHECK-NEXT:    ret i64 [[TMP5]]
127;
128  %1 = and i32 %x, 1073741822
129  %2 = shl nsw i32 %1, 2
130  %3 = zext i32 %2 to i64
131  %4 = icmp eq i32 %1, 0
132  %5 = ashr i64 %y, %3
133  %6 = select i1 %4, i64 %y, i64 %5
134  ret i64 %6
135}
136
137define i64 @test_shl__nuw_is_safe(i32 %x, i64 %y) {
138; CHECK-LABEL: @test_shl__nuw_is_safe(
139; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
140; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 2
141; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
142; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
143; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
144; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
145; CHECK-NEXT:    ret i64 [[TMP5]]
146;
147  %1 = and i32 %x, 1073741822
148  %2 = shl i32 %1, 2
149  %3 = zext i32 %2 to i64
150  %4 = icmp eq i32 %1, 0
151  %5 = ashr i64 %y, %3
152  %6 = select i1 %4, i64 %y, i64 %5
153  ret i64 %6
154}
155
156define i32 @test_shl_nuw_nsw__nsw_is_safe(i32 %x) {
157; CHECK-LABEL: @test_shl_nuw_nsw__nsw_is_safe(
158; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
159; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
160; CHECK-NEXT:    [[TMP3:%.*]] = shl nuw nsw i32 [[TMP1]], 2
161; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
162; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
163; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
164; CHECK-NEXT:    ret i32 [[TMP6]]
165;
166  %1 = or i32 %x, -83886080
167  %2 = icmp eq i32 %1, -83886079
168  %3 = shl nuw nsw i32 %1, 2
169  %4 = select i1 %2, i32 -335544316, i32 %3
170  %5 = mul i32 %4, %1
171  %6 = mul i32 %5, %3
172  ret i32 %6
173}
174
175define i32 @test_shl_nuw__nsw_is_safe(i32 %x) {
176; CHECK-LABEL: @test_shl_nuw__nsw_is_safe(
177; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
178; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
179; CHECK-NEXT:    [[TMP3:%.*]] = shl nuw nsw i32 [[TMP1]], 2
180; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
181; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
182; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
183; CHECK-NEXT:    ret i32 [[TMP6]]
184;
185  %1 = or i32 %x, -83886080
186  %2 = icmp eq i32 %1, -83886079
187  %3 = shl nuw i32 %1, 2
188  %4 = select i1 %2, i32 -335544316, i32 %3
189  %5 = mul i32 %4, %1
190  %6 = mul i32 %5, %3
191  ret i32 %6
192}
193
194define i32 @test_shl_nsw__nsw_is_safe(i32 %x) {
195; CHECK-LABEL: @test_shl_nsw__nsw_is_safe(
196; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
197; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
198; CHECK-NEXT:    [[TMP3:%.*]] = shl nsw i32 [[TMP1]], 2
199; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
200; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
201; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
202; CHECK-NEXT:    ret i32 [[TMP6]]
203;
204  %1 = or i32 %x, -83886080
205  %2 = icmp eq i32 %1, -83886079
206  %3 = shl nsw i32 %1, 2
207  %4 = select i1 %2, i32 -335544316, i32 %3
208  %5 = mul i32 %4, %1
209  %6 = mul i32 %5, %3
210  ret i32 %6
211}
212
213define i32 @test_shl__nsw_is_safe(i32 %x) {
214; CHECK-LABEL: @test_shl__nsw_is_safe(
215; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
216; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
217; CHECK-NEXT:    [[TMP3:%.*]] = shl nsw i32 [[TMP1]], 2
218; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
219; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
220; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
221; CHECK-NEXT:    ret i32 [[TMP6]]
222;
223  %1 = or i32 %x, -83886080
224  %2 = icmp eq i32 %1, -83886079
225  %3 = shl i32 %1, 2
226  %4 = select i1 %2, i32 -335544316, i32 %3
227  %5 = mul i32 %4, %1
228  %6 = mul i32 %5, %3
229  ret i32 %6
230}
231
232
233define i64 @test_shl_nuw_nsw__none_are_safe(i32 %x, i64 %y) {
234; CHECK-LABEL: @test_shl_nuw_nsw__none_are_safe(
235; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
236; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
237; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
238; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
239; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
240; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
241; CHECK-NEXT:    ret i64 [[TMP5]]
242;
243  %1 = and i32 %x, 4294967294
244  %2 = shl nuw nsw i32 %1, 2
245  %3 = zext i32 %2 to i64
246  %4 = icmp eq i32 %1, 0
247  %5 = ashr i64 %y, %3
248  %6 = select i1 %4, i64 %y, i64 %5
249  ret i64 %6
250}
251
252define i64 @test_shl_nuw__none_are_safe(i32 %x, i64 %y) {
253; CHECK-LABEL: @test_shl_nuw__none_are_safe(
254; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
255; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 2
256; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
257; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
258; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
259; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
260; CHECK-NEXT:    ret i64 [[TMP5]]
261;
262  %1 = and i32 %x, 4294967294
263  %2 = shl nuw i32 %1, 2
264  %3 = zext i32 %2 to i64
265  %4 = icmp eq i32 %1, 0
266  %5 = ashr i64 %y, %3
267  %6 = select i1 %4, i64 %y, i64 %5
268  ret i64 %6
269}
270
271define i64 @test_shl_nsw__none_are_safe(i32 %x, i64 %y) {
272; CHECK-LABEL: @test_shl_nsw__none_are_safe(
273; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
274; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
275; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
276; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
277; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
278; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
279; CHECK-NEXT:    ret i64 [[TMP5]]
280;
281  %1 = and i32 %x, 4294967294
282  %2 = shl nsw i32 %1, 2
283  %3 = zext i32 %2 to i64
284  %4 = icmp eq i32 %1, 0
285  %5 = ashr i64 %y, %3
286  %6 = select i1 %4, i64 %y, i64 %5
287  ret i64 %6
288}
289
290define i64 @test_shl__none_are_safe(i32 %x, i64 %y) {
291; CHECK-LABEL: @test_shl__none_are_safe(
292; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
293; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
294; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
295; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
296; CHECK-NEXT:    ret i64 [[TMP4]]
297;
298  %1 = and i32 %x, 4294967294
299  %2 = shl i32 %1, 2
300  %3 = zext i32 %2 to i64
301  %4 = icmp eq i32 %1, 0
302  %5 = ashr i64 %y, %3
303  %6 = select i1 %4, i64 %y, i64 %5
304  ret i64 %6
305}
306
307define i64 @test_lshr_exact__exact_is_safe(i32 %x, i64 %y) {
308; CHECK-LABEL: @test_lshr_exact__exact_is_safe(
309; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 60
310; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
311; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
312; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
313; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
314; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
315; CHECK-NEXT:    ret i64 [[TMP5]]
316;
317  %1 = and i32 %x, 60
318  %2 = lshr exact i32 %1, 2
319  %3 = zext i32 %2 to i64
320  %4 = icmp eq i32 %1, 0
321  %5 = ashr i64 %y, %3
322  %6 = select i1 %4, i64 %y, i64 %5
323  ret i64 %6
324}
325
326define i64 @test_lshr__exact_is_safe(i32 %x, i64 %y) {
327; CHECK-LABEL: @test_lshr__exact_is_safe(
328; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 60
329; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
330; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
331; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
332; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
333; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
334; CHECK-NEXT:    ret i64 [[TMP5]]
335;
336  %1 = and i32 %x, 60
337  %2 = lshr i32 %1, 2
338  %3 = zext i32 %2 to i64
339  %4 = icmp eq i32 %1, 0
340  %5 = ashr i64 %y, %3
341  %6 = select i1 %4, i64 %y, i64 %5
342  ret i64 %6
343}
344
345define i64 @test_lshr_exact__exact_is_unsafe(i32 %x, i64 %y) {
346; CHECK-LABEL: @test_lshr_exact__exact_is_unsafe(
347; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 63
348; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
349; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
350; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
351; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
352; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
353; CHECK-NEXT:    ret i64 [[TMP5]]
354;
355  %1 = and i32 %x, 63
356  %2 = lshr exact i32 %1, 2
357  %3 = zext i32 %2 to i64
358  %4 = icmp eq i32 %1, 0
359  %5 = ashr i64 %y, %3
360  %6 = select i1 %4, i64 %y, i64 %5
361  ret i64 %6
362}
363
364define i64 @test_lshr__exact_is_unsafe(i32 %x, i64 %y) {
365; CHECK-LABEL: @test_lshr__exact_is_unsafe(
366; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
367; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 15
368; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
369; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
370; CHECK-NEXT:    ret i64 [[TMP4]]
371;
372  %1 = and i32 %x, 63
373  %2 = lshr i32 %1, 2
374  %3 = zext i32 %2 to i64
375  %4 = icmp eq i32 %1, 0
376  %5 = ashr i64 %y, %3
377  %6 = select i1 %4, i64 %y, i64 %5
378  ret i64 %6
379}
380
381define i64 @test_ashr_exact__exact_is_safe(i32 %x, i64 %y) {
382; CHECK-LABEL: @test_ashr_exact__exact_is_safe(
383; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483588
384; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
385; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
386; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
387; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
388; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
389; CHECK-NEXT:    ret i64 [[TMP5]]
390;
391  %1 = and i32 %x, -2147483588
392  %2 = ashr exact i32 %1, 2
393  %3 = zext i32 %2 to i64
394  %4 = icmp eq i32 %1, 0
395  %5 = ashr i64 %y, %3
396  %6 = select i1 %4, i64 %y, i64 %5
397  ret i64 %6
398}
399
400define i64 @test_ashr__exact_is_safe(i32 %x, i64 %y) {
401; CHECK-LABEL: @test_ashr__exact_is_safe(
402; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483588
403; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
404; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
405; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
406; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
407; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
408; CHECK-NEXT:    ret i64 [[TMP5]]
409;
410  %1 = and i32 %x, -2147483588
411  %2 = ashr i32 %1, 2
412  %3 = zext i32 %2 to i64
413  %4 = icmp eq i32 %1, 0
414  %5 = ashr i64 %y, %3
415  %6 = select i1 %4, i64 %y, i64 %5
416  ret i64 %6
417}
418
419define i64 @test_ashr_exact__exact_is_unsafe(i32 %x, i64 %y) {
420; CHECK-LABEL: @test_ashr_exact__exact_is_unsafe(
421; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483585
422; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
423; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
424; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
425; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
426; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
427; CHECK-NEXT:    ret i64 [[TMP5]]
428;
429  %1 = and i32 %x, -2147483585
430  %2 = ashr exact i32 %1, 2
431  %3 = zext i32 %2 to i64
432  %4 = icmp eq i32 %1, 0
433  %5 = ashr i64 %y, %3
434  %6 = select i1 %4, i64 %y, i64 %5
435  ret i64 %6
436}
437
438define i64 @test_ashr__exact_is_unsafe(i32 %x, i64 %y) {
439; CHECK-LABEL: @test_ashr__exact_is_unsafe(
440; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 2
441; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -536870897
442; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
443; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
444; CHECK-NEXT:    ret i64 [[TMP4]]
445;
446  %1 = and i32 %x, -2147483585
447  %2 = ashr i32 %1, 2
448  %3 = zext i32 %2 to i64
449  %4 = icmp eq i32 %1, 0
450  %5 = ashr i64 %y, %3
451  %6 = select i1 %4, i64 %y, i64 %5
452  ret i64 %6
453}
454
455define i32 @test_add_nuw_nsw__all_are_safe(i32 %x) {
456; CHECK-LABEL: @test_add_nuw_nsw__all_are_safe(
457; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
458; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
459; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
460; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
461; CHECK-NEXT:    ret i32 [[SEL]]
462;
463  %and = and i32 %x, 1073741823
464  %cmp = icmp eq i32 %and, 3
465  %add = add nuw nsw i32 %and, 1
466  %sel = select i1 %cmp, i32 4, i32 %add
467  ret i32 %sel
468}
469
470define i32 @test_add_nuw__all_are_safe(i32 %x) {
471; CHECK-LABEL: @test_add_nuw__all_are_safe(
472; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
473; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
474; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
475; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
476; CHECK-NEXT:    ret i32 [[SEL]]
477;
478  %and = and i32 %x, 1073741823
479  %cmp = icmp eq i32 %and, 3
480  %add = add nuw i32 %and, 1
481  %sel = select i1 %cmp, i32 4, i32 %add
482  ret i32 %sel
483}
484
485define i32 @test_add_nsw__all_are_safe(i32 %x) {
486; CHECK-LABEL: @test_add_nsw__all_are_safe(
487; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
488; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
489; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
490; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
491; CHECK-NEXT:    ret i32 [[SEL]]
492;
493  %and = and i32 %x, 1073741823
494  %cmp = icmp eq i32 %and, 3
495  %add = add nsw i32 %and, 1
496  %sel = select i1 %cmp, i32 4, i32 %add
497  ret i32 %sel
498}
499
500define i32 @test_add__all_are_safe(i32 %x) {
501; CHECK-LABEL: @test_add__all_are_safe(
502; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
503; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
504; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
505; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
506; CHECK-NEXT:    ret i32 [[SEL]]
507;
508  %and = and i32 %x, 1073741823
509  %cmp = icmp eq i32 %and, 3
510  %add = add i32 %and, 1
511  %sel = select i1 %cmp, i32 4, i32 %add
512  ret i32 %sel
513}
514
515define i32 @test_add_nuw_nsw__nuw_is_safe(i32 %x) {
516; CHECK-LABEL: @test_add_nuw_nsw__nuw_is_safe(
517; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
518; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
519; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
520; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
521; CHECK-NEXT:    ret i32 [[SEL]]
522;
523  %and = and i32 %x, 2147483647
524  %cmp = icmp eq i32 %and, 2147483647
525  %add = add nuw nsw i32 %and, 1
526  %sel = select i1 %cmp, i32 -2147483648, i32 %add
527  ret i32 %sel
528}
529
530define i32 @test_add_nuw__nuw_is_safe(i32 %x) {
531; CHECK-LABEL: @test_add_nuw__nuw_is_safe(
532; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
533; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
534; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[AND]], 1
535; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
536; CHECK-NEXT:    ret i32 [[SEL]]
537;
538  %and = and i32 %x, 2147483647
539  %cmp = icmp eq i32 %and, 2147483647
540  %add = add nuw i32 %and, 1
541  %sel = select i1 %cmp, i32 -2147483648, i32 %add
542  ret i32 %sel
543}
544
545define i32 @test_add_nsw__nuw_is_safe(i32 %x) {
546; CHECK-LABEL: @test_add_nsw__nuw_is_safe(
547; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
548; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
549; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
550; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
551; CHECK-NEXT:    ret i32 [[SEL]]
552;
553  %and = and i32 %x, 2147483647
554  %cmp = icmp eq i32 %and, 2147483647
555  %add = add nsw i32 %and, 1
556  %sel = select i1 %cmp, i32 -2147483648, i32 %add
557  ret i32 %sel
558}
559
560define i32 @test_add__nuw_is_safe(i32 %x) {
561; CHECK-LABEL: @test_add__nuw_is_safe(
562; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
563; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
564; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[AND]], 1
565; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
566; CHECK-NEXT:    ret i32 [[SEL]]
567;
568  %and = and i32 %x, 2147483647
569  %cmp = icmp eq i32 %and, 2147483647
570  %add = add i32 %and, 1
571  %sel = select i1 %cmp, i32 -2147483648, i32 %add
572  ret i32 %sel
573}
574
575define i32 @test_add_nuw_nsw__nsw_is_safe(i32 %x) {
576; CHECK-LABEL: @test_add_nuw_nsw__nsw_is_safe(
577; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
578; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
579; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[OR]], 1
580; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
581; CHECK-NEXT:    ret i32 [[SEL]]
582;
583  %or = or i32 %x, -2147483648
584  %cmp = icmp eq i32 %or, -1
585  %add = add nuw nsw i32 %or, 1
586  %sel = select i1 %cmp, i32 0, i32 %add
587  ret i32 %sel
588}
589
590define i32 @test_add_nuw__nsw_is_safe(i32 %x) {
591; CHECK-LABEL: @test_add_nuw__nsw_is_safe(
592; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
593; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
594; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[OR]], 1
595; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
596; CHECK-NEXT:    ret i32 [[SEL]]
597;
598  %or = or i32 %x, -2147483648
599  %cmp = icmp eq i32 %or, -1
600  %add = add nuw i32 %or, 1
601  %sel = select i1 %cmp, i32 0, i32 %add
602  ret i32 %sel
603}
604
605define i32 @test_add_nsw__nsw_is_safe(i32 %x) {
606; CHECK-LABEL: @test_add_nsw__nsw_is_safe(
607; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
608; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
609; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[OR]], 1
610; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
611; CHECK-NEXT:    ret i32 [[SEL]]
612;
613  %or = or i32 %x, -2147483648
614  %cmp = icmp eq i32 %or, -1
615  %add = add nsw i32 %or, 1
616  %sel = select i1 %cmp, i32 0, i32 %add
617  ret i32 %sel
618}
619
620define i32 @test_add__nsw_is_safe(i32 %x) {
621; CHECK-LABEL: @test_add__nsw_is_safe(
622; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
623; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
624; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[OR]], 1
625; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
626; CHECK-NEXT:    ret i32 [[SEL]]
627;
628  %or = or i32 %x, -2147483648
629  %cmp = icmp eq i32 %or, -1
630  %add = add i32 %or, 1
631  %sel = select i1 %cmp, i32 0, i32 %add
632  ret i32 %sel
633}
634
635define i32 @test_add_nuw_nsw__none_are_safe(i32 %x) {
636; CHECK-LABEL: @test_add_nuw_nsw__none_are_safe(
637; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
638; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], 1
639; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
640; CHECK-NEXT:    ret i32 [[SEL]]
641;
642  %cmp = icmp eq i32 %x, 3
643  %add = add nuw nsw i32 %x, 1
644  %sel = select i1 %cmp, i32 4, i32 %add
645  ret i32 %sel
646}
647
648define i32 @test_add_nuw__none_are_safe(i32 %x) {
649; CHECK-LABEL: @test_add_nuw__none_are_safe(
650; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
651; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[X]], 1
652; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
653; CHECK-NEXT:    ret i32 [[SEL]]
654;
655  %cmp = icmp eq i32 %x, 3
656  %add = add nuw i32 %x, 1
657  %sel = select i1 %cmp, i32 4, i32 %add
658  ret i32 %sel
659}
660
661define i32 @test_add_nsw__none_are_safe(i32 %x) {
662; CHECK-LABEL: @test_add_nsw__none_are_safe(
663; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
664; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X]], 1
665; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
666; CHECK-NEXT:    ret i32 [[SEL]]
667;
668  %cmp = icmp eq i32 %x, 3
669  %add = add nsw i32 %x, 1
670  %sel = select i1 %cmp, i32 4, i32 %add
671  ret i32 %sel
672}
673
674define i32 @test_add__none_are_safe(i32 %x) {
675; CHECK-LABEL: @test_add__none_are_safe(
676; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 1
677; CHECK-NEXT:    ret i32 [[ADD]]
678;
679  %cmp = icmp eq i32 %x, 3
680  %add = add i32 %x, 1
681  %sel = select i1 %cmp, i32 4, i32 %add
682  ret i32 %sel
683}
684
685define i32 @test_sub_nuw_nsw__all_are_safe(i32 %x) {
686; CHECK-LABEL: @test_sub_nuw_nsw__all_are_safe(
687; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
688; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
689; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
690; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
691; CHECK-NEXT:    ret i32 [[SEL]]
692;
693  %and = and i32 %x, 255
694  %cmp = icmp eq i32 %and, 6
695  %sub = sub nuw nsw i32 -254, %and
696  %sel = select i1 %cmp, i32 -260, i32 %sub
697  ret i32 %sel
698}
699
700define i32 @test_sub_nuw__all_are_safe(i32 %x) {
701; CHECK-LABEL: @test_sub_nuw__all_are_safe(
702; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
703; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
704; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
705; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
706; CHECK-NEXT:    ret i32 [[SEL]]
707;
708  %and = and i32 %x, 255
709  %cmp = icmp eq i32 %and, 6
710  %sub = sub nuw i32 -254, %and
711  %sel = select i1 %cmp, i32 -260, i32 %sub
712  ret i32 %sel
713}
714
715define i32 @test_sub_nsw__all_are_safe(i32 %x) {
716; CHECK-LABEL: @test_sub_nsw__all_are_safe(
717; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
718; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
719; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
720; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
721; CHECK-NEXT:    ret i32 [[SEL]]
722;
723  %and = and i32 %x, 255
724  %cmp = icmp eq i32 %and, 6
725  %sub = sub nsw i32 -254, %and
726  %sel = select i1 %cmp, i32 -260, i32 %sub
727  ret i32 %sel
728}
729
730define i32 @test_sub__all_are_safe(i32 %x) {
731; CHECK-LABEL: @test_sub__all_are_safe(
732; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
733; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
734; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
735; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
736; CHECK-NEXT:    ret i32 [[SEL]]
737;
738  %and = and i32 %x, 255
739  %cmp = icmp eq i32 %and, 6
740  %sub = sub i32 -254, %and
741  %sel = select i1 %cmp, i32 -260, i32 %sub
742  ret i32 %sel
743}
744
745define i32 @test_sub_nuw_nsw__nuw_is_safe(i32 %x) {
746; CHECK-LABEL: @test_sub_nuw_nsw__nuw_is_safe(
747; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
748; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
749; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[AND]]
750; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
751; CHECK-NEXT:    ret i32 [[SEL]]
752;
753  %and = and i32 %x, 2147483647
754  %cmp = icmp eq i32 %and, 1073741824
755  %sub = sub nuw nsw i32 -2147483648, %and
756  %sel = select i1 %cmp, i32 1073741824, i32 %sub
757  ret i32 %sel
758}
759
760define i32 @test_sub_nuw__nuw_is_safe(i32 %x) {
761; CHECK-LABEL: @test_sub_nuw__nuw_is_safe(
762; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
763; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
764; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[AND]]
765; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
766; CHECK-NEXT:    ret i32 [[SEL]]
767;
768  %and = and i32 %x, 2147483647
769  %cmp = icmp eq i32 %and, 1073741824
770  %sub = sub nuw i32 -2147483648, %and
771  %sel = select i1 %cmp, i32 1073741824, i32 %sub
772  ret i32 %sel
773}
774
775define i32 @test_sub_nsw__nuw_is_safe(i32 %x) {
776; CHECK-LABEL: @test_sub_nsw__nuw_is_safe(
777; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
778; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
779; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[AND]]
780; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
781; CHECK-NEXT:    ret i32 [[SEL]]
782;
783  %and = and i32 %x, 2147483647
784  %cmp = icmp eq i32 %and, 1073741824
785  %sub = sub nsw i32 -2147483648, %and
786  %sel = select i1 %cmp, i32 1073741824, i32 %sub
787  ret i32 %sel
788}
789
790define i32 @test_sub__nuw_is_safe(i32 %x) {
791; CHECK-LABEL: @test_sub__nuw_is_safe(
792; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
793; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
794; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[AND]]
795; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
796; CHECK-NEXT:    ret i32 [[SEL]]
797;
798  %and = and i32 %x, 2147483647
799  %cmp = icmp eq i32 %and, 1073741824
800  %sub = sub i32 -2147483648, %and
801  %sel = select i1 %cmp, i32 1073741824, i32 %sub
802  ret i32 %sel
803}
804
805define i32 @test_sub_nuw_nsw__nsw_is_safe(i32 %x) {
806; CHECK-LABEL: @test_sub_nuw_nsw__nsw_is_safe(
807; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
808; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
809; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[OR]]
810; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
811; CHECK-NEXT:    ret i32 [[SEL]]
812;
813  %or = or i32 %x, -2147483648
814  %cmp = icmp eq i32 %or, -2147483647
815  %sub = sub nuw nsw i32 -2147483648, %or
816  %sel = select i1 %cmp, i32 -1, i32 %sub
817  ret i32 %sel
818}
819
820define i32 @test_sub_nuw__nsw_is_safe(i32 %x) {
821; CHECK-LABEL: @test_sub_nuw__nsw_is_safe(
822; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
823; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
824; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[OR]]
825; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
826; CHECK-NEXT:    ret i32 [[SEL]]
827;
828  %or = or i32 %x, -2147483648
829  %cmp = icmp eq i32 %or, -2147483647
830  %sub = sub nuw i32 -2147483648, %or
831  %sel = select i1 %cmp, i32 -1, i32 %sub
832  ret i32 %sel
833}
834
835define i32 @test_sub_nsw__nsw_is_safe(i32 %x) {
836; CHECK-LABEL: @test_sub_nsw__nsw_is_safe(
837; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
838; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
839; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[OR]]
840; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
841; CHECK-NEXT:    ret i32 [[SEL]]
842;
843  %or = or i32 %x, -2147483648
844  %cmp = icmp eq i32 %or, -2147483647
845  %sub = sub nsw i32 -2147483648, %or
846  %sel = select i1 %cmp, i32 -1, i32 %sub
847  ret i32 %sel
848}
849
850define i32 @test_sub__nsw_is_safe(i32 %x) {
851; CHECK-LABEL: @test_sub__nsw_is_safe(
852; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
853; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
854; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[OR]]
855; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
856; CHECK-NEXT:    ret i32 [[SEL]]
857;
858  %or = or i32 %x, -2147483648
859  %cmp = icmp eq i32 %or, -2147483647
860  %sub = sub i32 -2147483648, %or
861  %sel = select i1 %cmp, i32 -1, i32 %sub
862  ret i32 %sel
863}
864
865define i32 @test_sub_nuw_nsw__none_are_safe(i32 %x) {
866; CHECK-LABEL: @test_sub_nuw_nsw__none_are_safe(
867; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 1
868; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[X]]
869; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[SUB]]
870; CHECK-NEXT:    ret i32 [[SEL]]
871;
872  %cmp = icmp eq i32 %x, 1
873  %sub = sub nuw nsw i32 -2147483648, %x
874  %sel = select i1 %cmp, i32 2147483647, i32 %sub
875  ret i32 %sel
876}
877
878define i32 @test_sub_nuw__none_are_safe(i32 %x) {
879; CHECK-LABEL: @test_sub_nuw__none_are_safe(
880; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 1
881; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[X]]
882; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[SUB]]
883; CHECK-NEXT:    ret i32 [[SEL]]
884;
885  %cmp = icmp eq i32 %x, 1
886  %sub = sub nuw i32 -2147483648, %x
887  %sel = select i1 %cmp, i32 2147483647, i32 %sub
888  ret i32 %sel
889}
890
891define i32 @test_sub_nsw__none_are_safe(i32 %x) {
892; CHECK-LABEL: @test_sub_nsw__none_are_safe(
893; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 1
894; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[X]]
895; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[SUB]]
896; CHECK-NEXT:    ret i32 [[SEL]]
897;
898  %cmp = icmp eq i32 %x, 1
899  %sub = sub nsw i32 -2147483648, %x
900  %sel = select i1 %cmp, i32 2147483647, i32 %sub
901  ret i32 %sel
902}
903
904define i32 @test_sub__none_are_safe(i32 %x) {
905; CHECK-LABEL: @test_sub__none_are_safe(
906; CHECK-NEXT:    [[SUB:%.*]] = sub i32 -2147483648, [[X:%.*]]
907; CHECK-NEXT:    ret i32 [[SUB]]
908;
909  %cmp = icmp eq i32 %x, 1
910  %sub = sub i32 -2147483648, %x
911  %sel = select i1 %cmp, i32 2147483647, i32 %sub
912  ret i32 %sel
913}
914
915define i32 @test_mul_nuw_nsw__all_are_safe(i32 %x) {
916; CHECK-LABEL: @test_mul_nuw_nsw__all_are_safe(
917; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
918; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
919; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
920; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
921; CHECK-NEXT:    ret i32 [[SEL]]
922;
923  %and = and i32 %x, 255
924  %cmp = icmp eq i32 %and, 17
925  %mul = mul nuw nsw i32 %and, 9
926  %sel = select i1 %cmp, i32 153, i32 %mul
927  ret i32 %sel
928}
929
930define i32 @test_mul_nuw__all_are_safe(i32 %x) {
931; CHECK-LABEL: @test_mul_nuw__all_are_safe(
932; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
933; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
934; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
935; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
936; CHECK-NEXT:    ret i32 [[SEL]]
937;
938  %and = and i32 %x, 255
939  %cmp = icmp eq i32 %and, 17
940  %mul = mul nuw i32 %and, 9
941  %sel = select i1 %cmp, i32 153, i32 %mul
942  ret i32 %sel
943}
944
945define i32 @test_mul_nsw__all_are_safe(i32 %x) {
946; CHECK-LABEL: @test_mul_nsw__all_are_safe(
947; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
948; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
949; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
950; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
951; CHECK-NEXT:    ret i32 [[SEL]]
952;
953  %and = and i32 %x, 255
954  %cmp = icmp eq i32 %and, 17
955  %mul = mul nsw i32 %and, 9
956  %sel = select i1 %cmp, i32 153, i32 %mul
957  ret i32 %sel
958}
959
960define i32 @test_mul__all_are_safe(i32 %x) {
961; CHECK-LABEL: @test_mul__all_are_safe(
962; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
963; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
964; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
965; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
966; CHECK-NEXT:    ret i32 [[SEL]]
967;
968  %and = and i32 %x, 255
969  %cmp = icmp eq i32 %and, 17
970  %mul = mul i32 %and, 9
971  %sel = select i1 %cmp, i32 153, i32 %mul
972  ret i32 %sel
973}
974
975define i32 @test_mul_nuw_nsw__nuw_is_safe(i32 %x) {
976; CHECK-LABEL: @test_mul_nuw_nsw__nuw_is_safe(
977; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
978; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
979; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
980; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
981; CHECK-NEXT:    ret i32 [[SEL]]
982;
983  %and = and i32 %x, 268435457
984  %cmp = icmp eq i32 %and, 268435456
985  %mul = mul nuw nsw i32 %and, 9
986  %sel = select i1 %cmp, i32 -1879048192, i32 %mul
987  ret i32 %sel
988}
989
990define i32 @test_mul_nuw__nuw_is_safe(i32 %x) {
991; CHECK-LABEL: @test_mul_nuw__nuw_is_safe(
992; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
993; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
994; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[AND]], 9
995; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
996; CHECK-NEXT:    ret i32 [[SEL]]
997;
998  %and = and i32 %x, 268435457
999  %cmp = icmp eq i32 %and, 268435456
1000  %mul = mul nuw i32 %and, 9
1001  %sel = select i1 %cmp, i32 -1879048192, i32 %mul
1002  ret i32 %sel
1003}
1004
1005define i32 @test_mul_nsw__nuw_is_safe(i32 %x) {
1006; CHECK-LABEL: @test_mul_nsw__nuw_is_safe(
1007; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
1008; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
1009; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
1010; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
1011; CHECK-NEXT:    ret i32 [[SEL]]
1012;
1013  %and = and i32 %x, 268435457
1014  %cmp = icmp eq i32 %and, 268435456
1015  %mul = mul nsw i32 %and, 9
1016  %sel = select i1 %cmp, i32 -1879048192, i32 %mul
1017  ret i32 %sel
1018}
1019
1020define i32 @test_mul__nuw_is_safe(i32 %x) {
1021; CHECK-LABEL: @test_mul__nuw_is_safe(
1022; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
1023; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
1024; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[AND]], 9
1025; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
1026; CHECK-NEXT:    ret i32 [[SEL]]
1027;
1028  %and = and i32 %x, 268435457
1029  %cmp = icmp eq i32 %and, 268435456
1030  %mul = mul i32 %and, 9
1031  %sel = select i1 %cmp, i32 -1879048192, i32 %mul
1032  ret i32 %sel
1033}
1034
1035define i32 @test_mul_nuw_nsw__nsw_is_safe(i32 %x) {
1036; CHECK-LABEL: @test_mul_nuw_nsw__nsw_is_safe(
1037; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
1038; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
1039; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
1040; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
1041; CHECK-NEXT:    ret i32 [[SEL]]
1042;
1043  %and = or i32 %x, -83886080
1044  %cmp = icmp eq i32 %and, -83886079
1045  %mul = mul nuw nsw i32 %and, 9
1046  %sel = select i1 %cmp, i32 -754974711, i32 %mul
1047  ret i32 %sel
1048}
1049
1050define i32 @test_mul_nuw__nsw_is_safe(i32 %x) {
1051; CHECK-LABEL: @test_mul_nuw__nsw_is_safe(
1052; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
1053; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
1054; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
1055; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
1056; CHECK-NEXT:    ret i32 [[SEL]]
1057;
1058  %and = or i32 %x, -83886080
1059  %cmp = icmp eq i32 %and, -83886079
1060  %mul = mul nuw i32 %and, 9
1061  %sel = select i1 %cmp, i32 -754974711, i32 %mul
1062  ret i32 %sel
1063}
1064
1065define i32 @test_mul_nsw__nsw_is_safe(i32 %x) {
1066; CHECK-LABEL: @test_mul_nsw__nsw_is_safe(
1067; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
1068; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
1069; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[AND]], 9
1070; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
1071; CHECK-NEXT:    ret i32 [[SEL]]
1072;
1073  %and = or i32 %x, -83886080
1074  %cmp = icmp eq i32 %and, -83886079
1075  %mul = mul nsw i32 %and, 9
1076  %sel = select i1 %cmp, i32 -754974711, i32 %mul
1077  ret i32 %sel
1078}
1079
1080define i32 @test_mul__nsw_is_safe(i32 %x) {
1081; CHECK-LABEL: @test_mul__nsw_is_safe(
1082; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
1083; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
1084; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[AND]], 9
1085; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
1086; CHECK-NEXT:    ret i32 [[SEL]]
1087;
1088  %and = or i32 %x, -83886080
1089  %cmp = icmp eq i32 %and, -83886079
1090  %mul = mul i32 %and, 9
1091  %sel = select i1 %cmp, i32 -754974711, i32 %mul
1092  ret i32 %sel
1093}
1094
1095define i32 @test_mul_nuw_nsw__none_are_safe(i32 %x) {
1096; CHECK-LABEL: @test_mul_nuw_nsw__none_are_safe(
1097; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 805306368
1098; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[X]], 9
1099; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1342177280, i32 [[MUL]]
1100; CHECK-NEXT:    ret i32 [[SEL]]
1101;
1102  %cmp = icmp eq i32 %x, 805306368
1103  %mul = mul nuw nsw i32 %x, 9
1104  %sel = select i1 %cmp, i32 -1342177280, i32 %mul
1105  ret i32 %sel
1106}
1107
1108define i32 @test_mul_nuw__none_are_safe(i32 %x) {
1109; CHECK-LABEL: @test_mul_nuw__none_are_safe(
1110; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 805306368
1111; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X]], 9
1112; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1342177280, i32 [[MUL]]
1113; CHECK-NEXT:    ret i32 [[SEL]]
1114;
1115  %cmp = icmp eq i32 %x, 805306368
1116  %mul = mul nuw i32 %x, 9
1117  %sel = select i1 %cmp, i32 -1342177280, i32 %mul
1118  ret i32 %sel
1119}
1120
1121define i32 @test_mul_nsw__none_are_safe(i32 %x) {
1122; CHECK-LABEL: @test_mul_nsw__none_are_safe(
1123; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 805306368
1124; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X]], 9
1125; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1342177280, i32 [[MUL]]
1126; CHECK-NEXT:    ret i32 [[SEL]]
1127;
1128  %cmp = icmp eq i32 %x, 805306368
1129  %mul = mul nsw i32 %x, 9
1130  %sel = select i1 %cmp, i32 -1342177280, i32 %mul
1131  ret i32 %sel
1132}
1133
1134define i32 @test_mul__none_are_safe(i32 %x) {
1135; CHECK-LABEL: @test_mul__none_are_safe(
1136; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], 9
1137; CHECK-NEXT:    ret i32 [[MUL]]
1138;
1139  %cmp = icmp eq i32 %x, 805306368
1140  %mul = mul i32 %x, 9
1141  %sel = select i1 %cmp, i32 -1342177280, i32 %mul
1142  ret i32 %sel
1143}
1144