@@ -630,5 +630,386 @@ define i8 @or_ne_bits_must_be_unset2_fail(i8 %x, i8 %y) {
630
630
ret i8 %r
631
631
}
632
632
633
+ declare void @use.i1 (i1 )
634
+ declare void @use.i8 (i8 )
635
+
636
+ declare void @use.2xi1 (<2 x i1 >)
637
+
638
+ define i1 @extract_value_uadd (<2 x i8 > %xx , <2 x i8 > %yy ) {
639
+ ; CHECK-LABEL: @extract_value_uadd(
640
+ ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1>
641
+ ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1>
642
+ ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
643
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
644
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
645
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
646
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
647
+ ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
648
+ ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 0
649
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
650
+ ; CHECK-NEXT: ret i1 [[R]]
651
+ ;
652
+ %x0 = and <2 x i8 > %xx , <i8 63 , i8 255 >
653
+ %y0 = and <2 x i8 > %yy , <i8 63 , i8 255 >
654
+ %x = add nuw <2 x i8 > %x0 , <i8 1 , i8 0 >
655
+ %y = add nuw <2 x i8 > %y0 , <i8 1 , i8 0 >
656
+
657
+ %add_uov = call { <2 x i8 >, <2 x i1 > } @llvm.uadd.with.overflow (<2 x i8 > %x , <2 x i8 > %y )
658
+ %add = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 0
659
+ %uov = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 1
660
+ call void @use.2xi1 (<2 x i1 > %uov )
661
+ %add_ele = extractelement <2 x i8 > %add , i32 0
662
+ %r = icmp eq i8 %add_ele , 0
663
+ ret i1 %r
664
+ }
665
+
666
+ define i1 @extract_value_uadd2 (<2 x i8 > %xx , <2 x i8 > %yy ) {
667
+ ; CHECK-LABEL: @extract_value_uadd2(
668
+ ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 -1, i8 63>
669
+ ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 -1, i8 63>
670
+ ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 0, i8 1>
671
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 0, i8 1>
672
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
673
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
674
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
675
+ ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
676
+ ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 1
677
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
678
+ ; CHECK-NEXT: ret i1 [[R]]
679
+ ;
680
+ %x0 = and <2 x i8 > %xx , <i8 255 , i8 63 >
681
+ %y0 = and <2 x i8 > %yy , <i8 255 , i8 63 >
682
+ %x = add nuw <2 x i8 > %x0 , <i8 0 , i8 1 >
683
+ %y = add nuw <2 x i8 > %y0 , <i8 0 , i8 1 >
684
+
685
+ %add_uov = call { <2 x i8 >, <2 x i1 > } @llvm.uadd.with.overflow (<2 x i8 > %x , <2 x i8 > %y )
686
+ %add = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 0
687
+ %uov = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 1
688
+ call void @use.2xi1 (<2 x i1 > %uov )
689
+ %add_ele = extractelement <2 x i8 > %add , i32 1
690
+ %r = icmp eq i8 %add_ele , 0
691
+ ret i1 %r
692
+ }
693
+
694
+ define i1 @extract_value_uadd_fail (<2 x i8 > %xx , <2 x i8 > %yy ) {
695
+ ; CHECK-LABEL: @extract_value_uadd_fail(
696
+ ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1>
697
+ ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1>
698
+ ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
699
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
700
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
701
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
702
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
703
+ ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
704
+ ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 1
705
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
706
+ ; CHECK-NEXT: ret i1 [[R]]
707
+ ;
708
+ %x0 = and <2 x i8 > %xx , <i8 63 , i8 255 >
709
+ %y0 = and <2 x i8 > %yy , <i8 63 , i8 255 >
710
+ %x = add nuw <2 x i8 > %x0 , <i8 1 , i8 0 >
711
+ %y = add nuw <2 x i8 > %y0 , <i8 1 , i8 0 >
712
+
713
+ %add_uov = call { <2 x i8 >, <2 x i1 > } @llvm.uadd.with.overflow (<2 x i8 > %x , <2 x i8 > %y )
714
+ %add = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 0
715
+ %uov = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 1
716
+ call void @use.2xi1 (<2 x i1 > %uov )
717
+ %add_ele = extractelement <2 x i8 > %add , i32 1
718
+ %r = icmp eq i8 %add_ele , 0
719
+ ret i1 %r
720
+ }
721
+
722
+ define i1 @extract_value_uadd_fail2 (<2 x i8 > %xx , <2 x i8 > %yy , i32 %idx ) {
723
+ ; CHECK-LABEL: @extract_value_uadd_fail2(
724
+ ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1>
725
+ ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1>
726
+ ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
727
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
728
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
729
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
730
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
731
+ ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
732
+ ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i32 [[IDX:%.*]]
733
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
734
+ ; CHECK-NEXT: ret i1 [[R]]
735
+ ;
736
+ %x0 = and <2 x i8 > %xx , <i8 63 , i8 255 >
737
+ %y0 = and <2 x i8 > %yy , <i8 63 , i8 255 >
738
+ %x = add nuw <2 x i8 > %x0 , <i8 1 , i8 0 >
739
+ %y = add nuw <2 x i8 > %y0 , <i8 1 , i8 0 >
740
+
741
+ %add_uov = call { <2 x i8 >, <2 x i1 > } @llvm.uadd.with.overflow (<2 x i8 > %x , <2 x i8 > %y )
742
+ %add = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 0
743
+ %uov = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 1
744
+ call void @use.2xi1 (<2 x i1 > %uov )
745
+ %add_ele = extractelement <2 x i8 > %add , i32 %idx
746
+ %r = icmp eq i8 %add_ele , 0
747
+ ret i1 %r
748
+ }
749
+
750
+ define i1 @extract_value_uadd_fail3 (<2 x i8 > %xx , <2 x i8 > %yy ) {
751
+ ; CHECK-LABEL: @extract_value_uadd_fail3(
752
+ ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 127, i8 127>
753
+ ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 127, i8 127>
754
+ ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 1>
755
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 1>
756
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
757
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
758
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
759
+ ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
760
+ ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 0
761
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
762
+ ; CHECK-NEXT: ret i1 [[R]]
763
+ ;
764
+ %x0 = and <2 x i8 > %xx , <i8 127 , i8 127 >
765
+ %y0 = and <2 x i8 > %yy , <i8 127 , i8 127 >
766
+ %x = add nuw <2 x i8 > %x0 , <i8 1 , i8 1 >
767
+ %y = add nuw <2 x i8 > %y0 , <i8 1 , i8 1 >
768
+
769
+ %add_uov = call { <2 x i8 >, <2 x i1 > } @llvm.uadd.with.overflow (<2 x i8 > %x , <2 x i8 > %y )
770
+ %add = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 0
771
+ %uov = extractvalue { <2 x i8 >, <2 x i1 > } %add_uov , 1
772
+ call void @use.2xi1 (<2 x i1 > %uov )
773
+ %add_ele = extractelement <2 x i8 > %add , i32 0
774
+ %r = icmp eq i8 %add_ele , 0
775
+ ret i1 %r
776
+ }
777
+
778
+ define i1 @extract_value_sadd (i8 %xx , i8 %yy ) {
779
+ ; CHECK-LABEL: @extract_value_sadd(
780
+ ; CHECK-NEXT: [[X:%.*]] = add nuw i8 [[XX:%.*]], 1
781
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
782
+ ; CHECK-NEXT: [[X_LEMMA:%.*]] = icmp sgt i8 [[X]], -1
783
+ ; CHECK-NEXT: [[Y_LEMMA:%.*]] = icmp sgt i8 [[Y]], -1
784
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
785
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
786
+ ; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
787
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0
788
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
789
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
790
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
791
+ ; CHECK-NEXT: ret i1 [[R]]
792
+ ;
793
+ %x = add nuw i8 %xx , 1
794
+ %y = add nuw i8 %yy , 1
795
+ %x_lemma = icmp ult i8 %x , 128
796
+ %y_lemma = icmp ult i8 %y , 128
797
+ call void @llvm.assume (i1 %x_lemma )
798
+ call void @llvm.assume (i1 %y_lemma )
799
+
800
+ %add_sov = call { i8 , i1 } @llvm.sadd.with.overflow (i8 %x , i8 %y )
801
+ %add = extractvalue { i8 , i1 } %add_sov , 0
802
+ %sov = extractvalue { i8 , i1 } %add_sov , 1
803
+ call void @use.i1 (i1 %sov )
804
+ %r = icmp eq i8 %add , 0
805
+ ret i1 %r
806
+ }
807
+
808
+ define i1 @extract_value_sadd_fail (i8 %xx , i8 %yy ) {
809
+ ; CHECK-LABEL: @extract_value_sadd_fail(
810
+ ; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], 1
811
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
812
+ ; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
813
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0
814
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
815
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
816
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
817
+ ; CHECK-NEXT: ret i1 [[R]]
818
+ ;
819
+ %x = add i8 %xx , 1
820
+ %y = add i8 %yy , 1
821
+
822
+ %add_sov = call { i8 , i1 } @llvm.sadd.with.overflow (i8 %x , i8 %y )
823
+ %add = extractvalue { i8 , i1 } %add_sov , 0
824
+ %sov = extractvalue { i8 , i1 } %add_sov , 1
825
+ call void @use.i1 (i1 %sov )
826
+ %r = icmp eq i8 %add , 0
827
+ ret i1 %r
828
+ }
829
+
830
+ define i1 @extract_value_usub (i8 %x , i8 %zz ) {
831
+ ; CHECK-LABEL: @extract_value_usub(
832
+ ; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1
833
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[Z]], [[X:%.*]]
834
+ ; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]])
835
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0
836
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
837
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
838
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
839
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
840
+ ; CHECK-NEXT: ret i1 [[R]]
841
+ ;
842
+ %z = add nuw i8 %zz , 1
843
+ %y = add i8 %x , %z
844
+
845
+ %sub_uov = call { i8 , i1 } @llvm.usub.with.overflow (i8 %x , i8 %y )
846
+ %sub = extractvalue { i8 , i1 } %sub_uov , 0
847
+ %uov = extractvalue { i8 , i1 } %sub_uov , 1
848
+ call void @use.i1 (i1 %uov )
849
+ call void @use.i8 (i8 %sub )
850
+ %r = icmp eq i8 %sub , 0
851
+ ret i1 %r
852
+ }
853
+
854
+ define i1 @extract_value_usub_fail (i8 %x , i8 %z ) {
855
+ ; CHECK-LABEL: @extract_value_usub_fail(
856
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z:%.*]]
857
+ ; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]])
858
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0
859
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
860
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
861
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
862
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
863
+ ; CHECK-NEXT: ret i1 [[R]]
864
+ ;
865
+ %y = add i8 %x , %z
866
+ %sub_uov = call { i8 , i1 } @llvm.usub.with.overflow (i8 %x , i8 %y )
867
+ %sub = extractvalue { i8 , i1 } %sub_uov , 0
868
+ %uov = extractvalue { i8 , i1 } %sub_uov , 1
869
+ call void @use.i1 (i1 %uov )
870
+ call void @use.i8 (i8 %sub )
871
+ %r = icmp eq i8 %sub , 0
872
+ ret i1 %r
873
+ }
874
+
875
+ define i1 @extract_value_ssub (i8 %x , i8 %zz ) {
876
+ ; CHECK-LABEL: @extract_value_ssub(
877
+ ; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1
878
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[Z]], [[X:%.*]]
879
+ ; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[Y]], i8 [[X]])
880
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0
881
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
882
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
883
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
884
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
885
+ ; CHECK-NEXT: ret i1 [[R]]
886
+ ;
887
+ %z = add nuw i8 %zz , 1
888
+ %y = add i8 %x , %z
889
+
890
+ %sub_sov = call { i8 , i1 } @llvm.ssub.with.overflow (i8 %y , i8 %x )
891
+ %sub = extractvalue { i8 , i1 } %sub_sov , 0
892
+ %sov = extractvalue { i8 , i1 } %sub_sov , 1
893
+ call void @use.i1 (i1 %sov )
894
+ call void @use.i8 (i8 %sub )
895
+ %r = icmp eq i8 %sub , 0
896
+ ret i1 %r
897
+ }
898
+
899
+ define i1 @extract_value_ssub_fail (i8 %x ) {
900
+ ; CHECK-LABEL: @extract_value_ssub_fail(
901
+ ; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 10, i8 [[X:%.*]])
902
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0
903
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
904
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
905
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
906
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
907
+ ; CHECK-NEXT: ret i1 [[R]]
908
+ ;
909
+ %sub_sov = call { i8 , i1 } @llvm.ssub.with.overflow (i8 10 , i8 %x )
910
+ %sub = extractvalue { i8 , i1 } %sub_sov , 0
911
+ %sov = extractvalue { i8 , i1 } %sub_sov , 1
912
+ call void @use.i1 (i1 %sov )
913
+ call void @use.i8 (i8 %sub )
914
+ %r = icmp eq i8 %sub , 0
915
+ ret i1 %r
916
+ }
917
+
918
+ define i1 @extract_value_umul (i8 %xx , i8 %yy ) {
919
+ ; CHECK-LABEL: @extract_value_umul(
920
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
921
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
922
+ ; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]])
923
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0
924
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
925
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
926
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
927
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
928
+ ; CHECK-NEXT: ret i1 [[R]]
929
+ ;
930
+ %x = or i8 %xx , 1
931
+ %y = add nuw i8 %yy , 1
932
+
933
+ %mul_uov = call { i8 , i1 } @llvm.umul.with.overflow (i8 %x , i8 %y )
934
+ %mul = extractvalue { i8 , i1 } %mul_uov , 0
935
+ %uov = extractvalue { i8 , i1 } %mul_uov , 1
936
+ call void @use.i1 (i1 %uov )
937
+ call void @use.i8 (i8 %mul )
938
+ %r = icmp eq i8 %mul , 0
939
+ ret i1 %r
940
+ }
941
+
942
+ define i1 @extract_value_umul_fail (i8 %xx , i8 %yy ) {
943
+ ; CHECK-LABEL: @extract_value_umul_fail(
944
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 2
945
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
946
+ ; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]])
947
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0
948
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
949
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
950
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
951
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
952
+ ; CHECK-NEXT: ret i1 [[R]]
953
+ ;
954
+ %x = or i8 %xx , 2
955
+ %y = add nuw i8 %yy , 1
956
+
957
+ %mul_uov = call { i8 , i1 } @llvm.umul.with.overflow (i8 %x , i8 %y )
958
+ %mul = extractvalue { i8 , i1 } %mul_uov , 0
959
+ %uov = extractvalue { i8 , i1 } %mul_uov , 1
960
+ call void @use.i1 (i1 %uov )
961
+ call void @use.i8 (i8 %mul )
962
+ %r = icmp eq i8 %mul , 0
963
+ ret i1 %r
964
+ }
965
+
966
+ define i1 @extract_value_smul (i8 %xx , i8 %yy ) {
967
+ ; CHECK-LABEL: @extract_value_smul(
968
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
969
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
970
+ ; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]])
971
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0
972
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
973
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
974
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
975
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
976
+ ; CHECK-NEXT: ret i1 [[R]]
977
+ ;
978
+ %x = or i8 %xx , 1
979
+ %y = add nuw i8 %yy , 1
980
+
981
+ %mul_sov = call { i8 , i1 } @llvm.smul.with.overflow (i8 %y , i8 %x )
982
+ %mul = extractvalue { i8 , i1 } %mul_sov , 0
983
+ %sov = extractvalue { i8 , i1 } %mul_sov , 1
984
+ call void @use.i1 (i1 %sov )
985
+ call void @use.i8 (i8 %mul )
986
+ %r = icmp eq i8 %mul , 0
987
+ ret i1 %r
988
+ }
989
+
990
+ define i1 @extract_value_smul_fail (i8 %xx , i8 %yy ) {
991
+ ; CHECK-LABEL: @extract_value_smul_fail(
992
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
993
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
994
+ ; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]])
995
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0
996
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
997
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
998
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
999
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
1000
+ ; CHECK-NEXT: ret i1 [[R]]
1001
+ ;
1002
+ %x = or i8 %xx , 1
1003
+ %y = add i8 %yy , 1
1004
+
1005
+ %mul_sov = call { i8 , i1 } @llvm.smul.with.overflow (i8 %y , i8 %x )
1006
+ %mul = extractvalue { i8 , i1 } %mul_sov , 0
1007
+ %sov = extractvalue { i8 , i1 } %mul_sov , 1
1008
+ call void @use.i1 (i1 %sov )
1009
+ call void @use.i8 (i8 %mul )
1010
+ %r = icmp eq i8 %mul , 0
1011
+ ret i1 %r
1012
+ }
1013
+
633
1014
declare void @use (i1 )
634
1015
declare void @sink (i8 )
0 commit comments