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 @@ -1872,6 +1872,10 @@ } } break; + case Instruction::Freeze: + if (isGuaranteedNotToBePoison(I->getOperand(0), Q.CxtI, Q.DT, Depth + 1)) + computeKnownBits(I->getOperand(0), Known, Depth + 1, Q); + break; } } @@ -2577,6 +2581,13 @@ return isKnownNonZero(Vec, DemandedVecElts, Depth, Q); } } + // Freeze + else if (const FreezeInst *FI = dyn_cast(V)) { + auto *Op = FI->getOperand(0); + if (isKnownNonZero(Op, Depth, Q) && + isGuaranteedNotToBePoison(Op, Q.CxtI, Q.DT, Depth)) + return true; + } KnownBits Known(BitWidth); computeKnownBits(V, DemandedElts, Known, Depth, Q); diff --git a/llvm/test/Transforms/InstSimplify/known-non-zero.ll b/llvm/test/Transforms/InstSimplify/known-non-zero.ll --- a/llvm/test/Transforms/InstSimplify/known-non-zero.ll +++ b/llvm/test/Transforms/InstSimplify/known-non-zero.ll @@ -145,3 +145,24 @@ %inc = add nuw nsw i32 %shift.0, 1 br label %for.cond } + +define i1 @freeze_nonzero(i8 %x, i8 %mask) { +; CHECK-LABEL: @freeze_nonzero( +; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], [[MASK:%.*]] +; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[Y]], 0 +; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] +; CHECK: A: +; CHECK-NEXT: ret i1 false +; CHECK: B: +; CHECK-NEXT: ret i1 false +; + %y = or i8 %x, %mask + %c = icmp ne i8 %y, 0 + br i1 %c, label %A, label %B +A: + %fr = freeze i8 %y + %c2 = icmp eq i8 %fr, 0 + ret i1 %c2 +B: + ret i1 0 +} diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1059,6 +1059,24 @@ EXPECT_EQ(Known.One.getZExtValue(), 0u); } +TEST_F(ComputeKnownBitsTest, ComputeKnownBitsFreeze) { + parseAssembly("define void @test() {\n" + " %m = call i32 @any_num()\n" + " %A = freeze i32 %m\n" + " %n = and i32 %m, 31\n" + " %c = icmp eq i32 %n, 0\n" + " call void @llvm.assume(i1 %c)\n" + " ret void\n" + "}\n" + "declare void @llvm.assume(i1)\n" + "declare i32 @any_num()\n"); + AssumptionCache AC(*F); + KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, + F->front().getTerminator()); + EXPECT_EQ(Known.Zero.getZExtValue(), 31u); + EXPECT_EQ(Known.One.getZExtValue(), 0u); +} + class IsBytewiseValueTest : public ValueTrackingTest, public ::testing::WithParamInterface< std::pair> {