[PATCH] D12799: [ValueTracking] Teach isKnownNonZero a new trick
James Molloy via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 11 05:51:20 PDT 2015
jmolloy created this revision.
jmolloy added reviewers: majnemer, hfinkel.
jmolloy added a subscriber: llvm-commits.
jmolloy set the repository for this revision to rL LLVM.
If the shifter operand is a constant, and all of the bits shifted out are known to be zero, then if X is known non-zero at least one non-zero bit must remain.
Repository:
rL LLVM
http://reviews.llvm.org/D12799
Files:
lib/Analysis/ValueTracking.cpp
unittests/Analysis/ValueTrackingTest.cpp
Index: unittests/Analysis/ValueTrackingTest.cpp
===================================================================
--- unittests/Analysis/ValueTrackingTest.cpp
+++ unittests/Analysis/ValueTrackingTest.cpp
@@ -21,7 +21,7 @@
namespace {
-class MatchSelectPatternTest : public testing::Test {
+class AssemblyParsingTestHelper {
protected:
void parseAssembly(const char *Assembly) {
SMDiagnostic Error;
@@ -50,19 +50,31 @@
report_fatal_error("@test must have an instruction %A");
}
+ std::unique_ptr<Module> M;
+ Instruction *A;
+};
+
+class MatchSelectPatternTest : public testing::Test,
+ public AssemblyParsingTestHelper {
+protected:
void expectPattern(const SelectPatternResult &P) {
Value *LHS, *RHS;
Instruction::CastOps CastOp;
SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);
EXPECT_EQ(P.Flavor, R.Flavor);
EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
EXPECT_EQ(P.Ordered, R.Ordered);
}
-
- std::unique_ptr<Module> M;
- Instruction *A, *B;
};
+class KnownValueTest : public testing::Test,
+ public AssemblyParsingTestHelper {
+protected:
+ void expectKnownNonZero() {
+ EXPECT_TRUE(isKnownNonZero(A, M->getDataLayout()));
+ }
+};
+
}
TEST_F(MatchSelectPatternTest, SimpleFMin) {
@@ -187,3 +199,16 @@
// The cast types here aren't the same, so we cannot match an UMIN.
expectPattern({SPF_UNKNOWN, SPNB_NA, false});
}
+
+TEST_F(KnownValueTest, NonZeroShiftRight) {
+ parseAssembly(
+ "define i8 @test(i8 %p, i8* %pq) {\n"
+ " %q = load i8, i8* %pq, !range !0\n" // %q is known nonzero; no known bits
+ " %1 = or i8 %p, 1\n" // %1[0] = 1, %1 is odd
+ " %2 = shl i8 %1, %q\n" // %2[0] = 0, rest unknown but cannot be zero
+ " %A = lshr i8 %2, 1\n" // We should know that %A is nonzero.
+ " ret i8 %A\n"
+ "}\n"
+ "!0 = !{ i8 1, i8 5 }\n");
+ expectKnownNonZero();
+}
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1824,6 +1824,19 @@
ComputeSignBit(X, XKnownNonNegative, XKnownNegative, DL, Depth, Q);
if (XKnownNegative)
return true;
+
+ // If the shifter operand is a constant, and all of the bits shifted
+ // out are known to be zero, and X is known non-zero then at least one
+ // non-zero bit must remain.
+ if (ConstantInt *Shift = dyn_cast<ConstantInt>(Y))
+ if (Shift->getLimitedValue() < BitWidth) {
+ APInt KnownZero(BitWidth, 0);
+ APInt KnownOne(BitWidth, 0);
+ computeKnownBits(X, KnownZero, KnownOne, DL, Depth, Q);
+ APInt LoBits = APInt::getLowBitsSet(BitWidth, Shift->getLimitedValue());
+ if ((KnownZero & LoBits).eq(LoBits))
+ return KnownOne.getBoolValue() || isKnownNonZero(X, DL, Depth, Q);
+ }
}
// div exact can only produce a zero if the dividend is zero.
else if (match(V, m_Exact(m_IDiv(m_Value(X), m_Value())))) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12799.34543.patch
Type: text/x-patch
Size: 3056 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150911/65301805/attachment.bin>
More information about the llvm-commits
mailing list