diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2581,6 +2581,12 @@ Q.DL.getTypeSizeInBits(I->getType()).getFixedValue()) return isKnownNonZero(I->getOperand(0), Depth, Q); break; + case Instruction::Sub: + if (auto *C = dyn_cast(I->getOperand(0))) + if (C->isNullValue() && + isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q)) + return true; + break; case Instruction::Or: // X | Y != 0 if X != 0 or Y != 0. return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q) || @@ -2725,8 +2731,26 @@ isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT, Depth); case Instruction::Call: - if (cast(I)->getIntrinsicID() == Intrinsic::vscale) - return true; + if (auto *II = dyn_cast(I)) { + switch (II->getIntrinsicID()) { + case Intrinsic::abs: + case Intrinsic::bitreverse: + case Intrinsic::bswap: + case Intrinsic::ctpop: + if (isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q)) + return true; + break; + case Intrinsic::uadd_sat: + if (isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q) || + isKnownNonZero(II->getArgOperand(1), DemandedElts, Depth, Q)) + return true; + break; + case Intrinsic::vscale: + return true; + default: + break; + } + } break; } diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll --- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll @@ -20,9 +20,7 @@ ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) ; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[X]] ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0 -; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[CMP0]] ; %ne = icmp ne i8 %x, 0 call void @llvm.assume(i1 %ne) @@ -40,9 +38,7 @@ ; CHECK: true: ; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0 -; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[CMP0]] ; CHECK: false: ; CHECK-NEXT: ret i1 [[NE]] ; @@ -89,9 +85,7 @@ ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) ; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[X]]) ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0 -; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[CMP0]] ; %ne = icmp ne i8 %x, 0 call void @llvm.assume(i1 %ne) @@ -108,9 +102,7 @@ ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) ; CHECK-NEXT: [[Z:%.*]] = call i16 @llvm.bswap.i16(i16 [[X]]) ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i16 [[Z]], [[Y:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i16 [[Y]], 0 -; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[CMP0]] ; %ne = icmp ne i16 %x, 0 call void @llvm.assume(i1 %ne) @@ -130,9 +122,7 @@ ; CHECK: false: ; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X]]) ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0 -; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[CMP0]] ; %ne = icmp eq i8 %x, 0 br i1 %ne, label %true, label %false @@ -152,9 +142,7 @@ ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) ; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X]], i8 [[Y:%.*]]) ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[W:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[W]], 0 -; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[CMP0]] ; %ne = icmp ne i8 %x, 0 call void @llvm.assume(i1 %ne) @@ -170,9 +158,7 @@ ; CHECK-NEXT: [[YNZ:%.*]] = or <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[Z:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[YNZ]]) ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt <2 x i8> [[Z]], [[W:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i8> [[W]], zeroinitializer -; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[CMP0]], [[CMP1]] -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> [[CMP0]] ; %ynz = or <2 x i8> %y, %z = call <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8> %x, <2 x i8> %ynz)