@@ -216,3 +216,140 @@ define i1 @lshr_add_ule_non_monotonic(i32 %x, i32 %y, i32 %z) {
216216 %cmp = icmp ule i32 %op1 , %op2
217217 ret i1 %cmp
218218}
219+
220+ define i1 @mul_nuw_nonzero_rhs_monotonic (i8 %x , i8 %c ) {
221+ ; CHECK-LABEL: define i1 @mul_nuw_nonzero_rhs_monotonic(
222+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
223+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[C]], 0
224+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
225+ ; CHECK-NEXT: [[PROD:%.*]] = mul nuw i8 [[X]], [[C]]
226+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[PROD]], [[X]]
227+ ; CHECK-NEXT: ret i1 [[CMP]]
228+ ;
229+ %c_nonzero = icmp ne i8 %c , 0
230+ call void @llvm.assume (i1 %c_nonzero )
231+
232+ %prod = mul nuw i8 %x , %c
233+ %cmp = icmp uge i8 %prod , %x
234+ ret i1 %cmp
235+ }
236+
237+ define i1 @mul_nuw_nonzero_rhs_monotonic_inverse_predicate (i8 %x , i8 %c ) {
238+ ; CHECK-LABEL: define i1 @mul_nuw_nonzero_rhs_monotonic_inverse_predicate(
239+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
240+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[C]], 0
241+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
242+ ; CHECK-NEXT: [[PROD:%.*]] = mul nuw i8 [[X]], [[C]]
243+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[PROD]], [[X]]
244+ ; CHECK-NEXT: ret i1 [[CMP]]
245+ ;
246+ %c_nonzero = icmp ne i8 %c , 0
247+ call void @llvm.assume (i1 %c_nonzero )
248+
249+ %prod = mul nuw i8 %x , %c
250+ %cmp = icmp ult i8 %prod , %x
251+ ret i1 %cmp
252+ }
253+
254+ define i1 @mul_nuw_nonzero_lhs_monotonic (i8 %x , i8 %c ) {
255+ ; CHECK-LABEL: define i1 @mul_nuw_nonzero_lhs_monotonic(
256+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
257+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[X]], 0
258+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
259+ ; CHECK-NEXT: [[PROD:%.*]] = mul nuw i8 [[X]], [[C]]
260+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[PROD]], [[C]]
261+ ; CHECK-NEXT: ret i1 [[CMP]]
262+ ;
263+ %c_nonzero = icmp ne i8 %x , 0
264+ call void @llvm.assume (i1 %c_nonzero )
265+
266+ %prod = mul nuw i8 %x , %c
267+ %cmp = icmp uge i8 %prod , %c
268+ ret i1 %cmp
269+ }
270+
271+ define i1 @mul_nuw_nonzero_lhs_rhs_monotonic (i8 %x , i8 %c ) {
272+ ; CHECK-LABEL: define i1 @mul_nuw_nonzero_lhs_rhs_monotonic(
273+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
274+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[C]], 0
275+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
276+ ; CHECK-NEXT: [[X_NONZERO:%.*]] = icmp ne i8 [[X]], 0
277+ ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NONZERO]])
278+ ; CHECK-NEXT: [[PROD:%.*]] = mul nuw i8 [[X]], [[C]]
279+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[PROD]], [[X]]
280+ ; CHECK-NEXT: ret i1 [[CMP]]
281+ ;
282+ %c_nonzero = icmp ne i8 %c , 0
283+ call void @llvm.assume (i1 %c_nonzero )
284+
285+ %x_nonzero = icmp ne i8 %x , 0
286+ call void @llvm.assume (i1 %x_nonzero )
287+
288+ %prod = mul nuw i8 %x , %c
289+ %cmp = icmp uge i8 %prod , %x
290+ ret i1 %cmp
291+ }
292+
293+
294+ define i1 @negative_mul_non_nsw (i8 %x , i8 %c ) {
295+ ; CHECK-LABEL: define i1 @negative_mul_non_nsw(
296+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
297+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[C]], 0
298+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
299+ ; CHECK-NEXT: [[X3:%.*]] = mul i8 [[X]], [[C]]
300+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X3]], [[X]]
301+ ; CHECK-NEXT: ret i1 [[CMP]]
302+ ;
303+ %c_nonzero = icmp ne i8 %c , 0
304+ call void @llvm.assume (i1 %c_nonzero )
305+
306+ %prod = mul i8 %x , %c
307+ %cmp = icmp uge i8 %prod , %x
308+ ret i1 %cmp
309+ }
310+
311+ define i1 @negative_mul_no_nonzero (i8 %x , i8 %c ) {
312+ ; CHECK-LABEL: define i1 @negative_mul_no_nonzero(
313+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
314+ ; CHECK-NEXT: [[X3:%.*]] = mul nsw i8 [[X]], [[C]]
315+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X3]], [[X]]
316+ ; CHECK-NEXT: ret i1 [[CMP]]
317+ ;
318+ %prod = mul nsw i8 %x , %c
319+ %cmp = icmp uge i8 %prod , %x
320+ ret i1 %cmp
321+ }
322+
323+ define i1 @negative_mul_lhs_maybe_zero (i8 %x , i8 %c ) {
324+ ; CHECK-LABEL: define i1 @negative_mul_lhs_maybe_zero(
325+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
326+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[C]], 0
327+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
328+ ; CHECK-NEXT: [[X3:%.*]] = mul nuw i8 [[X]], [[C]]
329+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X3]], [[C]]
330+ ; CHECK-NEXT: ret i1 [[CMP]]
331+ ;
332+ %c_nonzero = icmp ne i8 %c , 0
333+ call void @llvm.assume (i1 %c_nonzero )
334+
335+ %prod = mul nuw i8 %x , %c
336+ %cmp = icmp uge i8 %prod , %c
337+ ret i1 %cmp
338+ }
339+
340+ define i1 @negative_mul_rhs_maybe_zero (i8 %x , i8 %c ) {
341+ ; CHECK-LABEL: define i1 @negative_mul_rhs_maybe_zero(
342+ ; CHECK-SAME: i8 [[X:%.*]], i8 [[C:%.*]]) {
343+ ; CHECK-NEXT: [[C_NONZERO:%.*]] = icmp ne i8 [[X]], 0
344+ ; CHECK-NEXT: call void @llvm.assume(i1 [[C_NONZERO]])
345+ ; CHECK-NEXT: [[X3:%.*]] = mul nuw i8 [[X]], [[C]]
346+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X3]], [[X]]
347+ ; CHECK-NEXT: ret i1 [[CMP]]
348+ ;
349+ %c_nonzero = icmp ne i8 %x , 0
350+ call void @llvm.assume (i1 %c_nonzero )
351+
352+ %prod = mul nuw i8 %x , %c
353+ %cmp = icmp uge i8 %prod , %x
354+ ret i1 %cmp
355+ }
0 commit comments