@@ -497,4 +497,221 @@ entry:
497497 ret i1 %and
498498}
499499
500+ define void @and_tree_second_implies_first (i32 noundef %v0 , i32 noundef %v1 , i32 noundef %v2 ) {
501+ ; CHECK-LABEL: @and_tree_second_implies_first(
502+ ; CHECK-NEXT: entry:
503+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
504+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
505+ ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
506+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
507+ ; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]]
508+ ; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
509+ ; CHECK: if.then:
510+ ; CHECK-NEXT: call void @side_effect()
511+ ; CHECK-NEXT: br label [[RETURN]]
512+ ; CHECK: return:
513+ ; CHECK-NEXT: ret void
514+ ;
515+ entry:
516+ %cmp0 = icmp sge i32 %v0 , %v1
517+ %cmp1 = icmp sge i32 %v1 , %v2
518+ %and1 = and i1 %cmp0 , %cmp1
519+ %cmp2 = icmp slt i32 %v0 , %v2
520+ %and2 = and i1 %cmp2 , %and1
521+ br i1 %and2 , label %if.then , label %return
522+
523+ if.then:
524+ call void @side_effect ()
525+ br label %return
526+
527+ return:
528+ ret void
529+ }
530+
531+ define void @and_tree_second_implies_first_perm1 (i32 noundef %v0 , i32 noundef %v1 , i32 noundef %v2 ) {
532+ ; CHECK-LABEL: @and_tree_second_implies_first_perm1(
533+ ; CHECK-NEXT: entry:
534+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
535+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
536+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
537+ ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP2]], [[CMP1]]
538+ ; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]]
539+ ; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
540+ ; CHECK: if.then:
541+ ; CHECK-NEXT: call void @side_effect()
542+ ; CHECK-NEXT: br label [[RETURN]]
543+ ; CHECK: return:
544+ ; CHECK-NEXT: ret void
545+ ;
546+ entry:
547+ %cmp0 = icmp sge i32 %v0 , %v1
548+ %cmp1 = icmp sge i32 %v1 , %v2
549+ %cmp2 = icmp slt i32 %v0 , %v2
550+ %and1 = and i1 %cmp2 , %cmp1
551+ %and2 = and i1 %cmp0 , %and1
552+ br i1 %and2 , label %if.then , label %return
553+
554+ if.then:
555+ call void @side_effect ()
556+ br label %return
557+
558+ return:
559+ ret void
560+ }
561+
562+
563+ define void @and_tree_second_implies_first_perm2 (i32 noundef %v0 , i32 noundef %v1 , i32 noundef %v2 ) {
564+ ; CHECK-LABEL: @and_tree_second_implies_first_perm2(
565+ ; CHECK-NEXT: entry:
566+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
567+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
568+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
569+ ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP2]]
570+ ; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]]
571+ ; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
572+ ; CHECK: if.then:
573+ ; CHECK-NEXT: call void @side_effect()
574+ ; CHECK-NEXT: br label [[RETURN]]
575+ ; CHECK: return:
576+ ; CHECK-NEXT: ret void
577+ ;
578+ entry:
579+ %cmp0 = icmp sge i32 %v0 , %v1
580+ %cmp1 = icmp sge i32 %v1 , %v2
581+ %cmp2 = icmp slt i32 %v0 , %v2
582+ %and1 = and i1 %cmp0 , %cmp2
583+ %and2 = and i1 %cmp1 , %and1
584+ br i1 %and2 , label %if.then , label %return
585+
586+ if.then:
587+ call void @side_effect ()
588+ br label %return
589+
590+ return:
591+ ret void
592+ }
593+
594+ define void @logical_and_tree_second_implies_first (i32 %v0 , i32 %v1 , i32 %v2 ) {
595+ ; CHECK-LABEL: @logical_and_tree_second_implies_first(
596+ ; CHECK-NEXT: entry:
597+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
598+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
599+ ; CHECK-NEXT: [[AND1:%.*]] = select i1 [[CMP0]], i1 [[CMP1]], i1 false
600+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
601+ ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[CMP2]], i1 [[AND1]], i1 false
602+ ; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
603+ ; CHECK: if.then:
604+ ; CHECK-NEXT: call void @side_effect()
605+ ; CHECK-NEXT: br label [[RETURN]]
606+ ; CHECK: return:
607+ ; CHECK-NEXT: ret void
608+ ;
609+ entry:
610+ %cmp0 = icmp sge i32 %v0 , %v1
611+ %cmp1 = icmp sge i32 %v1 , %v2
612+ %and1 = select i1 %cmp0 , i1 %cmp1 , i1 false
613+ %cmp2 = icmp slt i32 %v0 , %v2
614+ %and2 = select i1 %cmp2 , i1 %and1 , i1 false
615+ br i1 %and2 , label %if.then , label %return
616+
617+ if.then:
618+ call void @side_effect ()
619+ br label %return
620+
621+ return:
622+ ret void
623+ }
624+
625+ define void @or_tree_second_implies_first (i32 noundef %v0 , i32 noundef %v1 , i32 noundef %v2 ) {
626+ ; CHECK-LABEL: @or_tree_second_implies_first(
627+ ; CHECK-NEXT: entry:
628+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
629+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
630+ ; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
631+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
632+ ; CHECK-NEXT: [[AND2:%.*]] = or i1 true, [[AND1]]
633+ ; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
634+ ; CHECK: if.then:
635+ ; CHECK-NEXT: call void @side_effect()
636+ ; CHECK-NEXT: br label [[RETURN]]
637+ ; CHECK: return:
638+ ; CHECK-NEXT: ret void
639+ ;
640+ entry:
641+ %cmp0 = icmp sge i32 %v0 , %v1
642+ %cmp1 = icmp sge i32 %v1 , %v2
643+ %and1 = or i1 %cmp0 , %cmp1
644+ %cmp2 = icmp slt i32 %v0 , %v2
645+ %and2 = or i1 %cmp2 , %and1
646+ br i1 %and2 , label %if.then , label %return
647+
648+ if.then:
649+ call void @side_effect ()
650+ br label %return
651+
652+ return:
653+ ret void
654+ }
655+
656+ define void @or_tree_second_implies_first_with_unknown_cond (i64 %x , i1 %cond ) {
657+ ; CHECK-LABEL: @or_tree_second_implies_first_with_unknown_cond(
658+ ; CHECK-NEXT: entry:
659+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], 1
660+ ; CHECK-NEXT: [[OR1:%.*]] = select i1 [[CMP1]], i1 [[COND:%.*]], i1 false
661+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[X]], 2
662+ ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 false, i1 false
663+ ; CHECK-NEXT: br i1 [[OR2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
664+ ; CHECK: if.then:
665+ ; CHECK-NEXT: call void @side_effect()
666+ ; CHECK-NEXT: br label [[IF_END]]
667+ ; CHECK: if.end:
668+ ; CHECK-NEXT: ret void
669+ ;
670+ entry:
671+ %cmp1 = icmp ugt i64 %x , 1
672+ %or1 = select i1 %cmp1 , i1 %cond , i1 false
673+ %cmp2 = icmp ult i64 %x , 2
674+ %or2 = select i1 %or1 , i1 %cmp2 , i1 false
675+ br i1 %or2 , label %if.then , label %if.end
676+
677+ if.then:
678+ call void @side_effect ()
679+ br label %if.end
680+
681+ if.end:
682+ ret void
683+ }
684+
685+ define void @negative_and_or_tree_second_implies_first (i32 noundef %v0 , i32 noundef %v1 , i32 noundef %v2 ) {
686+ ; CHECK-LABEL: @negative_and_or_tree_second_implies_first(
687+ ; CHECK-NEXT: entry:
688+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
689+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
690+ ; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
691+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
692+ ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]
693+ ; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
694+ ; CHECK: if.then:
695+ ; CHECK-NEXT: call void @side_effect()
696+ ; CHECK-NEXT: br label [[RETURN]]
697+ ; CHECK: return:
698+ ; CHECK-NEXT: ret void
699+ ;
700+ entry:
701+ %cmp0 = icmp sge i32 %v0 , %v1
702+ %cmp1 = icmp sge i32 %v1 , %v2
703+ %and1 = or i1 %cmp0 , %cmp1
704+ %cmp2 = icmp slt i32 %v0 , %v2
705+ %and2 = and i1 %cmp2 , %and1
706+ br i1 %and2 , label %if.then , label %return
707+
708+ if.then:
709+ call void @side_effect ()
710+ br label %return
711+
712+ return:
713+ ret void
714+ }
715+
716+ declare void @side_effect ()
500717declare void @no_noundef (i1 noundef)
0 commit comments