Skip to content

Commit 4f6ada5

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
1 parent b675d68 commit 4f6ada5

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 9 additions & 1 deletion
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+
auto *TI = cast<TruncInst>(I);
2637+
// nuw/nsw trunc preserves zero/non-zero status of input.
2638+
if (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap())
2639+
return isKnownNonZero(TI->getOperand(0), Q, Depth + 1);
2640+
break;
2641+
}
26352642
case Instruction::Sub:
26362643
return isNonZeroSub(DemandedElts, Depth, Q, BitWidth, I->getOperand(0),
26372644
I->getOperand(1));
@@ -3785,7 +3792,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
37853792
// truncation, then we can make use of that. Otherwise we don't know
37863793
// anything.
37873794
Tmp = ComputeNumSignBits(U->getOperand(0), Depth + 1, Q);
3788-
unsigned OperandTyBits = U->getOperand(0)->getType()->getScalarSizeInBits();
3795+
unsigned OperandTyBits =
3796+
U->getOperand(0)->getType()->getScalarSizeInBits();
37893797
if (Tmp > (OperandTyBits - TyBits))
37903798
return Tmp - (OperandTyBits - TyBits);
37913799

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)