Skip to content

Commit 37ca6fa

Browse files
committed
[ValueTracking] Add support for overflow detection functions is isKnownNonZero
Adds support for: `{s,u}{add,sub,mul}.with.overflow` The logic is identical to the the non-overflow binops, we where just missing the cases. Closes llvm#87701
1 parent f0a487d commit 37ca6fa

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,6 +2798,29 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
27982798
// handled in isKnownNonZero.
27992799
return false;
28002800
}
2801+
case Instruction::ExtractValue: {
2802+
const WithOverflowInst *WO;
2803+
if (match(I, m_ExtractValue<0>(m_WithOverflowInst(WO)))) {
2804+
switch (WO->getBinaryOp()) {
2805+
default:
2806+
break;
2807+
case Instruction::Add:
2808+
return isNonZeroAdd(DemandedElts, Depth, Q, BitWidth,
2809+
WO->getArgOperand(0), WO->getArgOperand(1),
2810+
/*NSW=*/false,
2811+
/*NUW=*/false);
2812+
case Instruction::Sub:
2813+
return isNonZeroSub(DemandedElts, Depth, Q, BitWidth,
2814+
WO->getArgOperand(0), WO->getArgOperand(1));
2815+
case Instruction::Mul:
2816+
return isNonZeroMul(DemandedElts, Depth, Q, BitWidth,
2817+
WO->getArgOperand(0), WO->getArgOperand(1),
2818+
/*NSW=*/false, /*NUW=*/false);
2819+
break;
2820+
}
2821+
}
2822+
break;
2823+
}
28012824
case Instruction::Call:
28022825
case Instruction::Invoke: {
28032826
const auto *Call = cast<CallBase>(I);

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

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -642,12 +642,9 @@ define i1 @extract_value_uadd(<2 x i8> %xx, <2 x i8> %yy) {
642642
; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
643643
; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
644644
; 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
646645
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
647646
; 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]]
647+
; CHECK-NEXT: ret i1 false
651648
;
652649
%x0 = and <2 x i8> %xx, <i8 63, i8 255>
653650
%y0 = and <2 x i8> %yy, <i8 63, i8 255>
@@ -670,12 +667,9 @@ define i1 @extract_value_uadd2(<2 x i8> %xx, <2 x i8> %yy) {
670667
; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 0, i8 1>
671668
; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 0, i8 1>
672669
; 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
674670
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
675671
; 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]]
672+
; CHECK-NEXT: ret i1 false
679673
;
680674
%x0 = and <2 x i8> %xx, <i8 255, i8 63>
681675
%y0 = and <2 x i8> %yy, <i8 255, i8 63>
@@ -784,11 +778,9 @@ define i1 @extract_value_sadd(i8 %xx, i8 %yy) {
784778
; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
785779
; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
786780
; 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
788781
; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
789782
; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
790-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
791-
; CHECK-NEXT: ret i1 [[R]]
783+
; CHECK-NEXT: ret i1 false
792784
;
793785
%x = add nuw i8 %xx, 1
794786
%y = add nuw i8 %yy, 1
@@ -836,8 +828,7 @@ define i1 @extract_value_usub(i8 %x, i8 %zz) {
836828
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
837829
; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
838830
; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
839-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
840-
; CHECK-NEXT: ret i1 [[R]]
831+
; CHECK-NEXT: ret i1 false
841832
;
842833
%z = add nuw i8 %zz, 1
843834
%y = add i8 %x, %z
@@ -881,8 +872,7 @@ define i1 @extract_value_ssub(i8 %x, i8 %zz) {
881872
; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
882873
; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
883874
; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
884-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
885-
; CHECK-NEXT: ret i1 [[R]]
875+
; CHECK-NEXT: ret i1 false
886876
;
887877
%z = add nuw i8 %zz, 1
888878
%y = add i8 %x, %z
@@ -924,8 +914,7 @@ define i1 @extract_value_umul(i8 %xx, i8 %yy) {
924914
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
925915
; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
926916
; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
927-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
928-
; CHECK-NEXT: ret i1 [[R]]
917+
; CHECK-NEXT: ret i1 false
929918
;
930919
%x = or i8 %xx, 1
931920
%y = add nuw i8 %yy, 1
@@ -972,8 +961,7 @@ define i1 @extract_value_smul(i8 %xx, i8 %yy) {
972961
; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
973962
; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
974963
; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
975-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
976-
; CHECK-NEXT: ret i1 [[R]]
964+
; CHECK-NEXT: ret i1 false
977965
;
978966
%x = or i8 %xx, 1
979967
%y = add nuw i8 %yy, 1

0 commit comments

Comments
 (0)