Skip to content

Commit b933c84

Browse files
committed
[ValueTracking] Add support for trunc nuw/nsw in isKnowNonZero
With `nsw`/`nuw`, the `trunc` is non-zero if its operand is non-zero. Proofs: https://alive2.llvm.org/ce/z/iujmk6 Closes #89643
1 parent b3ca9c3 commit b933c84

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,13 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
26322632
Q.DL.getTypeSizeInBits(I->getType()).getFixedValue())
26332633
return isKnownNonZero(I->getOperand(0), Q, Depth);
26342634
break;
2635+
case Instruction::Trunc:
2636+
// nuw/nsw trunc preserves zero/non-zero status of input.
2637+
if (auto *TI = dyn_cast<TruncInst>(I))
2638+
if (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap())
2639+
return isKnownNonZero(TI->getOperand(0), Q, Depth);
2640+
break;
2641+
26352642
case Instruction::Sub:
26362643
return isNonZeroSub(DemandedElts, Depth, Q, BitWidth, I->getOperand(0),
26372644
I->getOperand(1));

llvm/test/Analysis/ValueTracking/known-non-zero.ll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,9 +1452,7 @@ define i1 @trunc_nsw_non_zero(i8 %x) {
14521452
; CHECK-LABEL: @trunc_nsw_non_zero(
14531453
; CHECK-NEXT: [[X_NE_Z:%.*]] = icmp ne i8 [[X:%.*]], 0
14541454
; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_Z]])
1455-
; CHECK-NEXT: [[V:%.*]] = trunc nsw i8 [[X]] to i4
1456-
; CHECK-NEXT: [[R:%.*]] = icmp ne i4 [[V]], 0
1457-
; CHECK-NEXT: ret i1 [[R]]
1455+
; CHECK-NEXT: ret i1 true
14581456
;
14591457
%x_ne_z = icmp ne i8 %x, 0
14601458
call void @llvm.assume(i1 %x_ne_z)
@@ -1465,10 +1463,7 @@ define i1 @trunc_nsw_non_zero(i8 %x) {
14651463

14661464
define i1 @trunc_nuw_non_zero(i8 %xx) {
14671465
; CHECK-LABEL: @trunc_nuw_non_zero(
1468-
; CHECK-NEXT: [[X:%.*]] = add nuw i8 [[XX:%.*]], 1
1469-
; CHECK-NEXT: [[V:%.*]] = trunc nuw i8 [[X]] to i4
1470-
; CHECK-NEXT: [[R:%.*]] = icmp eq i4 [[V]], 0
1471-
; CHECK-NEXT: ret i1 [[R]]
1466+
; CHECK-NEXT: ret i1 false
14721467
;
14731468
%x = add nuw i8 %xx, 1
14741469
%v = trunc nuw i8 %x to i4

0 commit comments

Comments
 (0)