xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/mul-nsw.ll (revision 13ffde316a8541d77116bd18f73efada236617f3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @use(i1)
5declare void @llvm.assume(i1)
6
7define void @slt_mul_nsw_3_known_positive_1(i8 %start, i8 %high) {
8; CHECK-LABEL: @slt_mul_nsw_3_known_positive_1(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
11; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
12; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
13; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
14; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
15; CHECK:       then:
16; CHECK-NEXT:    call void @use(i1 true)
17; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
18; CHECK-NEXT:    call void @use(i1 true)
19; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
20; CHECK-NEXT:    call void @use(i1 true)
21; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
22; CHECK-NEXT:    call void @use(i1 true)
23; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
24; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
25; CHECK-NEXT:    call void @use(i1 [[C_3]])
26; CHECK-NEXT:    ret void
27; CHECK:       else:
28; CHECK-NEXT:    ret void
29;
30entry:
31  %mul.3  = mul nsw i8 %start, 3
32  %c.1 = icmp slt i8 %mul.3, %high
33  %c.2 = icmp sgt i8 %start, 0
34  %and = and i1 %c.1, %c.2
35  br i1 %and, label %then, label %else
36
37then:
38  %t.0 = icmp slt i8 %start, %high
39  call void @use(i1 %t.0)
40  %start.1 = mul nsw i8 %start, 1
41  %t.1 = icmp slt i8 %start.1, %high
42  call void @use(i1 %t.1)
43  %start.2 = mul nsw i8 %start, 2
44  %t.2 = icmp slt i8 %start.2, %high
45  call void @use(i1 %t.2)
46  %start.3 = mul nsw i8 %start, 3
47  %t.3 = icmp slt i8 %start.3, %high
48  call void @use(i1 %t.3)
49  %start.4 = mul nsw i8 %start, 4
50  %c.3 = icmp slt i8 %start.4, %high
51  call void @use(i1 %c.3)
52  ret void
53
54else:
55  ret void
56}
57
58define void @slt_mul_nsw_3_known_positive_2(i8 %start, i8 %high) {
59; CHECK-LABEL: @slt_mul_nsw_3_known_positive_2(
60; CHECK-NEXT:  entry:
61; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
62; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
63; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
64; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
65; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
66; CHECK:       then:
67; CHECK-NEXT:    ret void
68; CHECK:       else:
69; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START]], [[HIGH]]
70; CHECK-NEXT:    call void @use(i1 [[C_4]])
71; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
72; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
73; CHECK-NEXT:    call void @use(i1 [[C_5]])
74; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
75; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
76; CHECK-NEXT:    call void @use(i1 [[C_6]])
77; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
78; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
79; CHECK-NEXT:    call void @use(i1 [[C_7]])
80; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
81; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
82; CHECK-NEXT:    call void @use(i1 [[C_8]])
83; CHECK-NEXT:    ret void
84;
85entry:
86  %mul.3  = mul nsw i8 %start, 3
87  %c.1 = icmp slt i8 %mul.3, %high
88  %c.2 = icmp sgt i8 %start, 0
89  %and = and i1 %c.1, %c.2
90  br i1 %and, label %then, label %else
91
92then:
93  ret void
94
95else:
96  %c.4 = icmp slt i8 %start, %high
97  call void @use(i1 %c.4)
98  %else.start.1 = mul nsw i8 %start, 1
99  %c.5 = icmp slt i8 %else.start.1, %high
100  call void @use(i1 %c.5)
101  %else.start.2 = mul nsw i8 %start, 2
102  %c.6 = icmp slt i8 %else.start.2, %high
103  call void @use(i1 %c.6)
104  %else.start.3 = mul nsw i8 %start, 3
105  %c.7 = icmp slt i8 %else.start.3, %high
106  call void @use(i1 %c.7)
107  %else.start.4 = mul nsw i8 %start, 4
108  %c.8 = icmp slt i8 %else.start.4, %high
109  call void @use(i1 %c.8)
110  ret void
111}
112
113define void @slt_mul_no_nsw_3_known_positive_1(i8 %start, i8 %high) {
114; CHECK-LABEL: @slt_mul_no_nsw_3_known_positive_1(
115; CHECK-NEXT:  entry:
116; CHECK-NEXT:    [[MUL_3:%.*]] = mul i8 [[START:%.*]], 3
117; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
118; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
119; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
120; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
121; CHECK:       then:
122; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START]], [[HIGH]]
123; CHECK-NEXT:    call void @use(i1 [[C_3]])
124; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
125; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
126; CHECK-NEXT:    call void @use(i1 [[C_4]])
127; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
128; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
129; CHECK-NEXT:    call void @use(i1 [[C_5]])
130; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
131; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[START_3]], [[HIGH]]
132; CHECK-NEXT:    call void @use(i1 [[C_6]])
133; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
134; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
135; CHECK-NEXT:    call void @use(i1 [[C_7]])
136; CHECK-NEXT:    ret void
137; CHECK:       else:
138; CHECK-NEXT:    ret void
139;
140entry:
141  %mul.3  = mul i8 %start, 3
142  %c.1 = icmp slt i8 %mul.3, %high
143  %c.2 = icmp sgt i8 %start, 0
144  %and = and i1 %c.1, %c.2
145  br i1 %and, label %then, label %else
146
147then:
148  %c.3 = icmp slt i8 %start, %high
149  call void @use(i1 %c.3)
150  %start.1 = mul nsw i8 %start, 1
151  %c.4 = icmp slt i8 %start.1, %high
152  call void @use(i1 %c.4)
153  %start.2 = mul nsw i8 %start, 2
154  %c.5 = icmp slt i8 %start.2, %high
155  call void @use(i1 %c.5)
156  %start.3 = mul nsw i8 %start, 3
157  %c.6 = icmp slt i8 %start.3, %high
158  call void @use(i1 %c.6)
159  %start.4 = mul nsw i8 %start, 4
160  %c.7 = icmp slt i8 %start.4, %high
161  call void @use(i1 %c.7)
162  ret void
163
164else:
165  ret void
166}
167
168define void @slt_mul_no_nsw_3_known_positive_2(i8 %start, i8 %high) {
169; CHECK-LABEL: @slt_mul_no_nsw_3_known_positive_2(
170; CHECK-NEXT:  entry:
171; CHECK-NEXT:    [[MUL_3:%.*]] = mul i8 [[START:%.*]], 3
172; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
173; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
174; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
175; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
176; CHECK:       then:
177; CHECK-NEXT:    ret void
178; CHECK:       else:
179; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[START]], [[HIGH]]
180; CHECK-NEXT:    call void @use(i1 [[C_8]])
181; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
182; CHECK-NEXT:    [[C_9:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
183; CHECK-NEXT:    call void @use(i1 [[C_9]])
184; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
185; CHECK-NEXT:    [[C_10:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
186; CHECK-NEXT:    call void @use(i1 [[C_10]])
187; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
188; CHECK-NEXT:    [[C_11:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
189; CHECK-NEXT:    call void @use(i1 [[C_11]])
190; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
191; CHECK-NEXT:    [[C_12:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
192; CHECK-NEXT:    call void @use(i1 [[C_12]])
193; CHECK-NEXT:    ret void
194;
195entry:
196  %mul.3  = mul i8 %start, 3
197  %c.1 = icmp slt i8 %mul.3, %high
198  %c.2 = icmp sgt i8 %start, 0
199  %and = and i1 %c.1, %c.2
200  br i1 %and, label %then, label %else
201
202then:
203  ret void
204
205else:
206  %c.8 = icmp slt i8 %start, %high
207  call void @use(i1 %c.8)
208  %else.start.1 = mul nsw i8 %start, 1
209  %c.9 = icmp slt i8 %else.start.1, %high
210  call void @use(i1 %c.9)
211  %else.start.2 = mul nsw i8 %start, 2
212  %c.10 = icmp slt i8 %else.start.2, %high
213  call void @use(i1 %c.10)
214  %else.start.3 = mul nsw i8 %start, 3
215  %c.11 = icmp slt i8 %else.start.3, %high
216  call void @use(i1 %c.11)
217  %else.start.4 = mul nsw i8 %start, 4
218  %c.12 = icmp slt i8 %else.start.4, %high
219  call void @use(i1 %c.12)
220  ret void
221}
222
223define void @slt_mul_nsw_3_not_known_positive_1(i8 %start, i8 %high) {
224; CHECK-LABEL: @slt_mul_nsw_3_not_known_positive_1(
225; CHECK-NEXT:  entry:
226; CHECK-NEXT:    [[MUL_3:%.*]] = mul i8 [[START:%.*]], 3
227; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
228; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
229; CHECK:       then:
230; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START]], [[HIGH]]
231; CHECK-NEXT:    call void @use(i1 [[C_3]])
232; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
233; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
234; CHECK-NEXT:    call void @use(i1 [[C_4]])
235; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
236; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
237; CHECK-NEXT:    call void @use(i1 [[C_5]])
238; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
239; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[START_3]], [[HIGH]]
240; CHECK-NEXT:    call void @use(i1 [[C_6]])
241; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
242; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
243; CHECK-NEXT:    call void @use(i1 [[C_7]])
244; CHECK-NEXT:    ret void
245; CHECK:       else:
246; CHECK-NEXT:    ret void
247;
248entry:
249  %mul.3  = mul i8 %start, 3
250  %c.1 = icmp slt i8 %mul.3, %high
251  br i1 %c.1, label %then, label %else
252
253then:
254  %c.3 = icmp slt i8 %start, %high
255  call void @use(i1 %c.3)
256  %start.1 = mul nsw i8 %start, 1
257  %c.4 = icmp slt i8 %start.1, %high
258  call void @use(i1 %c.4)
259  %start.2 = mul nsw i8 %start, 2
260  %c.5 = icmp slt i8 %start.2, %high
261  call void @use(i1 %c.5)
262  %start.3 = mul nsw i8 %start, 3
263  %c.6 = icmp slt i8 %start.3, %high
264  call void @use(i1 %c.6)
265  %start.4 = mul nsw i8 %start, 4
266  %c.7 = icmp slt i8 %start.4, %high
267  call void @use(i1 %c.7)
268  ret void
269
270else:
271  ret void
272}
273
274define void @slt_mul_nsw_3_not_known_positive_2(i8 %start, i8 %high) {
275; CHECK-LABEL: @slt_mul_nsw_3_not_known_positive_2(
276; CHECK-NEXT:  entry:
277; CHECK-NEXT:    [[MUL_3:%.*]] = mul i8 [[START:%.*]], 3
278; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
279; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
280; CHECK:       then:
281; CHECK-NEXT:    ret void
282; CHECK:       else:
283; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[START]], [[HIGH]]
284; CHECK-NEXT:    call void @use(i1 [[C_8]])
285; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
286; CHECK-NEXT:    [[C_9:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
287; CHECK-NEXT:    call void @use(i1 [[C_9]])
288; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
289; CHECK-NEXT:    [[C_10:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
290; CHECK-NEXT:    call void @use(i1 [[C_10]])
291; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
292; CHECK-NEXT:    [[C_11:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
293; CHECK-NEXT:    call void @use(i1 [[C_11]])
294; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
295; CHECK-NEXT:    [[C_12:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
296; CHECK-NEXT:    call void @use(i1 [[C_12]])
297; CHECK-NEXT:    ret void
298;
299entry:
300  %mul.3  = mul i8 %start, 3
301  %c.1 = icmp slt i8 %mul.3, %high
302  br i1 %c.1, label %then, label %else
303
304then:
305  ret void
306
307else:
308  %c.8 = icmp slt i8 %start, %high
309  call void @use(i1 %c.8)
310  %else.start.1 = mul nsw i8 %start, 1
311  %c.9 = icmp slt i8 %else.start.1, %high
312  call void @use(i1 %c.9)
313  %else.start.2 = mul nsw i8 %start, 2
314  %c.10 = icmp slt i8 %else.start.2, %high
315  call void @use(i1 %c.10)
316  %else.start.3 = mul nsw i8 %start, 3
317  %c.11 = icmp slt i8 %else.start.3, %high
318  call void @use(i1 %c.11)
319  %else.start.4 = mul nsw i8 %start, 4
320  %c.12 = icmp slt i8 %else.start.4, %high
321  call void @use(i1 %c.12)
322  ret void
323}
324
325define void @slt_mul_nsw_neg_3_known_negative_1(i8 %start, i8 %high) {
326; CHECK-LABEL: @slt_mul_nsw_neg_3_known_negative_1(
327; CHECK-NEXT:  entry:
328; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], -3
329; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
330; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[START]], 0
331; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
332; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
333; CHECK:       then:
334; CHECK-NEXT:    call void @use(i1 true)
335; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], -1
336; CHECK-NEXT:    call void @use(i1 true)
337; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], -2
338; CHECK-NEXT:    call void @use(i1 true)
339; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], -3
340; CHECK-NEXT:    call void @use(i1 true)
341; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], -4
342; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
343; CHECK-NEXT:    call void @use(i1 [[C_3]])
344; CHECK-NEXT:    ret void
345; CHECK:       else:
346; CHECK-NEXT:    ret void
347;
348entry:
349  %mul.3  = mul nsw i8 %start, -3
350  %c.1 = icmp slt i8 %mul.3, %high
351  %c.2 = icmp slt i8 %start, 0
352  %and = and i1 %c.1, %c.2
353  br i1 %and, label %then, label %else
354
355then:
356  %t.0 = icmp slt i8 %start, %high
357  call void @use(i1 %t.0)
358  %start.1 = mul nsw i8 %start, -1
359  %t.1 = icmp slt i8 %start.1, %high
360  call void @use(i1 %t.1)
361  %start.2 = mul nsw i8 %start, -2
362  %t.2 = icmp slt i8 %start.2, %high
363  call void @use(i1 %t.2)
364  %start.3 = mul nsw i8 %start, -3
365  %t.3 = icmp slt i8 %start.3, %high
366  call void @use(i1 %t.3)
367  %start.4 = mul nsw i8 %start, -4
368  %c.3 = icmp slt i8 %start.4, %high
369  call void @use(i1 %c.3)
370  ret void
371
372else:
373  ret void
374}
375
376define void @slt_mul_nsw_neg_3_known_negative_2(i8 %start, i8 %high) {
377; CHECK-LABEL: @slt_mul_nsw_neg_3_known_negative_2(
378; CHECK-NEXT:  entry:
379; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], -3
380; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
381; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[START]], 0
382; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
383; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
384; CHECK:       then:
385; CHECK-NEXT:    ret void
386; CHECK:       else:
387; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START]], [[HIGH]]
388; CHECK-NEXT:    call void @use(i1 [[C_4]])
389; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], -1
390; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
391; CHECK-NEXT:    call void @use(i1 [[C_5]])
392; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], -2
393; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
394; CHECK-NEXT:    call void @use(i1 [[C_6]])
395; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], -3
396; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
397; CHECK-NEXT:    call void @use(i1 [[C_7]])
398; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], -4
399; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
400; CHECK-NEXT:    call void @use(i1 [[C_8]])
401; CHECK-NEXT:    ret void
402;
403entry:
404  %mul.3  = mul nsw i8 %start, -3
405  %c.1 = icmp slt i8 %mul.3, %high
406  %c.2 = icmp slt i8 %start, 0
407  %and = and i1 %c.1, %c.2
408  br i1 %and, label %then, label %else
409
410then:
411  ret void
412
413else:
414  %c.4 = icmp slt i8 %start, %high
415  call void @use(i1 %c.4)
416  %else.start.1 = mul nsw i8 %start, -1
417  %c.5 = icmp slt i8 %else.start.1, %high
418  call void @use(i1 %c.5)
419  %else.start.2 = mul nsw i8 %start, -2
420  %c.6 = icmp slt i8 %else.start.2, %high
421  call void @use(i1 %c.6)
422  %else.start.3 = mul nsw i8 %start, -3
423  %c.7 = icmp slt i8 %else.start.3, %high
424  call void @use(i1 %c.7)
425  %else.start.4 = mul nsw i8 %start, -4
426  %c.8 = icmp slt i8 %else.start.4, %high
427  call void @use(i1 %c.8)
428  ret void
429}
430
431define void @slt_mul_nsw_3_known_negative_1(i8 %start, i8 %high) {
432; CHECK-LABEL: @slt_mul_nsw_3_known_negative_1(
433; CHECK-NEXT:  entry:
434; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
435; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
436; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[START]], 0
437; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
438; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
439; CHECK:       then:
440; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START]], [[HIGH]]
441; CHECK-NEXT:    call void @use(i1 [[C_3]])
442; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
443; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
444; CHECK-NEXT:    call void @use(i1 [[C_4]])
445; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
446; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
447; CHECK-NEXT:    call void @use(i1 [[C_5]])
448; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
449; CHECK-NEXT:    call void @use(i1 true)
450; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
451; CHECK-NEXT:    call void @use(i1 true)
452; CHECK-NEXT:    ret void
453; CHECK:       else:
454; CHECK-NEXT:    ret void
455;
456entry:
457  %mul.3  = mul nsw i8 %start, 3
458  %c.1 = icmp slt i8 %mul.3, %high
459  %c.2 = icmp slt i8 %start, 0
460  %and = and i1 %c.1, %c.2
461  br i1 %and, label %then, label %else
462
463then:
464  %c.3 = icmp slt i8 %start, %high
465  call void @use(i1 %c.3)
466  %start.1 = mul nsw i8 %start, 1
467  %c.4 = icmp slt i8 %start.1, %high
468  call void @use(i1 %c.4)
469  %start.2 = mul nsw i8 %start, 2
470  %c.5 = icmp slt i8 %start.2, %high
471  call void @use(i1 %c.5)
472  %start.3 = mul nsw i8 %start, 3
473  %t.0 = icmp slt i8 %start.3, %high
474  call void @use(i1 %t.0)
475  %start.4 = mul nsw i8 %start, 4
476  %t.1 = icmp slt i8 %start.4, %high
477  call void @use(i1 %t.1)
478  ret void
479
480else:
481  ret void
482}
483
484define void @slt_mul_nsw_3_known_negative_2(i8 %start, i8 %high) {
485; CHECK-LABEL: @slt_mul_nsw_3_known_negative_2(
486; CHECK-NEXT:  entry:
487; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
488; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
489; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[START]], 0
490; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
491; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
492; CHECK:       then:
493; CHECK-NEXT:    ret void
494; CHECK:       else:
495; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[START]], [[HIGH]]
496; CHECK-NEXT:    call void @use(i1 [[C_6]])
497; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
498; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
499; CHECK-NEXT:    call void @use(i1 [[C_7]])
500; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
501; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
502; CHECK-NEXT:    call void @use(i1 [[C_8]])
503; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
504; CHECK-NEXT:    [[C_9:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
505; CHECK-NEXT:    call void @use(i1 [[C_9]])
506; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
507; CHECK-NEXT:    [[C_10:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
508; CHECK-NEXT:    call void @use(i1 [[C_10]])
509; CHECK-NEXT:    ret void
510;
511entry:
512  %mul.3  = mul nsw i8 %start, 3
513  %c.1 = icmp slt i8 %mul.3, %high
514  %c.2 = icmp slt i8 %start, 0
515  %and = and i1 %c.1, %c.2
516  br i1 %and, label %then, label %else
517
518then:
519  ret void
520
521else:
522  %c.6 = icmp slt i8 %start, %high
523  call void @use(i1 %c.6)
524  %else.start.1 = mul nsw i8 %start, 1
525  %c.7 = icmp slt i8 %else.start.1, %high
526  call void @use(i1 %c.7)
527  %else.start.2 = mul nsw i8 %start, 2
528  %c.8 = icmp slt i8 %else.start.2, %high
529  call void @use(i1 %c.8)
530  %else.start.3 = mul nsw i8 %start, 3
531  %c.9 = icmp slt i8 %else.start.3, %high
532  call void @use(i1 %c.9)
533  %else.start.4 = mul nsw i8 %start, 4
534  %c.10 = icmp slt i8 %else.start.4, %high
535  call void @use(i1 %c.10)
536  ret void
537}
538
539define void @slt_mul_nsw_neg_3_known_positive_1(i8 %start, i8 %high) {
540; CHECK-LABEL: @slt_mul_nsw_neg_3_known_positive_1(
541; CHECK-NEXT:  entry:
542; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], -3
543; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
544; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
545; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
546; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
547; CHECK:       then:
548; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START]], [[HIGH]]
549; CHECK-NEXT:    call void @use(i1 [[C_3]])
550; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], -1
551; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
552; CHECK-NEXT:    call void @use(i1 [[C_4]])
553; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], -2
554; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
555; CHECK-NEXT:    call void @use(i1 [[C_5]])
556; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], -3
557; CHECK-NEXT:    call void @use(i1 true)
558; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], -4
559; CHECK-NEXT:    call void @use(i1 true)
560; CHECK-NEXT:    ret void
561; CHECK:       else:
562; CHECK-NEXT:    ret void
563;
564entry:
565  %mul.3  = mul nsw i8 %start, -3
566  %c.1 = icmp slt i8 %mul.3, %high
567  %c.2 = icmp sgt i8 %start, 0
568  %and = and i1 %c.1, %c.2
569  br i1 %and, label %then, label %else
570
571then:
572  %c.3 = icmp slt i8 %start, %high
573  call void @use(i1 %c.3)
574  %start.1 = mul nsw i8 %start, -1
575  %c.4 = icmp slt i8 %start.1, %high
576  call void @use(i1 %c.4)
577  %start.2 = mul nsw i8 %start, -2
578  %c.5 = icmp slt i8 %start.2, %high
579  call void @use(i1 %c.5)
580  %start.3 = mul nsw i8 %start, -3
581  %t.0 = icmp slt i8 %start.3, %high
582  call void @use(i1 %t.0)
583  %start.4 = mul nsw i8 %start, -4
584  %t.1 = icmp slt i8 %start.4, %high
585  call void @use(i1 %t.1)
586  ret void
587
588else:
589  ret void
590}
591
592define void @slt_mul_nsw_neg_3_known_positive_2(i8 %start, i8 %high) {
593; CHECK-LABEL: @slt_mul_nsw_neg_3_known_positive_2(
594; CHECK-NEXT:  entry:
595; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], -3
596; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
597; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
598; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
599; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
600; CHECK:       then:
601; CHECK-NEXT:    ret void
602; CHECK:       else:
603; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[START]], [[HIGH]]
604; CHECK-NEXT:    call void @use(i1 [[C_6]])
605; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], -1
606; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
607; CHECK-NEXT:    call void @use(i1 [[C_7]])
608; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], -2
609; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
610; CHECK-NEXT:    call void @use(i1 [[C_8]])
611; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], -3
612; CHECK-NEXT:    [[C_9:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
613; CHECK-NEXT:    call void @use(i1 [[C_9]])
614; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], -4
615; CHECK-NEXT:    [[C_10:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
616; CHECK-NEXT:    call void @use(i1 [[C_10]])
617; CHECK-NEXT:    ret void
618;
619entry:
620  %mul.3  = mul nsw i8 %start, -3
621  %c.1 = icmp slt i8 %mul.3, %high
622  %c.2 = icmp sgt i8 %start, 0
623  %and = and i1 %c.1, %c.2
624  br i1 %and, label %then, label %else
625
626then:
627  ret void
628
629else:
630  %c.6 = icmp slt i8 %start, %high
631  call void @use(i1 %c.6)
632  %else.start.1 = mul nsw i8 %start, -1
633  %c.7 = icmp slt i8 %else.start.1, %high
634  call void @use(i1 %c.7)
635  %else.start.2 = mul nsw i8 %start, -2
636  %c.8 = icmp slt i8 %else.start.2, %high
637  call void @use(i1 %c.8)
638  %else.start.3 = mul nsw i8 %start, -3
639  %c.9 = icmp slt i8 %else.start.3, %high
640  call void @use(i1 %c.9)
641  %else.start.4 = mul nsw i8 %start, -4
642  %c.10 = icmp slt i8 %else.start.4, %high
643  call void @use(i1 %c.10)
644  ret void
645}
646
647define void @slt_mul_nsw_3_known_nonnegative_1(i8 %start, i8 %high) {
648; CHECK-LABEL: @slt_mul_nsw_3_known_nonnegative_1(
649; CHECK-NEXT:  entry:
650; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
651; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
652; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[START]], 0
653; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
654; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
655; CHECK:       then:
656; CHECK-NEXT:    call void @use(i1 true)
657; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
658; CHECK-NEXT:    call void @use(i1 true)
659; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
660; CHECK-NEXT:    call void @use(i1 true)
661; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
662; CHECK-NEXT:    call void @use(i1 true)
663; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
664; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
665; CHECK-NEXT:    call void @use(i1 [[C_3]])
666; CHECK-NEXT:    ret void
667; CHECK:       else:
668; CHECK-NEXT:    ret void
669;
670entry:
671  %mul.3  = mul nsw i8 %start, 3
672  %c.1 = icmp slt i8 %mul.3, %high
673  %c.2 = icmp sge i8 %start, 0
674  %and = and i1 %c.1, %c.2
675  br i1 %and, label %then, label %else
676
677then:
678  %t.0 = icmp slt i8 %start, %high
679  call void @use(i1 %t.0)
680  %start.1 = mul nsw i8 %start, 1
681  %t.1 = icmp slt i8 %start.1, %high
682  call void @use(i1 %t.1)
683  %start.2 = mul nsw i8 %start, 2
684  %t.2 = icmp slt i8 %start.2, %high
685  call void @use(i1 %t.2)
686  %start.3 = mul nsw i8 %start, 3
687  %t.3 = icmp slt i8 %start.3, %high
688  call void @use(i1 %t.3)
689  %start.4 = mul nsw i8 %start, 4
690  %c.3 = icmp slt i8 %start.4, %high
691  call void @use(i1 %c.3)
692  ret void
693
694else:
695  ret void
696}
697
698define void @slt_mul_nsw_3_known_nonnegative_2(i8 %start, i8 %high) {
699; CHECK-LABEL: @slt_mul_nsw_3_known_nonnegative_2(
700; CHECK-NEXT:  entry:
701; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
702; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
703; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[START]], 0
704; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
705; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
706; CHECK:       then:
707; CHECK-NEXT:    ret void
708; CHECK:       else:
709; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START]], [[HIGH]]
710; CHECK-NEXT:    call void @use(i1 [[C_4]])
711; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
712; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
713; CHECK-NEXT:    call void @use(i1 [[C_5]])
714; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
715; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
716; CHECK-NEXT:    call void @use(i1 [[C_6]])
717; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
718; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
719; CHECK-NEXT:    call void @use(i1 [[C_7]])
720; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
721; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
722; CHECK-NEXT:    call void @use(i1 [[C_8]])
723; CHECK-NEXT:    ret void
724;
725entry:
726  %mul.3  = mul nsw i8 %start, 3
727  %c.1 = icmp slt i8 %mul.3, %high
728  %c.2 = icmp sge i8 %start, 0
729  %and = and i1 %c.1, %c.2
730  br i1 %and, label %then, label %else
731
732then:
733  ret void
734
735else:
736  %c.4 = icmp slt i8 %start, %high
737  call void @use(i1 %c.4)
738  %else.start.1 = mul nsw i8 %start, 1
739  %c.5 = icmp slt i8 %else.start.1, %high
740  call void @use(i1 %c.5)
741  %else.start.2 = mul nsw i8 %start, 2
742  %c.6 = icmp slt i8 %else.start.2, %high
743  call void @use(i1 %c.6)
744  %else.start.3 = mul nsw i8 %start, 3
745  %c.7 = icmp slt i8 %else.start.3, %high
746  call void @use(i1 %c.7)
747  %else.start.4 = mul nsw i8 %start, 4
748  %c.8 = icmp slt i8 %else.start.4, %high
749  call void @use(i1 %c.8)
750  ret void
751}
752
753define void @slt_mul_nsw_both_var_non_negative_1(i8 %start, i8 %scale, i8 %high) {
754; CHECK-LABEL: @slt_mul_nsw_both_var_non_negative_1(
755; CHECK-NEXT:  entry:
756; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], [[SCALE:%.*]]
757; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
758; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
759; CHECK-NEXT:    [[C3:%.*]] = icmp sgt i8 [[SCALE]], 0
760; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])
761; CHECK-NEXT:    [[C4:%.*]] = icmp sle i8 [[SCALE]], 3
762; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])
763; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
764; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
765; CHECK:       then:
766; CHECK-NEXT:    [[T_0:%.*]] = icmp slt i8 [[START]], [[HIGH]]
767; CHECK-NEXT:    call void @use(i1 [[T_0]])
768; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
769; CHECK-NEXT:    [[T_1:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
770; CHECK-NEXT:    call void @use(i1 [[T_1]])
771; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
772; CHECK-NEXT:    [[T_2:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
773; CHECK-NEXT:    call void @use(i1 [[T_2]])
774; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
775; CHECK-NEXT:    [[T_3:%.*]] = icmp slt i8 [[START_3]], [[HIGH]]
776; CHECK-NEXT:    call void @use(i1 [[T_3]])
777; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
778; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
779; CHECK-NEXT:    call void @use(i1 [[C_3]])
780; CHECK-NEXT:    ret void
781; CHECK:       else:
782; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START]], [[HIGH]]
783; CHECK-NEXT:    call void @use(i1 [[C_4]])
784; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
785; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
786; CHECK-NEXT:    call void @use(i1 [[C_5]])
787; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
788; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
789; CHECK-NEXT:    call void @use(i1 [[C_6]])
790; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
791; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
792; CHECK-NEXT:    call void @use(i1 [[C_7]])
793; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
794; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
795; CHECK-NEXT:    call void @use(i1 [[C_8]])
796; CHECK-NEXT:    ret void
797;
798entry:
799  %mul.3  = mul nsw i8 %start, %scale
800  %c.1 = icmp slt i8 %mul.3, %high
801  %c.2 = icmp sgt i8 %start, 0
802  %c3 = icmp sgt i8 %scale, 0
803  call void @llvm.assume(i1 %c3)
804  %c4 = icmp sle i8 %scale, 3
805  call void @llvm.assume(i1 %c3)
806  %and = and i1 %c.1, %c.2
807  br i1 %and, label %then, label %else
808
809then:
810  %t.0 = icmp slt i8 %start, %high
811  call void @use(i1 %t.0)
812  %start.1 = mul nsw i8 %start, 1
813  %t.1 = icmp slt i8 %start.1, %high
814  call void @use(i1 %t.1)
815  %start.2 = mul nsw i8 %start, 2
816  %t.2 = icmp slt i8 %start.2, %high
817  call void @use(i1 %t.2)
818  %start.3 = mul nsw i8 %start, 3
819  %t.3 = icmp slt i8 %start.3, %high
820  call void @use(i1 %t.3)
821  %start.4 = mul nsw i8 %start, 4
822  %c.3 = icmp slt i8 %start.4, %high
823  call void @use(i1 %c.3)
824  ret void
825
826else:
827  %c.4 = icmp slt i8 %start, %high
828  call void @use(i1 %c.4)
829  %else.start.1 = mul nsw i8 %start, 1
830  %c.5 = icmp slt i8 %else.start.1, %high
831  call void @use(i1 %c.5)
832  %else.start.2 = mul nsw i8 %start, 2
833  %c.6 = icmp slt i8 %else.start.2, %high
834  call void @use(i1 %c.6)
835  %else.start.3 = mul nsw i8 %start, 3
836  %c.7 = icmp slt i8 %else.start.3, %high
837  call void @use(i1 %c.7)
838  %else.start.4 = mul nsw i8 %start, 4
839  %c.8 = icmp slt i8 %else.start.4, %high
840  call void @use(i1 %c.8)
841  ret void
842}
843
844define void @slt_mul_nsw_both_var_non_negative_2(i8 %start, i8 %scale, i8 %high) {
845; CHECK-LABEL: @slt_mul_nsw_both_var_non_negative_2(
846; CHECK-NEXT:  entry:
847; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], [[SCALE:%.*]]
848; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[MUL_3]], [[HIGH:%.*]]
849; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i8 [[START]], 0
850; CHECK-NEXT:    [[C3:%.*]] = icmp sgt i8 [[SCALE]], 0
851; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])
852; CHECK-NEXT:    [[C4:%.*]] = icmp sle i8 [[SCALE]], 3
853; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])
854; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
855; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
856; CHECK:       then:
857; CHECK-NEXT:    ret void
858; CHECK:       else:
859; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START]], [[HIGH]]
860; CHECK-NEXT:    call void @use(i1 [[C_4]])
861; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
862; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
863; CHECK-NEXT:    call void @use(i1 [[C_5]])
864; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
865; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
866; CHECK-NEXT:    call void @use(i1 [[C_6]])
867; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
868; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
869; CHECK-NEXT:    call void @use(i1 [[C_7]])
870; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
871; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
872; CHECK-NEXT:    call void @use(i1 [[C_8]])
873; CHECK-NEXT:    ret void
874;
875entry:
876  %mul.3  = mul nsw i8 %start, %scale
877  %c.1 = icmp slt i8 %mul.3, %high
878  %c.2 = icmp sgt i8 %start, 0
879  %c3 = icmp sgt i8 %scale, 0
880  call void @llvm.assume(i1 %c3)
881  %c4 = icmp sle i8 %scale, 3
882  call void @llvm.assume(i1 %c3)
883  %and = and i1 %c.1, %c.2
884  br i1 %and, label %then, label %else
885
886then:
887  ret void
888
889else:
890  %c.4 = icmp slt i8 %start, %high
891  call void @use(i1 %c.4)
892  %else.start.1 = mul nsw i8 %start, 1
893  %c.5 = icmp slt i8 %else.start.1, %high
894  call void @use(i1 %c.5)
895  %else.start.2 = mul nsw i8 %start, 2
896  %c.6 = icmp slt i8 %else.start.2, %high
897  call void @use(i1 %c.6)
898  %else.start.3 = mul nsw i8 %start, 3
899  %c.7 = icmp slt i8 %else.start.3, %high
900  call void @use(i1 %c.7)
901  %else.start.4 = mul nsw i8 %start, 4
902  %c.8 = icmp slt i8 %else.start.4, %high
903  call void @use(i1 %c.8)
904  ret void
905}
906
907define void @ult_mul_nsw_3_known_positive_1(i8 %start, i8 %high) {
908; CHECK-LABEL: @ult_mul_nsw_3_known_positive_1(
909; CHECK-NEXT:  entry:
910; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
911; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[MUL_3]], [[HIGH:%.*]]
912; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[START]], 0
913; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
914; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
915; CHECK:       then:
916; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]
917; CHECK-NEXT:    call void @use(i1 [[T_0]])
918; CHECK-NEXT:    [[START_1:%.*]] = mul nsw i8 [[START]], 1
919; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]]
920; CHECK-NEXT:    call void @use(i1 [[T_1]])
921; CHECK-NEXT:    [[START_2:%.*]] = mul nsw i8 [[START]], 2
922; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]]
923; CHECK-NEXT:    call void @use(i1 [[T_2]])
924; CHECK-NEXT:    [[START_3:%.*]] = mul nsw i8 [[START]], 3
925; CHECK-NEXT:    [[T_3:%.*]] = icmp ult i8 [[START_3]], [[HIGH]]
926; CHECK-NEXT:    call void @use(i1 [[T_3]])
927; CHECK-NEXT:    [[START_4:%.*]] = mul nsw i8 [[START]], 4
928; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
929; CHECK-NEXT:    call void @use(i1 [[C_3]])
930; CHECK-NEXT:    ret void
931; CHECK:       else:
932; CHECK-NEXT:    ret void
933;
934entry:
935  %mul.3  = mul nsw i8 %start, 3
936  %c.1 = icmp ult i8 %mul.3, %high
937  %c.2 = icmp ugt i8 %start, 0
938  %and = and i1 %c.1, %c.2
939  br i1 %and, label %then, label %else
940
941then:
942  %t.0 = icmp ult i8 %start, %high
943  call void @use(i1 %t.0)
944  %start.1 = mul nsw i8 %start, 1
945  %t.1 = icmp ult i8 %start.1, %high
946  call void @use(i1 %t.1)
947  %start.2 = mul nsw i8 %start, 2
948  %t.2 = icmp ult i8 %start.2, %high
949  call void @use(i1 %t.2)
950  %start.3 = mul nsw i8 %start, 3
951  %t.3 = icmp ult i8 %start.3, %high
952  call void @use(i1 %t.3)
953  %start.4 = mul nsw i8 %start, 4
954  %c.3 = icmp slt i8 %start.4, %high
955  call void @use(i1 %c.3)
956  ret void
957
958else:
959  ret void
960}
961
962define void @ult_mul_nsw_3_known_positive_2(i8 %start, i8 %high) {
963; CHECK-LABEL: @ult_mul_nsw_3_known_positive_2(
964; CHECK-NEXT:  entry:
965; CHECK-NEXT:    [[MUL_3:%.*]] = mul nsw i8 [[START:%.*]], 3
966; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[MUL_3]], [[HIGH:%.*]]
967; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[START]], 0
968; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
969; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
970; CHECK:       then:
971; CHECK-NEXT:    ret void
972; CHECK:       else:
973; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START]], [[HIGH]]
974; CHECK-NEXT:    call void @use(i1 [[C_4]])
975; CHECK-NEXT:    [[ELSE_START_1:%.*]] = mul nsw i8 [[START]], 1
976; CHECK-NEXT:    [[C_5:%.*]] = icmp slt i8 [[ELSE_START_1]], [[HIGH]]
977; CHECK-NEXT:    call void @use(i1 [[C_5]])
978; CHECK-NEXT:    [[ELSE_START_2:%.*]] = mul nsw i8 [[START]], 2
979; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i8 [[ELSE_START_2]], [[HIGH]]
980; CHECK-NEXT:    call void @use(i1 [[C_6]])
981; CHECK-NEXT:    [[ELSE_START_3:%.*]] = mul nsw i8 [[START]], 3
982; CHECK-NEXT:    [[C_7:%.*]] = icmp slt i8 [[ELSE_START_3]], [[HIGH]]
983; CHECK-NEXT:    call void @use(i1 [[C_7]])
984; CHECK-NEXT:    [[ELSE_START_4:%.*]] = mul nsw i8 [[START]], 4
985; CHECK-NEXT:    [[C_8:%.*]] = icmp slt i8 [[ELSE_START_4]], [[HIGH]]
986; CHECK-NEXT:    call void @use(i1 [[C_8]])
987; CHECK-NEXT:    ret void
988;
989entry:
990  %mul.3  = mul nsw i8 %start, 3
991  %c.1 = icmp ult i8 %mul.3, %high
992  %c.2 = icmp ugt i8 %start, 0
993  %and = and i1 %c.1, %c.2
994  br i1 %and, label %then, label %else
995
996then:
997  ret void
998
999else:
1000  %c.4 = icmp slt i8 %start, %high
1001  call void @use(i1 %c.4)
1002  %else.start.1 = mul nsw i8 %start, 1
1003  %c.5 = icmp slt i8 %else.start.1, %high
1004  call void @use(i1 %c.5)
1005  %else.start.2 = mul nsw i8 %start, 2
1006  %c.6 = icmp slt i8 %else.start.2, %high
1007  call void @use(i1 %c.6)
1008  %else.start.3 = mul nsw i8 %start, 3
1009  %c.7 = icmp slt i8 %else.start.3, %high
1010  call void @use(i1 %c.7)
1011  %else.start.4 = mul nsw i8 %start, 4
1012  %c.8 = icmp slt i8 %else.start.4, %high
1013  call void @use(i1 %c.8)
1014  ret void
1015}
1016