@@ -534,3 +534,203 @@ 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: ret i1 false
573
+ ; CHECK: if.end:
574
+ ; CHECK-NEXT: ret i1 false
575
+ ;
576
+ entry:
577
+ %cond1 = icmp eq i64 %y , %x
578
+ %cond2 = icmp eq i64 %w , %z
579
+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
580
+ br i1 %or.cond , label %if.end , label %if.then
581
+
582
+ if.then:
583
+ %sub1 = sub i64 %w , %z
584
+ %sub2 = sub i64 %y , %x
585
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
586
+ %cmp = icmp eq i64 %umin , 0
587
+ ret i1 %cmp
588
+
589
+ if.end:
590
+ ret i1 false
591
+ }
592
+
593
+ define i1 @test_nonequal_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
594
+ ; CHECK-LABEL: @test_nonequal_domcond2(
595
+ ; CHECK-NEXT: entry:
596
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
597
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
598
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false
599
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
600
+ ; CHECK: if.then:
601
+ ; CHECK-NEXT: ret i1 false
602
+ ; CHECK: if.end:
603
+ ; CHECK-NEXT: ret i1 false
604
+ ;
605
+ entry:
606
+ %cond1 = icmp ne i64 %y , %x
607
+ %cond2 = icmp ne i64 %w , %z
608
+ %or.cond = select i1 %cond1 , i1 %cond2 , i1 false
609
+ br i1 %or.cond , label %if.then , label %if.end
610
+
611
+ if.then:
612
+ %sub1 = sub i64 %w , %z
613
+ %sub2 = sub i64 %y , %x
614
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
615
+ %cmp = icmp eq i64 %umin , 0
616
+ ret i1 %cmp
617
+
618
+ if.end:
619
+ ret i1 false
620
+ }
621
+
622
+ define i1 @test_nonequal_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
623
+ ; CHECK-LABEL: @test_nonequal_assume(
624
+ ; CHECK-NEXT: entry:
625
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
626
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
627
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
628
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
629
+ ; CHECK-NEXT: ret i1 false
630
+ ;
631
+ entry:
632
+ %cond1 = icmp ne i64 %y , %x
633
+ call void @llvm.assume (i1 %cond1 )
634
+ %cond2 = icmp ne i64 %w , %z
635
+ call void @llvm.assume (i1 %cond2 )
636
+
637
+ %sub1 = sub i64 %w , %z
638
+ %sub2 = sub i64 %y , %x
639
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
640
+ %cmp = icmp eq i64 %umin , 0
641
+ ret i1 %cmp
642
+ }
643
+
644
+ ; Negative tests
645
+
646
+ define i1 @test_nonequal_invalid_domcond1 (i64 %x , i64 %y , i64 %z , i64 %w ) {
647
+ ; CHECK-LABEL: @test_nonequal_invalid_domcond1(
648
+ ; CHECK-NEXT: entry:
649
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
650
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
651
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
652
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
653
+ ; CHECK: if.then:
654
+ ; CHECK-NEXT: ret i1 true
655
+ ; CHECK: if.end:
656
+ ; CHECK-NEXT: ret i1 false
657
+ ;
658
+ entry:
659
+ %cond1 = icmp ne i64 %y , %x
660
+ %cond2 = icmp eq i64 %w , %z
661
+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
662
+ br i1 %or.cond , label %if.end , label %if.then
663
+
664
+ if.then:
665
+ %sub1 = sub i64 %w , %z
666
+ %sub2 = sub i64 %y , %x
667
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
668
+ %cmp = icmp eq i64 %umin , 0
669
+ ret i1 %cmp
670
+
671
+ if.end:
672
+ ret i1 false
673
+ }
674
+
675
+ define i1 @test_nonequal_invalid_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
676
+ ; CHECK-LABEL: @test_nonequal_invalid_domcond2(
677
+ ; CHECK-NEXT: entry:
678
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
679
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
680
+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
681
+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
682
+ ; CHECK: if.then:
683
+ ; CHECK-NEXT: br label [[IF_END]]
684
+ ; CHECK: if.end:
685
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
686
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
687
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
688
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
689
+ ; CHECK-NEXT: ret i1 [[CMP]]
690
+ ;
691
+ entry:
692
+ %cond1 = icmp eq i64 %y , %x
693
+ %cond2 = icmp eq i64 %w , %z
694
+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
695
+ br i1 %or.cond , label %if.then , label %if.end
696
+
697
+ if.then:
698
+ br label %if.end
699
+
700
+ if.end:
701
+ %sub1 = sub i64 %w , %z
702
+ %sub2 = sub i64 %y , %x
703
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
704
+ %cmp = icmp eq i64 %umin , 0
705
+ ret i1 %cmp
706
+ }
707
+
708
+ define i1 @test_nonequal_invalid_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
709
+ ; CHECK-LABEL: @test_nonequal_invalid_assume(
710
+ ; CHECK-NEXT: entry:
711
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W:%.*]], [[Z:%.*]]
712
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y:%.*]], [[X:%.*]]
713
+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
714
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
715
+ ; CHECK-NEXT: call void @side_effect()
716
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y]], [[X]]
717
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
718
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W]], [[Z]]
719
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
720
+ ; CHECK-NEXT: ret i1 [[CMP]]
721
+ ;
722
+ entry:
723
+ %sub1 = sub i64 %w , %z
724
+ %sub2 = sub i64 %y , %x
725
+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
726
+ %cmp = icmp eq i64 %umin , 0
727
+
728
+ call void @side_effect ()
729
+ %cond1 = icmp ne i64 %y , %x
730
+ call void @llvm.assume (i1 %cond1 )
731
+ %cond2 = icmp ne i64 %w , %z
732
+ call void @llvm.assume (i1 %cond2 )
733
+ ret i1 %cmp
734
+ }
735
+
736
+ declare void @side_effect ()
0 commit comments