Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -350,6 +350,15 @@ } } + // The result of the bottom bits of an integer multiply can + // be inferred by looking at the bottom bits of both operands + // and multiplying them together. + APInt bottom0 = Known.One & ~Known.Zero; + APInt bottom1 = Known2.One & ~Known2.Zero; + // Find the last bit known on both operands. + unsigned trailBitsKnown = (Known.Zero | Known.One).countTrailingOnes(); + trailBitsKnown = std::min(trailBitsKnown, (Known2.Zero | Known2.One).countTrailingOnes()); + // If low bits are zero in either operand, output low known-0 bits. // Also compute a conservative estimate for high known-0 bits. // More trickiness is possible, but this is sufficient for the @@ -366,6 +375,23 @@ Known.Zero.setLowBits(TrailZ); Known.Zero.setHighBits(LeadZ); + if (trailBitsKnown != 0) { + // Finally, these are the known bottom bits of the result. + APInt bottomKnown = bottom0.getLoBits(trailBitsKnown) * + bottom1.getLoBits(trailBitsKnown); + unsigned trailKnown = bottomKnown.getBitWidth() - bottomKnown.countLeadingZeros(); + trailKnown = std::min(trailKnown, Known.getBitWidth()); + for (unsigned bit = TrailZ; bit < trailKnown; ++bit) { + if ((bottomKnown & (1<(F->getEntryBlock().getTerminator())->getOperand(0); EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u); } + +TEST(ValueTracking, ComputeKnownBits) { + StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { " + " %ash = mul i32 %a, 8 " + " %aad = add i32 %ash, 7 " + " %aan = and i32 %aad, 4095 " + " %bsh = shl i32 %b, 4 " + " %bad = add i32 %bsh, 6 " + " %ban = and i32 %bad, 4095 " + " %mul = mul i32 %aan, %ban " + " ret i32 %mul " + "} "; + + LLVMContext Context; + SMDiagnostic Error; + auto M = parseAssemblyString(Assembly, Error, Context); + assert(M && "Bad assembly?"); + + auto *F = M->getFunction("f"); + assert(F && "Bad assembly?"); + + auto *RVal = + cast(F->getEntryBlock().getTerminator())->getOperand(0); + auto Known = computeKnownBits(RVal, M->getDataLayout()); + ASSERT_FALSE(Known.hasConflict()); + EXPECT_EQ(Known.One.getZExtValue(), 42u); + EXPECT_EQ(Known.Zero.getZExtValue(), 4278190101u); +}