@@ -606,3 +606,323 @@ define i1 @fold_ne_rhs_fail_shift_not_1s(i8 %x, i8 %yy) {
606
606
%r = icmp ne i8 %and , 0
607
607
ret i1 %r
608
608
}
609
+
610
+ define i1 @test_shr_and_1_ne_0 (i32 %a , i32 %b ) {
611
+ ; CHECK-LABEL: @test_shr_and_1_ne_0(
612
+ ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
613
+ ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
614
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0
615
+ ; CHECK-NEXT: ret i1 [[CMP]]
616
+ ;
617
+ %shr = lshr i32 %a , %b
618
+ %and = and i32 %shr , 1
619
+ %cmp = icmp ne i32 %and , 0
620
+ ret i1 %cmp
621
+ }
622
+
623
+ define i1 @test_const_shr_and_1_ne_0 (i32 %b ) {
624
+ ; CHECK-LABEL: @test_const_shr_and_1_ne_0(
625
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
626
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
627
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
628
+ ; CHECK-NEXT: ret i1 [[CMP]]
629
+ ;
630
+ %shr = lshr i32 42 , %b
631
+ %and = and i32 %shr , 1
632
+ %cmp = icmp ne i32 %and , 0
633
+ ret i1 %cmp
634
+ }
635
+
636
+ define i1 @test_not_const_shr_and_1_ne_0 (i32 %b ) {
637
+ ; CHECK-LABEL: @test_not_const_shr_and_1_ne_0(
638
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
639
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
640
+ ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
641
+ ; CHECK-NEXT: ret i1 [[CMP_NOT]]
642
+ ;
643
+ %shr = lshr i32 42 , %b
644
+ %and = and i32 %shr , 1
645
+ %cmp = icmp eq i32 %and , 0
646
+ ret i1 %cmp
647
+ }
648
+
649
+ define i1 @test_const_shr_exact_and_1_ne_0 (i32 %b ) {
650
+ ; CHECK-LABEL: @test_const_shr_exact_and_1_ne_0(
651
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr exact i32 42, [[B:%.*]]
652
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
653
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
654
+ ; CHECK-NEXT: ret i1 [[CMP]]
655
+ ;
656
+ %shr = lshr exact i32 42 , %b
657
+ %and = and i32 %shr , 1
658
+ %cmp = icmp ne i32 %and , 0
659
+ ret i1 %cmp
660
+ }
661
+
662
+ define i1 @test_const_shr_and_2_ne_0_negative (i32 %b ) {
663
+ ; CHECK-LABEL: @test_const_shr_and_2_ne_0_negative(
664
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
665
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 2
666
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
667
+ ; CHECK-NEXT: ret i1 [[CMP]]
668
+ ;
669
+ %shr = lshr i32 42 , %b
670
+ %and = and i32 %shr , 2
671
+ %cmp = icmp eq i32 %and , 0
672
+ ret i1 %cmp
673
+ }
674
+
675
+ define <8 x i1 > @test_const_shr_and_1_ne_0_v8i8_splat_negative (<8 x i8 > %b ) {
676
+ ; CHECK-LABEL: @test_const_shr_and_1_ne_0_v8i8_splat_negative(
677
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>, [[B:%.*]]
678
+ ; CHECK-NEXT: [[CMP:%.*]] = trunc <8 x i8> [[SHR]] to <8 x i1>
679
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
680
+ ;
681
+ %shr = lshr <8 x i8 > <i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 >, %b
682
+ %and = and <8 x i8 > %shr , <i8 1 , i8 1 , i8 1 , i8 1 , i8 1 , i8 1 , i8 1 , i8 1 >
683
+ %cmp = icmp ne <8 x i8 > %and , zeroinitializer
684
+ ret <8 x i1 > %cmp
685
+ }
686
+
687
+ define <8 x i1 > @test_const_shr_and_1_ne_0_v8i8_nonsplat_negative (<8 x i8 > %b ) {
688
+ ; CHECK-LABEL: @test_const_shr_and_1_ne_0_v8i8_nonsplat_negative(
689
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr <8 x i8> <i8 42, i8 43, i8 44, i8 45, i8 46, i8 47, i8 48, i8 49>, [[B:%.*]]
690
+ ; CHECK-NEXT: [[CMP:%.*]] = trunc <8 x i8> [[SHR]] to <8 x i1>
691
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
692
+ ;
693
+ %shr = lshr <8 x i8 > <i8 42 , i8 43 , i8 44 , i8 45 , i8 46 , i8 47 , i8 48 , i8 49 >, %b
694
+ %and = and <8 x i8 > %shr , <i8 1 , i8 1 , i8 1 , i8 1 , i8 1 , i8 1 , i8 1 , i8 1 >
695
+ %cmp = icmp ne <8 x i8 > %and , zeroinitializer
696
+ ret <8 x i1 > %cmp
697
+ }
698
+
699
+ define i1 @test_const_shr_and_1_ne_0_i1_negative (i1 %b ) {
700
+ ; CHECK-LABEL: @test_const_shr_and_1_ne_0_i1_negative(
701
+ ; CHECK-NEXT: ret i1 true
702
+ ;
703
+ %shr = lshr i1 1 , %b
704
+ %and = and i1 %shr , 1
705
+ %cmp = icmp ne i1 %and , 0
706
+ ret i1 %cmp
707
+ }
708
+
709
+ define i1 @test_const_shr_and_1_ne_0_multi_use_lshr_negative (i32 %b ) {
710
+ ; CHECK-LABEL: @test_const_shr_and_1_ne_0_multi_use_lshr_negative(
711
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
712
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
713
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 0
714
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SHR]], [[B]]
715
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]
716
+ ; CHECK-NEXT: ret i1 [[RET]]
717
+ ;
718
+ %shr = lshr i32 42 , %b
719
+ %and = and i32 %shr , 1
720
+ %cmp1 = icmp ne i32 %and , 0
721
+ %cmp2 = icmp eq i32 %b , %shr
722
+ %ret = and i1 %cmp1 , %cmp2
723
+ ret i1 %ret
724
+ }
725
+
726
+ define i1 @test_const_shr_and_1_ne_0_multi_use_and_negative (i32 %b ) {
727
+ ; CHECK-LABEL: @test_const_shr_and_1_ne_0_multi_use_and_negative(
728
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
729
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
730
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 0
731
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[AND]], [[B]]
732
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]
733
+ ; CHECK-NEXT: ret i1 [[RET]]
734
+ ;
735
+ %shr = lshr i32 42 , %b
736
+ %and = and i32 %shr , 1
737
+ %cmp1 = icmp ne i32 %and , 0
738
+ %cmp2 = icmp eq i32 %b , %and
739
+ %ret = and i1 %cmp1 , %cmp2
740
+ ret i1 %ret
741
+ }
742
+
743
+ define i1 @test_shl_sub_bw_minus_1_slt_0 (i32 %a , i32 %b ) {
744
+ ; CHECK-LABEL: @test_shl_sub_bw_minus_1_slt_0(
745
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
746
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
747
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 0
748
+ ; CHECK-NEXT: ret i1 [[CMP]]
749
+ ;
750
+ %sub = sub i32 31 , %b
751
+ %shl = shl i32 %a , %sub
752
+ %cmp = icmp slt i32 %shl , 0
753
+ ret i1 %cmp
754
+ }
755
+
756
+ define i1 @test_const_shl_sub_bw_minus_1_slt_0 (i32 %b ) {
757
+ ; CHECK-LABEL: @test_const_shl_sub_bw_minus_1_slt_0(
758
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
759
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 42, [[SUB]]
760
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 0
761
+ ; CHECK-NEXT: ret i1 [[CMP]]
762
+ ;
763
+ %sub = sub i32 31 , %b
764
+ %shl = shl i32 42 , %sub
765
+ %cmp = icmp slt i32 %shl , 0
766
+ ret i1 %cmp
767
+ }
768
+
769
+ define i1 @test_not_shl_sub_bw_minus_1_slt_0 (i32 %a , i32 %b ) {
770
+ ; CHECK-LABEL: @test_not_shl_sub_bw_minus_1_slt_0(
771
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
772
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
773
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SHL]], -1
774
+ ; CHECK-NEXT: ret i1 [[CMP]]
775
+ ;
776
+ %sub = sub i32 31 , %b
777
+ %shl = shl i32 %a , %sub
778
+ %cmp = icmp sge i32 %shl , 0
779
+ ret i1 %cmp
780
+ }
781
+
782
+ define i1 @test_shl_nuw_sub_bw_minus_1_slt_0 (i32 %a , i32 %b ) {
783
+ ; CHECK-LABEL: @test_shl_nuw_sub_bw_minus_1_slt_0(
784
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
785
+ ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[A:%.*]], [[SUB]]
786
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 0
787
+ ; CHECK-NEXT: ret i1 [[CMP]]
788
+ ;
789
+ %sub = sub i32 31 , %b
790
+ %shl = shl nuw i32 %a , %sub
791
+ %cmp = icmp slt i32 %shl , 0
792
+ ret i1 %cmp
793
+ }
794
+
795
+ define i1 @test_not_const_shl_sub_bw_minus_1_slt_0 (i32 %b ) {
796
+ ; CHECK-LABEL: @test_not_const_shl_sub_bw_minus_1_slt_0(
797
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
798
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 42, [[SUB]]
799
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SHL]], -1
800
+ ; CHECK-NEXT: ret i1 [[CMP]]
801
+ ;
802
+ %sub = sub i32 31 , %b
803
+ %shl = shl i32 42 , %sub
804
+ %cmp = icmp sge i32 %shl , 0
805
+ ret i1 %cmp
806
+ }
807
+
808
+ define <8 x i1 > @test_shl_sub_bw_minus_1_slt_0_v8i8 (<8 x i8 > %a , <8 x i8 > %b ) {
809
+ ; CHECK-LABEL: @test_shl_sub_bw_minus_1_slt_0_v8i8(
810
+ ; CHECK-NEXT: [[SUB:%.*]] = sub <8 x i8> <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>, [[B:%.*]]
811
+ ; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i8> [[A:%.*]], [[SUB]]
812
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i8> [[SHL]], zeroinitializer
813
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
814
+ ;
815
+ %sub = sub <8 x i8 > <i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 >, %b
816
+ %shl = shl <8 x i8 > %a , %sub
817
+ %cmp = icmp slt <8 x i8 > %shl , zeroinitializer
818
+ ret <8 x i1 > %cmp
819
+ }
820
+
821
+ define <8 x i1 > @test_const_shl_sub_bw_minus_1_slt_0_v8i8_splat (<8 x i8 > %b ) {
822
+ ; CHECK-LABEL: @test_const_shl_sub_bw_minus_1_slt_0_v8i8_splat(
823
+ ; CHECK-NEXT: [[SUB:%.*]] = sub <8 x i8> <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>, [[B:%.*]]
824
+ ; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>, [[SUB]]
825
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i8> [[SHL]], zeroinitializer
826
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
827
+ ;
828
+ %sub = sub <8 x i8 > <i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 >, %b
829
+ %shl = shl <8 x i8 > <i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 >, %sub
830
+ %cmp = icmp slt <8 x i8 > %shl , zeroinitializer
831
+ ret <8 x i1 > %cmp
832
+ }
833
+
834
+ define <8 x i1 > @test_const_shl_sub_bw_minus_1_slt_0_v8i8_splat_poison_1 (<8 x i8 > %b ) {
835
+ ; CHECK-LABEL: @test_const_shl_sub_bw_minus_1_slt_0_v8i8_splat_poison_1(
836
+ ; CHECK-NEXT: [[SUB:%.*]] = sub <8 x i8> <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 poison>, [[B:%.*]]
837
+ ; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>, [[SUB]]
838
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i8> [[SHL]], zeroinitializer
839
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
840
+ ;
841
+ %sub = sub <8 x i8 > <i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 poison>, %b
842
+ %shl = shl <8 x i8 > <i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 >, %sub
843
+ %cmp = icmp slt <8 x i8 > %shl , zeroinitializer
844
+ ret <8 x i1 > %cmp
845
+ }
846
+
847
+ define <8 x i1 > @test_const_shl_sub_bw_minus_1_slt_0_v8i8_splat_poison_2 (<8 x i8 > %b ) {
848
+ ; CHECK-LABEL: @test_const_shl_sub_bw_minus_1_slt_0_v8i8_splat_poison_2(
849
+ ; CHECK-NEXT: [[SUB:%.*]] = sub <8 x i8> <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>, [[B:%.*]]
850
+ ; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 poison>, [[SUB]]
851
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i8> [[SHL]], zeroinitializer
852
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
853
+ ;
854
+ %sub = sub <8 x i8 > <i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 >, %b
855
+ %shl = shl <8 x i8 > <i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 42 , i8 poison>, %sub
856
+ %cmp = icmp slt <8 x i8 > %shl , zeroinitializer
857
+ ret <8 x i1 > %cmp
858
+ }
859
+
860
+ define <8 x i1 > @test_const_shl_sub_bw_minus_1_slt_0_v8i8_nonsplat (<8 x i8 > %b ) {
861
+ ; CHECK-LABEL: @test_const_shl_sub_bw_minus_1_slt_0_v8i8_nonsplat(
862
+ ; CHECK-NEXT: [[SUB:%.*]] = sub <8 x i8> <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>, [[B:%.*]]
863
+ ; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i8> <i8 42, i8 43, i8 44, i8 45, i8 46, i8 47, i8 48, i8 49>, [[SUB]]
864
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i8> [[SHL]], zeroinitializer
865
+ ; CHECK-NEXT: ret <8 x i1> [[CMP]]
866
+ ;
867
+ %sub = sub <8 x i8 > <i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 , i8 7 >, %b
868
+ %shl = shl <8 x i8 > <i8 42 , i8 43 , i8 44 , i8 45 , i8 46 , i8 47 , i8 48 , i8 49 >, %sub
869
+ %cmp = icmp slt <8 x i8 > %shl , zeroinitializer
870
+ ret <8 x i1 > %cmp
871
+ }
872
+
873
+ define i1 @test_shl_sub_non_bw_minus_1_slt_0_negative (i32 %a , i32 %b ) {
874
+ ; CHECK-LABEL: @test_shl_sub_non_bw_minus_1_slt_0_negative(
875
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 32, [[B:%.*]]
876
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
877
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 0
878
+ ; CHECK-NEXT: ret i1 [[CMP]]
879
+ ;
880
+ %sub = sub i32 32 , %b
881
+ %shl = shl i32 %a , %sub
882
+ %cmp = icmp slt i32 %shl , 0
883
+ ret i1 %cmp
884
+ }
885
+
886
+ define i1 @test_shl_sub_bw_minus_1_slt_0_i1_negative (i1 %a , i1 %b ) {
887
+ ; CHECK-LABEL: @test_shl_sub_bw_minus_1_slt_0_i1_negative(
888
+ ; CHECK-NEXT: ret i1 [[A:%.*]]
889
+ ;
890
+ %sub = sub i1 0 , %b
891
+ %shl = shl i1 %a , %sub
892
+ %cmp = icmp slt i1 %shl , 0
893
+ ret i1 %cmp
894
+ }
895
+
896
+ define i1 @test_shl_sub_bw_minus_1_slt_0_multi_use_sub_negative (i32 %a , i32 %b ) {
897
+ ; CHECK-LABEL: @test_shl_sub_bw_minus_1_slt_0_multi_use_sub_negative(
898
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
899
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
900
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[SHL]], 0
901
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[SUB]], [[B]]
902
+ ; CHECK-NEXT: [[RET:%.*]] = or i1 [[CMP1]], [[CMP2]]
903
+ ; CHECK-NEXT: ret i1 [[RET]]
904
+ ;
905
+ %sub = sub i32 31 , %b
906
+ %shl = shl i32 %a , %sub
907
+ %cmp1 = icmp slt i32 %shl , 0
908
+ %cmp2 = icmp slt i32 %b , %sub
909
+ %ret = or i1 %cmp1 , %cmp2
910
+ ret i1 %ret
911
+ }
912
+
913
+ define i1 @test_shl_sub_bw_minus_1_slt_0_multi_use_shl_negative (i32 %a , i32 %b ) {
914
+ ; CHECK-LABEL: @test_shl_sub_bw_minus_1_slt_0_multi_use_shl_negative(
915
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[B:%.*]]
916
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
917
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[SHL]], 0
918
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SHL]], [[B]]
919
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]
920
+ ; CHECK-NEXT: ret i1 [[RET]]
921
+ ;
922
+ %sub = sub i32 31 , %b
923
+ %shl = shl i32 %a , %sub
924
+ %cmp1 = icmp slt i32 %shl , 0
925
+ %cmp2 = icmp eq i32 %b , %shl
926
+ %ret = and i1 %cmp1 , %cmp2
927
+ ret i1 %ret
928
+ }
0 commit comments