[InstCombine] fold icmp of the sum of ext bool based on limited range · llvm/llvm-project@dd31a3b (original) (raw)
`@@ -629,13 +629,11 @@ define i1 @ashr_uge_sub(i8 %b, i8 %x, i8 %y) {
`
629
629
`ret i1 %r
`
630
630
`}
`
631
631
``
``
632
`+
; (zext i1 a) + (sext i1 b)) s< -1 --> false
`
``
633
+
632
634
`define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) {
`
633
635
`; CHECK-LABEL: @zext_sext_add_icmp_slt_minus1(
`
634
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
635
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
636
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
637
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], -1
`
638
``
`-
; CHECK-NEXT: ret i1 [[R]]
`
``
636
`+
; CHECK-NEXT: ret i1 false
`
639
637
`;
`
640
638
`%zext.a = zext i1 %a to i8
`
641
639
`%sext.b = sext i1 %b to i8
`
`@@ -644,13 +642,11 @@ define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) {
`
644
642
`ret i1 %r
`
645
643
`}
`
646
644
``
``
645
`+
; (zext i1 a) + (sext i1 b)) s> 1 --> false
`
``
646
+
647
647
`define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) {
`
648
648
`; CHECK-LABEL: @zext_sext_add_icmp_sgt_1(
`
649
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
650
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
651
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
652
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ADD]], 1
`
653
``
`-
; CHECK-NEXT: ret i1 [[R]]
`
``
649
`+
; CHECK-NEXT: ret i1 false
`
654
650
`;
`
655
651
`%zext.a = zext i1 %a to i8
`
656
652
`%sext.b = sext i1 %b to i8
`
`@@ -659,13 +655,11 @@ define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) {
`
659
655
`ret i1 %r
`
660
656
`}
`
661
657
``
``
658
`+
; (zext i1 a) + (sext i1 b)) s> -2 --> true
`
``
659
+
662
660
`define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) {
`
663
661
`; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus2(
`
664
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
665
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
666
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
667
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ADD]], -2
`
668
``
`-
; CHECK-NEXT: ret i1 [[R]]
`
``
662
`+
; CHECK-NEXT: ret i1 true
`
669
663
`;
`
670
664
`%zext.a = zext i1 %a to i8
`
671
665
`%sext.b = sext i1 %b to i8
`
`@@ -674,13 +668,11 @@ define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) {
`
674
668
`ret i1 %r
`
675
669
`}
`
676
670
``
``
671
`+
; (zext i1 a) + (sext i1 b)) s< 2 --> true
`
``
672
+
677
673
`define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) {
`
678
674
`; CHECK-LABEL: @zext_sext_add_icmp_slt_2(
`
679
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
680
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
681
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
682
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 2
`
683
``
`-
; CHECK-NEXT: ret i1 [[R]]
`
``
675
`+
; CHECK-NEXT: ret i1 true
`
684
676
`;
`
685
677
`%zext.a = zext i1 %a to i8
`
686
678
`%sext.b = sext i1 %b to i8
`
`@@ -689,13 +681,11 @@ define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) {
`
689
681
`ret i1 %r
`
690
682
`}
`
691
683
``
``
684
`+
; test case with i128
`
``
685
+
692
686
`define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) {
`
693
687
`; CHECK-LABEL: @zext_sext_add_icmp_i128(
`
694
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i128
`
695
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i128
`
696
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i128 [[ZEXT_A]], [[SEXT_B]]
`
697
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i128 [[ADD]], 9223372036854775808
`
698
``
`-
; CHECK-NEXT: ret i1 [[R]]
`
``
688
`+
; CHECK-NEXT: ret i1 false
`
699
689
`;
`
700
690
`%zext.a = zext i1 %a to i128
`
701
691
`%sext.b = sext i1 %b to i128
`
`@@ -704,12 +694,12 @@ define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) {
`
704
694
`ret i1 %r
`
705
695
`}
`
706
696
``
``
697
`+
; (zext i1 a) + (sext i1 b)) == -1 --> ~a & b
`
``
698
+
707
699
`define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) {
`
708
700
`; CHECK-LABEL: @zext_sext_add_icmp_eq_minus1(
`
709
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
710
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
711
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
712
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], -1
`
``
701
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[A:%.]], true
`
``
702
`+
; CHECK-NEXT: [[R:%.]] = and i1 [[TMP1]], [[B:%.]]
`
713
703
`; CHECK-NEXT: ret i1 [[R]]
`
714
704
`;
`
715
705
`%zext.a = zext i1 %a to i8
`
`@@ -719,12 +709,13 @@ define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) {
`
719
709
`ret i1 %r
`
720
710
`}
`
721
711
``
``
712
+
``
713
`+
; (zext i1 a) + (sext i1 b)) != -1 --> a | ~b
`
``
714
+
722
715
`define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) {
`
723
716
`; CHECK-LABEL: @zext_sext_add_icmp_ne_minus1(
`
724
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
725
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
726
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
727
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ADD]], -1
`
``
717
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[B:%.]], true
`
``
718
`+
; CHECK-NEXT: [[R:%.]] = or i1 [[TMP1]], [[A:%.]]
`
728
719
`; CHECK-NEXT: ret i1 [[R]]
`
729
720
`;
`
730
721
`%zext.a = zext i1 %a to i8
`
`@@ -734,10 +725,12 @@ define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) {
`
734
725
`ret i1 %r
`
735
726
`}
`
736
727
``
``
728
`+
; (zext i1 a) + (sext i1 b)) s> -1 --> a | ~b
`
``
729
+
737
730
`define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) {
`
738
731
`; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus1(
`
739
``
`-
; CHECK-NEXT: [[B_NOT:%.]] = xor i1 [[B:%.]], true
`
740
``
`-
; CHECK-NEXT: [[R:%.]] = or i1 [[B_NOT]], [[A:%.]]
`
``
732
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[B:%.]], true
`
``
733
`+
; CHECK-NEXT: [[R:%.]] = or i1 [[TMP1]], [[A:%.]]
`
741
734
`; CHECK-NEXT: ret i1 [[R]]
`
742
735
`;
`
743
736
`%zext.a = zext i1 %a to i8
`
`@@ -747,12 +740,12 @@ define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) {
`
747
740
`ret i1 %r
`
748
741
`}
`
749
742
``
``
743
`+
; (zext i1 a) + (sext i1 b)) u< -1 --> a | ~b
`
``
744
+
750
745
`define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) {
`
751
746
`; CHECK-LABEL: @zext_sext_add_icmp_ult_minus1(
`
752
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
753
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
754
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
755
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ADD]], -1
`
``
747
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[B:%.]], true
`
``
748
`+
; CHECK-NEXT: [[R:%.]] = or i1 [[TMP1]], [[A:%.]]
`
756
749
`; CHECK-NEXT: ret i1 [[R]]
`
757
750
`;
`
758
751
`%zext.a = zext i1 %a to i8
`
`@@ -762,12 +755,12 @@ define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) {
`
762
755
`ret i1 %r
`
763
756
`}
`
764
757
``
``
758
`+
; (zext i1 a) + (sext i1 b)) s> 0 --> a & ~b
`
``
759
+
765
760
`define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) {
`
766
761
`; CHECK-LABEL: @zext_sext_add_icmp_sgt_0(
`
767
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
768
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
769
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
770
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ADD]], 0
`
``
762
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[B:%.]], true
`
``
763
`+
; CHECK-NEXT: [[R:%.]] = and i1 [[TMP1]], [[A:%.]]
`
771
764
`; CHECK-NEXT: ret i1 [[R]]
`
772
765
`;
`
773
766
`%zext.a = zext i1 %a to i8
`
`@@ -777,11 +770,13 @@ define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) {
`
777
770
`ret i1 %r
`
778
771
`}
`
779
772
``
``
773
`+
; (zext i1 a) + (sext i1 b)) s< 0 --> ~a & b
`
``
774
+
780
775
`define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) {
`
781
776
`; CHECK-LABEL: @zext_sext_add_icmp_slt_0(
`
782
777
`; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[A:%.]], true
`
783
``
`-
; CHECK-NEXT: [[TMP2:%.]] = and i1 [[TMP1]], [[B:%.]]
`
784
``
`-
; CHECK-NEXT: ret i1 [[TMP2]]
`
``
778
`+
; CHECK-NEXT: [[R:%.]] = and i1 [[TMP1]], [[B:%.]]
`
``
779
`+
; CHECK-NEXT: ret i1 [[R]]
`
785
780
`;
`
786
781
`%zext.a = zext i1 %a to i8
`
787
782
`%sext.b = sext i1 %b to i8
`
`@@ -790,12 +785,12 @@ define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) {
`
790
785
`ret i1 %r
`
791
786
`}
`
792
787
``
``
788
`+
; (zext i1 a) + (sext i1 b)) == 1 --> a & ~b
`
``
789
+
793
790
`define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) {
`
794
791
`; CHECK-LABEL: @zext_sext_add_icmp_eq_1(
`
795
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
796
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
797
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
798
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 1
`
``
792
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[B:%.]], true
`
``
793
`+
; CHECK-NEXT: [[R:%.]] = and i1 [[TMP1]], [[A:%.]]
`
799
794
`; CHECK-NEXT: ret i1 [[R]]
`
800
795
`;
`
801
796
`%zext.a = zext i1 %a to i8
`
`@@ -805,12 +800,12 @@ define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) {
`
805
800
`ret i1 %r
`
806
801
`}
`
807
802
``
``
803
`+
; (zext i1 a) + (sext i1 b)) != 1 --> ~a | b
`
``
804
+
808
805
`define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) {
`
809
806
`; CHECK-LABEL: @zext_sext_add_icmp_ne_1(
`
810
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
811
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
812
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
813
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ADD]], 1
`
``
807
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[A:%.]], true
`
``
808
`+
; CHECK-NEXT: [[R:%.]] = or i1 [[TMP1]], [[B:%.]]
`
814
809
`; CHECK-NEXT: ret i1 [[R]]
`
815
810
`;
`
816
811
`%zext.a = zext i1 %a to i8
`
`@@ -820,12 +815,12 @@ define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) {
`
820
815
`ret i1 %r
`
821
816
`}
`
822
817
``
``
818
`+
; (zext i1 a) + (sext i1 b)) s< 1 --> ~a | b
`
``
819
+
823
820
`define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) {
`
824
821
`; CHECK-LABEL: @zext_sext_add_icmp_slt_1(
`
825
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
826
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext i1 [[B:%.]] to i8
`
827
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
`
828
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 1
`
``
822
`+
; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[A:%.]], true
`
``
823
`+
; CHECK-NEXT: [[R:%.]] = or i1 [[TMP1]], [[B:%.]]
`
829
824
`; CHECK-NEXT: ret i1 [[R]]
`
830
825
`;
`
831
826
`%zext.a = zext i1 %a to i8
`
`@@ -835,11 +830,13 @@ define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) {
`
835
830
`ret i1 %r
`
836
831
`}
`
837
832
``
``
833
`+
; (zext i1 a) + (sext i1 b)) u> 1 --> ~a & b
`
``
834
+
838
835
`define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) {
`
839
836
`; CHECK-LABEL: @zext_sext_add_icmp_ugt_1(
`
840
837
`; CHECK-NEXT: [[TMP1:%.]] = xor i1 [[A:%.]], true
`
841
``
`-
; CHECK-NEXT: [[TMP2:%.]] = and i1 [[TMP1]], [[B:%.]]
`
842
``
`-
; CHECK-NEXT: ret i1 [[TMP2]]
`
``
838
`+
; CHECK-NEXT: [[R:%.]] = and i1 [[TMP1]], [[B:%.]]
`
``
839
`+
; CHECK-NEXT: ret i1 [[R]]
`
843
840
`;
`
844
841
`%zext.a = zext i1 %a to i8
`
845
842
`%sext.b = sext i1 %b to i8
`
`@@ -850,10 +847,8 @@ define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) {
`
850
847
``
851
848
`define <2 x i1> @vector_zext_sext_add_icmp_slt_1(<2 x i1> %a, <2 x i1> %b) {
`
852
849
`; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1(
`
853
``
`-
; CHECK-NEXT: [[ZEXT_A:%.]] = zext <2 x i1> [[A:%.]] to <2 x i8>
`
854
``
`-
; CHECK-NEXT: [[SEXT_B:%.]] = sext <2 x i1> [[B:%.]] to <2 x i8>
`
855
``
`-
; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[ZEXT_A]], [[SEXT_B]]
`
856
``
`-
; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i8> [[ADD]], <i8 1, i8 1>
`
``
850
`+
; CHECK-NEXT: [[TMP1:%.]] = xor <2 x i1> [[A:%.]], <i1 true, i1 true>
`
``
851
`+
; CHECK-NEXT: [[R:%.]] = or <2 x i1> [[TMP1]], [[B:%.]]
`
857
852
`; CHECK-NEXT: ret <2 x i1> [[R]]
`
858
853
`;
`
859
854
`%zext.a = zext <2 x i1> %a to <2 x i8>
`
`@@ -878,6 +873,8 @@ define <2 x i1> @vector_zext_sext_add_icmp_slt_1_poison(<2 x i1> %a, <2 x i1> %b
`
878
873
`ret <2 x i1> %r
`
879
874
`}
`
880
875
``
``
876
`+
; Negative test, more than one use for icmp LHS
`
``
877
+
881
878
`define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) {
`
882
879
`; CHECK-LABEL: @zext_sext_add_icmp_slt_1_no_oneuse(
`
883
880
`; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
`@@ -895,6 +892,8 @@ define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) {
`
895
892
`ret i1 %r
`
896
893
`}
`
897
894
``
``
895
`+
; Negative test, icmp RHS is not a constant
`
``
896
+
898
897
`define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) {
`
899
898
`; CHECK-LABEL: @zext_sext_add_icmp_slt_1_rhs_not_const(
`
900
899
`; CHECK-NEXT: [[ZEXT_A:%.]] = zext i1 [[A:%.]] to i8
`
`@@ -910,6 +909,8 @@ define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) {
`
910
909
`ret i1 %r
`
911
910
`}
`
912
911
``
``
912
`+
; Negative test, ext source is not i1
`
``
913
+
913
914
`define i1 @zext_sext_add_icmp_slt_1_type_not_i1(i2 %a, i1 %b) {
`
914
915
`; CHECK-LABEL: @zext_sext_add_icmp_slt_1_type_not_i1(
`
915
916
`; CHECK-NEXT: [[ZEXT_A:%.]] = zext i2 [[A:%.]] to i8
`