Skip to content

Commit 90ef6b5

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.
1 parent 08d3ac3 commit 90ef6b5

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2791,6 +2791,35 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
27912791
// handled in isKnownNonZero.
27922792
return false;
27932793
}
2794+
case Instruction::ExtractValue:
2795+
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I->getOperand(0))) {
2796+
const ExtractValueInst *EVI = cast<ExtractValueInst>(I);
2797+
if (EVI->getNumIndices() != 1 || EVI->getIndices()[0] != 0)
2798+
break;
2799+
switch (II->getIntrinsicID()) {
2800+
default:
2801+
break;
2802+
case Intrinsic::uadd_with_overflow:
2803+
case Intrinsic::sadd_with_overflow:
2804+
return isNonZeroAdd(APInt::getAllOnes(DemandedElts.getBitWidth()),
2805+
Depth, Q, BitWidth, II->getArgOperand(0),
2806+
II->getArgOperand(1),
2807+
/*NSW=*/false,
2808+
/*NUW=*/false);
2809+
case Intrinsic::usub_with_overflow:
2810+
case Intrinsic::ssub_with_overflow:
2811+
return isNonZeroSub(APInt::getAllOnes(DemandedElts.getBitWidth()),
2812+
Depth, Q, BitWidth, II->getArgOperand(0),
2813+
II->getArgOperand(1));
2814+
case Intrinsic::umul_with_overflow:
2815+
case Intrinsic::smul_with_overflow:
2816+
return isNonZeroMul(APInt::getAllOnes(DemandedElts.getBitWidth()),
2817+
Depth, Q, BitWidth, II->getArgOperand(0),
2818+
II->getArgOperand(1), /*NSW=*/false, /*NUW=*/false);
2819+
break;
2820+
}
2821+
}
2822+
break;
27942823
case Instruction::Call:
27952824
case Instruction::Invoke: {
27962825
const auto *Call = cast<CallBase>(I);

llvm/test/Transforms/InstSimplify/known-non-zero.ll

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,9 @@ define i1 @extract_value_uadd(i8 %xx, i8 %yy) {
177177
; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
178178
; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
179179
; CHECK-NEXT: [[ADD_UOV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
180-
; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_UOV]], 0
181180
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[ADD_UOV]], 1
182181
; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
183-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
184-
; CHECK-NEXT: ret i1 [[R]]
182+
; CHECK-NEXT: ret i1 false
185183
;
186184
%x = add nuw i8 %xx, 1
187185
%y = add nuw i8 %yy, 1
@@ -237,11 +235,9 @@ define i1 @extract_value_sadd(i8 %xx, i8 %yy) {
237235
; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
238236
; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
239237
; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
240-
; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0
241238
; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
242239
; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
243-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
244-
; CHECK-NEXT: ret i1 [[R]]
240+
; CHECK-NEXT: ret i1 false
245241
;
246242
%x = add nuw i8 %xx, 1
247243
%y = add nuw i8 %yy, 1
@@ -289,8 +285,7 @@ define i1 @extract_value_usub(i8 %x, i8 %zz) {
289285
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
290286
; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
291287
; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
292-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
293-
; CHECK-NEXT: ret i1 [[R]]
288+
; CHECK-NEXT: ret i1 false
294289
;
295290
%z = add nuw i8 %zz, 1
296291
%y = add i8 %x, %z
@@ -334,8 +329,7 @@ define i1 @extract_value_ssub(i8 %x, i8 %zz) {
334329
; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
335330
; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
336331
; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
337-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
338-
; CHECK-NEXT: ret i1 [[R]]
332+
; CHECK-NEXT: ret i1 false
339333
;
340334
%z = add nuw i8 %zz, 1
341335
%y = add i8 %x, %z
@@ -377,8 +371,7 @@ define i1 @extract_value_umul(i8 %xx, i8 %yy) {
377371
; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
378372
; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
379373
; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
380-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
381-
; CHECK-NEXT: ret i1 [[R]]
374+
; CHECK-NEXT: ret i1 false
382375
;
383376
%x = or i8 %xx, 1
384377
%y = add nuw i8 %yy, 1
@@ -425,8 +418,7 @@ define i1 @extract_value_smul(i8 %xx, i8 %yy) {
425418
; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
426419
; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
427420
; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
428-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
429-
; CHECK-NEXT: ret i1 [[R]]
421+
; CHECK-NEXT: ret i1 false
430422
;
431423
%x = or i8 %xx, 1
432424
%y = add nuw i8 %yy, 1

0 commit comments

Comments
 (0)