@@ -425,3 +425,176 @@ define i1 @assume_4b(i64 %a, i64 %b) {
425425 %ret = icmp sle i64 %a , %b
426426 ret i1 %ret
427427}
428+
429+ define i1 @sle_and_ne_imply_slt (i8 %a ) {
430+ ; CHECK-LABEL: @sle_and_ne_imply_slt(
431+ ; CHECK-NEXT: [[SLE:%.*]] = icmp sle i8 [[A:%.*]], 0
432+ ; CHECK-NEXT: br i1 [[SLE]], label [[LESS_OR_EQUAL:%.*]], label [[EXIT:%.*]]
433+ ; CHECK: less_or_equal:
434+ ; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[A]], 0
435+ ; CHECK-NEXT: br i1 [[NE]], label [[NOT_EQUAL:%.*]], label [[EXIT]]
436+ ; CHECK: not_equal:
437+ ; CHECK-NEXT: ret i1 true
438+ ; CHECK: exit:
439+ ; CHECK-NEXT: ret i1 false
440+ ;
441+ %sle = icmp sle i8 %a , 0
442+ br i1 %sle , label %less_or_equal , label %exit
443+
444+ less_or_equal:
445+ %ne = icmp ne i8 %a , 0
446+ br i1 %ne , label %not_equal , label %exit
447+
448+ not_equal:
449+ %slt = icmp slt i8 %a , 0
450+ ret i1 %slt
451+
452+ exit:
453+ ret i1 0
454+ }
455+
456+ define i1 @sge_and_ne_imply_sgt (i8 %a ) {
457+ ; CHECK-LABEL: @sge_and_ne_imply_sgt(
458+ ; CHECK-NEXT: [[SGE:%.*]] = icmp sge i8 [[A:%.*]], 0
459+ ; CHECK-NEXT: br i1 [[SGE]], label [[GREATER_OR_EQUAL:%.*]], label [[EXIT:%.*]]
460+ ; CHECK: greater_or_equal:
461+ ; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[A]], 0
462+ ; CHECK-NEXT: br i1 [[NE]], label [[NOT_EQUAL:%.*]], label [[EXIT]]
463+ ; CHECK: not_equal:
464+ ; CHECK-NEXT: ret i1 true
465+ ; CHECK: exit:
466+ ; CHECK-NEXT: ret i1 false
467+ ;
468+ %sge = icmp sge i8 %a , 0
469+ br i1 %sge , label %greater_or_equal , label %exit
470+
471+ greater_or_equal:
472+ %ne = icmp ne i8 %a , 0
473+ br i1 %ne , label %not_equal , label %exit
474+
475+ not_equal:
476+ %sgt = icmp sgt i8 %a , 0
477+ ret i1 %sgt
478+
479+ exit:
480+ ret i1 0
481+ }
482+
483+ define i1 @sge_and_ne_imply_sgt_opposite_successor (i8 %a ) {
484+ ; CHECK-LABEL: @sge_and_ne_imply_sgt_opposite_successor(
485+ ; CHECK-NEXT: [[SLT:%.*]] = icmp slt i8 [[A:%.*]], 0
486+ ; CHECK-NEXT: br i1 [[SLT]], label [[EXIT:%.*]], label [[GREATER_OR_EQUAL:%.*]]
487+ ; CHECK: greater_or_equal:
488+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i8 [[A]], 0
489+ ; CHECK-NEXT: br i1 [[EQ]], label [[EXIT]], label [[NOT_EQUAL:%.*]]
490+ ; CHECK: not_equal:
491+ ; CHECK-NEXT: ret i1 true
492+ ; CHECK: exit:
493+ ; CHECK-NEXT: ret i1 false
494+ ;
495+ %slt = icmp slt i8 %a , 0
496+ br i1 %slt , label %exit , label %greater_or_equal
497+
498+ greater_or_equal:
499+ %eq = icmp eq i8 %a , 0
500+ br i1 %eq , label %exit , label %not_equal
501+
502+ not_equal:
503+ %sgt = icmp sgt i8 %a , 0
504+ ret i1 %sgt
505+
506+ exit:
507+ ret i1 0
508+ }
509+
510+ define i1 @sgt_implies_ugt_successful (i64 %a , i64 %b ) {
511+ ; CHECK-LABEL: @sgt_implies_ugt_successful(
512+ ; CHECK-NEXT: [[B_SGE_0:%.*]] = icmp sge i64 [[B:%.*]], 0
513+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_SGE_0]])
514+ ; CHECK-NEXT: [[B_NE_0:%.*]] = icmp ne i64 [[B]], 0
515+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_NE_0]])
516+ ; CHECK-NEXT: [[A_SGT_B:%.*]] = icmp sgt i64 [[A:%.*]], [[B]]
517+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGT_B]])
518+ ; CHECK-NEXT: [[A_MINUS_ONE:%.*]] = add nsw i64 [[A]], -1
519+ ; CHECK-NEXT: [[B_MINUS_ONE:%.*]] = add nsw i64 [[B]], -1
520+ ; CHECK-NEXT: ret i1 true
521+ ;
522+ %b_sge_0 = icmp sge i64 %b , 0
523+ call void @llvm.assume (i1 %b_sge_0 )
524+
525+ %b_ne_0 = icmp ne i64 %b , 0
526+ call void @llvm.assume (i1 %b_ne_0 )
527+
528+ %a_sgt_b = icmp sgt i64 %a , %b
529+ call void @llvm.assume (i1 %a_sgt_b )
530+
531+ %a_minus_one = add nsw i64 %a , -1
532+ %b_minus_one = add nsw i64 %b , -1
533+ %ugt = icmp ugt i64 %a_minus_one , %b_minus_one
534+ ret i1 %ugt
535+ }
536+
537+ define i1 @sgt_implies_ugt_unsuccessful1 (i64 %a , i64 %b ) {
538+ ; CHECK-LABEL: @sgt_implies_ugt_unsuccessful1(
539+ ; CHECK-NEXT: [[B_SGE_0:%.*]] = icmp sge i64 [[B:%.*]], 0
540+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_SGE_0]])
541+ ; CHECK-NEXT: [[A_SGT_B:%.*]] = icmp sgt i64 [[A:%.*]], [[B]]
542+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGT_B]])
543+ ; CHECK-NEXT: [[A_MINUS_ONE:%.*]] = add nsw i64 [[A]], -1
544+ ; CHECK-NEXT: [[B_MINUS_ONE:%.*]] = add nsw i64 [[B]], -1
545+ ; CHECK-NEXT: [[UGT:%.*]] = icmp ugt i64 [[A_MINUS_ONE]], [[B_MINUS_ONE]]
546+ ; CHECK-NEXT: ret i1 [[UGT]]
547+ ;
548+ %b_sge_0 = icmp sge i64 %b , 0
549+ call void @llvm.assume (i1 %b_sge_0 )
550+
551+ %a_sgt_b = icmp sgt i64 %a , %b
552+ call void @llvm.assume (i1 %a_sgt_b )
553+
554+ %a_minus_one = add nsw i64 %a , -1
555+ %b_minus_one = add nsw i64 %b , -1
556+ %ugt = icmp ugt i64 %a_minus_one , %b_minus_one
557+ ret i1 %ugt
558+ }
559+
560+ define i1 @sgt_implies_ugt_unsuccessful2 (i64 %a , i64 %b ) {
561+ ; CHECK-LABEL: @sgt_implies_ugt_unsuccessful2(
562+ ; CHECK-NEXT: [[B_NE_0:%.*]] = icmp ne i64 [[B:%.*]], 0
563+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_NE_0]])
564+ ; CHECK-NEXT: [[A_SGT_B:%.*]] = icmp sgt i64 [[A:%.*]], [[B]]
565+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGT_B]])
566+ ; CHECK-NEXT: [[A_MINUS_ONE:%.*]] = add nsw i64 [[A]], -1
567+ ; CHECK-NEXT: [[B_MINUS_ONE:%.*]] = add nsw i64 [[B]], -1
568+ ; CHECK-NEXT: [[UGT:%.*]] = icmp ugt i64 [[A_MINUS_ONE]], [[B_MINUS_ONE]]
569+ ; CHECK-NEXT: ret i1 [[UGT]]
570+ ;
571+ %b_ne_0 = icmp ne i64 %b , 0
572+ call void @llvm.assume (i1 %b_ne_0 )
573+
574+ %a_sgt_b = icmp sgt i64 %a , %b
575+ call void @llvm.assume (i1 %a_sgt_b )
576+
577+ %a_minus_one = add nsw i64 %a , -1
578+ %b_minus_one = add nsw i64 %b , -1
579+ %ugt = icmp ugt i64 %a_minus_one , %b_minus_one
580+ ret i1 %ugt
581+ }
582+
583+ define i1 @sgt_implies_ugt_unsuccessful3 (i64 %a , i64 %b ) {
584+ ; CHECK-LABEL: @sgt_implies_ugt_unsuccessful3(
585+ ; CHECK-NEXT: [[A_SGT_B:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
586+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGT_B]])
587+ ; CHECK-NEXT: [[A_MINUS_ONE:%.*]] = add nsw i64 [[A]], -1
588+ ; CHECK-NEXT: [[B_MINUS_ONE:%.*]] = add nsw i64 [[B]], -1
589+ ; CHECK-NEXT: [[UGT:%.*]] = icmp ugt i64 [[A_MINUS_ONE]], [[B_MINUS_ONE]]
590+ ; CHECK-NEXT: ret i1 [[UGT]]
591+ ;
592+ %a_sgt_b = icmp sgt i64 %a , %b
593+ call void @llvm.assume (i1 %a_sgt_b )
594+
595+ %a_minus_one = add nsw i64 %a , -1
596+ %b_minus_one = add nsw i64 %b , -1
597+ %ugt = icmp ugt i64 %a_minus_one , %b_minus_one
598+ ret i1 %ugt
599+ }
600+
0 commit comments