Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit c16c6e6

Browse files
committed
[ValueTracking] Make unit tests easier to write; NFC
Generalize the existing MatchSelectPatternTest class to also work with other types of tests. This reduces the amount of boilerplate necessary to write ValueTracking tests in general, and computeKnownBits tests in particular. The inherited convention is that the function must be @test and the tested instruction %A. Differential Revision: https://reviews.llvm.org/D55141 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348043 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 39cd630 commit c16c6e6

File tree

1 file changed

+63
-106
lines changed

1 file changed

+63
-106
lines changed

unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 63 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using namespace llvm;
2222

2323
namespace {
2424

25-
class MatchSelectPatternTest : public testing::Test {
25+
class ValueTrackingTest : public testing::Test {
2626
protected:
2727
void parseAssembly(const char *Assembly) {
2828
SMDiagnostic Error;
@@ -51,6 +51,13 @@ class MatchSelectPatternTest : public testing::Test {
5151
report_fatal_error("@test must have an instruction %A");
5252
}
5353

54+
LLVMContext Context;
55+
std::unique_ptr<Module> M;
56+
Instruction *A;
57+
};
58+
59+
class MatchSelectPatternTest : public ValueTrackingTest {
60+
protected:
5461
void expectPattern(const SelectPatternResult &P) {
5562
Value *LHS, *RHS;
5663
Instruction::CastOps CastOp;
@@ -59,10 +66,16 @@ class MatchSelectPatternTest : public testing::Test {
5966
EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
6067
EXPECT_EQ(P.Ordered, R.Ordered);
6168
}
69+
};
6270

63-
LLVMContext Context;
64-
std::unique_ptr<Module> M;
65-
Instruction *A, *B;
71+
class ComputeKnownBitsTest : public ValueTrackingTest {
72+
protected:
73+
void expectKnownBits(uint64_t Zero, uint64_t One) {
74+
auto Known = computeKnownBits(A, M->getDataLayout());
75+
ASSERT_FALSE(Known.hasConflict());
76+
EXPECT_EQ(Known.One.getZExtValue(), One);
77+
EXPECT_EQ(Known.Zero.getZExtValue(), Zero);
78+
}
6679
};
6780

6881
}
@@ -497,117 +510,61 @@ TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {
497510
}
498511
}
499512

500-
TEST(ValueTracking, ComputeNumSignBits_PR32045) {
501-
StringRef Assembly = "define i32 @f(i32 %a) { "
502-
" %val = ashr i32 %a, -1 "
503-
" ret i32 %val "
504-
"} ";
505-
506-
LLVMContext Context;
507-
SMDiagnostic Error;
508-
auto M = parseAssemblyString(Assembly, Error, Context);
509-
assert(M && "Bad assembly?");
510-
511-
auto *F = M->getFunction("f");
512-
assert(F && "Bad assembly?");
513-
514-
auto *RVal =
515-
cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
516-
EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
513+
TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) {
514+
parseAssembly(
515+
"define i32 @test(i32 %a) {\n"
516+
" %A = ashr i32 %a, -1\n"
517+
" ret i32 %A\n"
518+
"}\n");
519+
EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
517520
}
518521

519522
// No guarantees for canonical IR in this analysis, so this just bails out.
520-
TEST(ValueTracking, ComputeNumSignBits_Shuffle) {
521-
StringRef Assembly = "define <2 x i32> @f() { "
522-
" %val = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0> "
523-
" ret <2 x i32> %val "
524-
"} ";
525-
526-
LLVMContext Context;
527-
SMDiagnostic Error;
528-
auto M = parseAssemblyString(Assembly, Error, Context);
529-
assert(M && "Bad assembly?");
530-
531-
auto *F = M->getFunction("f");
532-
assert(F && "Bad assembly?");
533-
534-
auto *RVal =
535-
cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
536-
EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
523+
TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) {
524+
parseAssembly(
525+
"define <2 x i32> @test() {\n"
526+
" %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n"
527+
" ret <2 x i32> %A\n"
528+
"}\n");
529+
EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
537530
}
538531

539532
// No guarantees for canonical IR in this analysis, so a shuffle element that
540533
// references an undef value means this can't return any extra information.
541-
TEST(ValueTracking, ComputeNumSignBits_Shuffle2) {
542-
StringRef Assembly = "define <2 x i32> @f(<2 x i1> %x) { "
543-
" %sext = sext <2 x i1> %x to <2 x i32> "
544-
" %val = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2> "
545-
" ret <2 x i32> %val "
546-
"} ";
547-
548-
LLVMContext Context;
549-
SMDiagnostic Error;
550-
auto M = parseAssemblyString(Assembly, Error, Context);
551-
assert(M && "Bad assembly?");
552-
553-
auto *F = M->getFunction("f");
554-
assert(F && "Bad assembly?");
555-
556-
auto *RVal =
557-
cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
558-
EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
534+
TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) {
535+
parseAssembly(
536+
"define <2 x i32> @test(<2 x i1> %x) {\n"
537+
" %sext = sext <2 x i1> %x to <2 x i32>\n"
538+
" %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n"
539+
" ret <2 x i32> %A\n"
540+
"}\n");
541+
EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
559542
}
560543

561-
TEST(ValueTracking, ComputeKnownBits) {
562-
StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { "
563-
" %ash = mul i32 %a, 8 "
564-
" %aad = add i32 %ash, 7 "
565-
" %aan = and i32 %aad, 4095 "
566-
" %bsh = shl i32 %b, 4 "
567-
" %bad = or i32 %bsh, 6 "
568-
" %ban = and i32 %bad, 4095 "
569-
" %mul = mul i32 %aan, %ban "
570-
" ret i32 %mul "
571-
"} ";
572-
573-
LLVMContext Context;
574-
SMDiagnostic Error;
575-
auto M = parseAssemblyString(Assembly, Error, Context);
576-
assert(M && "Bad assembly?");
577-
578-
auto *F = M->getFunction("f");
579-
assert(F && "Bad assembly?");
580-
581-
auto *RVal =
582-
cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
583-
auto Known = computeKnownBits(RVal, M->getDataLayout());
584-
ASSERT_FALSE(Known.hasConflict());
585-
EXPECT_EQ(Known.One.getZExtValue(), 10u);
586-
EXPECT_EQ(Known.Zero.getZExtValue(), 4278190085u);
544+
TEST_F(ComputeKnownBitsTest, ComputeKnownBits) {
545+
parseAssembly(
546+
"define i32 @test(i32 %a, i32 %b) {\n"
547+
" %ash = mul i32 %a, 8\n"
548+
" %aad = add i32 %ash, 7\n"
549+
" %aan = and i32 %aad, 4095\n"
550+
" %bsh = shl i32 %b, 4\n"
551+
" %bad = or i32 %bsh, 6\n"
552+
" %ban = and i32 %bad, 4095\n"
553+
" %A = mul i32 %aan, %ban\n"
554+
" ret i32 %A\n"
555+
"}\n");
556+
expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u);
587557
}
588558

589-
TEST(ValueTracking, ComputeKnownMulBits) {
590-
StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { "
591-
" %aa = shl i32 %a, 5 "
592-
" %bb = shl i32 %b, 5 "
593-
" %aaa = or i32 %aa, 24 "
594-
" %bbb = or i32 %bb, 28 "
595-
" %mul = mul i32 %aaa, %bbb "
596-
" ret i32 %mul "
597-
"} ";
598-
599-
LLVMContext Context;
600-
SMDiagnostic Error;
601-
auto M = parseAssemblyString(Assembly, Error, Context);
602-
assert(M && "Bad assembly?");
603-
604-
auto *F = M->getFunction("f");
605-
assert(F && "Bad assembly?");
606-
607-
auto *RVal =
608-
cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
609-
auto Known = computeKnownBits(RVal, M->getDataLayout());
610-
ASSERT_FALSE(Known.hasConflict());
611-
EXPECT_EQ(Known.One.getZExtValue(), 32u);
612-
EXPECT_EQ(Known.Zero.getZExtValue(), 95u);
559+
TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) {
560+
parseAssembly(
561+
"define i32 @test(i32 %a, i32 %b) {\n"
562+
" %aa = shl i32 %a, 5\n"
563+
" %bb = shl i32 %b, 5\n"
564+
" %aaa = or i32 %aa, 24\n"
565+
" %bbb = or i32 %bb, 28\n"
566+
" %A = mul i32 %aaa, %bbb\n"
567+
" ret i32 %A\n"
568+
"}\n");
569+
expectKnownBits(/*zero*/ 95u, /*one*/ 32u);
613570
}

0 commit comments

Comments
 (0)