@@ -534,3 +534,215 @@ else:
534
534
%cmp1 = icmp eq i32 %and1 , 0
535
535
ret i1 %cmp1
536
536
}
537
+
538
+ ; TODO: X != Y implies X | Y != 0
539
+ define i1 @or_nonzero_from_nonequal (i8 %x , i8 %y ) {
540
+ ; CHECK-LABEL: @or_nonzero_from_nonequal(
541
+ ; CHECK-NEXT: entry:
542
+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
543
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
544
+ ; CHECK: if.then:
545
+ ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[Y]]
546
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0
547
+ ; CHECK-NEXT: ret i1 [[CMP]]
548
+ ; CHECK: if.else:
549
+ ; CHECK-NEXT: ret i1 false
550
+ ;
551
+ entry:
552
+ %cond = icmp eq i8 %x , %y
553
+ br i1 %cond , label %if.else , label %if.then
554
+
555
+ if.then:
556
+ %or = or i8 %x , %y
557
+ %cmp = icmp eq i8 %or , 0
558
+ ret i1 %cmp
559
+
560
+ if.else:
561
+ ret i1 false
562
+ }
563
+
564
+ define i1 @test_nonequal_domcond1 (i64 %x , i64 %y , i64 %z , i64 %w ) {
565
+ ; CHECK-LABEL: @test_nonequal_domcond1(
566
+ ; CHECK-NEXT: entry:
567
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
568
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
569
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
570
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
571
+ ; CHECK: if.then:
572
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
573
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
574
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
575
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
576
+ ; CHECK-NEXT: ret i1 [[CMP]]
577
+ ; CHECK: if.end:
578
+ ; CHECK-NEXT: ret i1 false
579
+ ;
580
+ entry:
581
+ %cond1 = icmp eq i64 %y , %x
582
+ %cond2 = icmp eq i64 %w , %z
583
+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
584
+ br i1 %or.cond , label %if.end , label %if.then
585
+
586
+ if.then:
587
+ %sub1 = sub i64 %w , %z
588
+ %sub2 = sub i64 %y , %x
589
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
590
+ %cmp = icmp eq i64 %umin , 0
591
+ ret i1 %cmp
592
+
593
+ if.end:
594
+ ret i1 false
595
+ }
596
+
597
+ define i1 @test_nonequal_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
598
+ ; CHECK-LABEL: @test_nonequal_domcond2(
599
+ ; CHECK-NEXT: entry:
600
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
601
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
602
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false
603
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
604
+ ; CHECK: if.then:
605
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
606
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
607
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
608
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
609
+ ; CHECK-NEXT: ret i1 [[CMP]]
610
+ ; CHECK: if.end:
611
+ ; CHECK-NEXT: ret i1 false
612
+ ;
613
+ entry:
614
+ %cond1 = icmp ne i64 %y , %x
615
+ %cond2 = icmp ne i64 %w , %z
616
+ %or.cond = select i1 %cond1 , i1 %cond2 , i1 false
617
+ br i1 %or.cond , label %if.then , label %if.end
618
+
619
+ if.then:
620
+ %sub1 = sub i64 %w , %z
621
+ %sub2 = sub i64 %y , %x
622
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
623
+ %cmp = icmp eq i64 %umin , 0
624
+ ret i1 %cmp
625
+
626
+ if.end:
627
+ ret i1 false
628
+ }
629
+
630
+ define i1 @test_nonequal_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
631
+ ; CHECK-LABEL: @test_nonequal_assume(
632
+ ; CHECK-NEXT: entry:
633
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
634
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
635
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
636
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
637
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
638
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
639
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
640
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
641
+ ; CHECK-NEXT: ret i1 [[CMP]]
642
+ ;
643
+ entry:
644
+ %cond1 = icmp ne i64 %y , %x
645
+ call void @llvm.assume (i1 %cond1 )
646
+ %cond2 = icmp ne i64 %w , %z
647
+ call void @llvm.assume (i1 %cond2 )
648
+
649
+ %sub1 = sub i64 %w , %z
650
+ %sub2 = sub i64 %y , %x
651
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
652
+ %cmp = icmp eq i64 %umin , 0
653
+ ret i1 %cmp
654
+ }
655
+
656
+ ; Negative tests
657
+
658
+ define i1 @test_nonequal_invalid_domcond1 (i64 %x , i64 %y , i64 %z , i64 %w ) {
659
+ ; CHECK-LABEL: @test_nonequal_invalid_domcond1(
660
+ ; CHECK-NEXT: entry:
661
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
662
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
663
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
664
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
665
+ ; CHECK: if.then:
666
+ ; CHECK-NEXT: ret i1 true
667
+ ; CHECK: if.end:
668
+ ; CHECK-NEXT: ret i1 false
669
+ ;
670
+ entry:
671
+ %cond1 = icmp ne i64 %y , %x
672
+ %cond2 = icmp eq i64 %w , %z
673
+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
674
+ br i1 %or.cond , label %if.end , label %if.then
675
+
676
+ if.then:
677
+ %sub1 = sub i64 %w , %z
678
+ %sub2 = sub i64 %y , %x
679
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
680
+ %cmp = icmp eq i64 %umin , 0
681
+ ret i1 %cmp
682
+
683
+ if.end:
684
+ ret i1 false
685
+ }
686
+
687
+ define i1 @test_nonequal_invalid_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
688
+ ; CHECK-LABEL: @test_nonequal_invalid_domcond2(
689
+ ; CHECK-NEXT: entry:
690
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
691
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
692
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
693
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
694
+ ; CHECK: if.then:
695
+ ; CHECK-NEXT: br label [[IF_END]]
696
+ ; CHECK: if.end:
697
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
698
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
699
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
700
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
701
+ ; CHECK-NEXT: ret i1 [[CMP]]
702
+ ;
703
+ entry:
704
+ %cond1 = icmp eq i64 %y , %x
705
+ %cond2 = icmp eq i64 %w , %z
706
+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
707
+ br i1 %or.cond , label %if.then , label %if.end
708
+
709
+ if.then:
710
+ br label %if.end
711
+
712
+ if.end:
713
+ %sub1 = sub i64 %w , %z
714
+ %sub2 = sub i64 %y , %x
715
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
716
+ %cmp = icmp eq i64 %umin , 0
717
+ ret i1 %cmp
718
+ }
719
+
720
+ define i1 @test_nonequal_invalid_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
721
+ ; CHECK-LABEL: @test_nonequal_invalid_assume(
722
+ ; CHECK-NEXT: entry:
723
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W:%.*]], [[Z:%.*]]
724
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y:%.*]], [[X:%.*]]
725
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
726
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
727
+ ; CHECK-NEXT: call void @side_effect()
728
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y]], [[X]]
729
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
730
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W]], [[Z]]
731
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
732
+ ; CHECK-NEXT: ret i1 [[CMP]]
733
+ ;
734
+ entry:
735
+ %sub1 = sub i64 %w , %z
736
+ %sub2 = sub i64 %y , %x
737
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
738
+ %cmp = icmp eq i64 %umin , 0
739
+
740
+ call void @side_effect ()
741
+ %cond1 = icmp ne i64 %y , %x
742
+ call void @llvm.assume (i1 %cond1 )
743
+ %cond2 = icmp ne i64 %w , %z
744
+ call void @llvm.assume (i1 %cond2 )
745
+ ret i1 %cmp
746
+ }
747
+
748
+ declare void @side_effect ()
0 commit comments