Skip to content

Commit a02b3c0

Browse files
committed
[ValueTracking] Add tests for overflow detection functions is isKnownNonZero; NFC
1 parent 41c5221 commit a02b3c0

File tree

1 file changed

+381
-0
lines changed

1 file changed

+381
-0
lines changed

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,5 +630,386 @@ define i8 @or_ne_bits_must_be_unset2_fail(i8 %x, i8 %y) {
630630
ret i8 %r
631631
}
632632

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+
6331014
declare void @use(i1)
6341015
declare void @sink(i8)

0 commit comments

Comments
 (0)