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 @@ -13,8 +13,8 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Support/KnownBits.h" +#include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" using namespace llvm; @@ -23,21 +23,26 @@ class ValueTrackingTest : public testing::Test { protected: - void parseAssembly(const char *Assembly) { + std::unique_ptr parseModule(StringRef Assembly) { SMDiagnostic Error; - M = parseAssemblyString(Assembly, Error, Context); + std::unique_ptr M = parseAssemblyString(Assembly, Error, Context); std::string errMsg; raw_string_ostream os(errMsg); Error.print("", os); + EXPECT_TRUE(M) << os.str(); + + return M; + } - // A failure here means that the test itself is buggy. - if (!M) - report_fatal_error(os.str()); + void parseAssembly(StringRef Assembly) { + M = parseModule(Assembly); + ASSERT_TRUE(M); Function *F = M->getFunction("test"); - if (F == nullptr) - report_fatal_error("Test must have a function named @test"); + ASSERT_TRUE(F) << "Test must have a function @test"; + if (!F) + return; A = nullptr; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { @@ -46,13 +51,12 @@ A = &*I; } } - if (A == nullptr) - report_fatal_error("@test must have an instruction %A"); + ASSERT_TRUE(A) << "@test must have an instruction %A"; } LLVMContext Context; std::unique_ptr M; - Instruction *A; + Instruction *A = nullptr; }; class MatchSelectPatternTest : public ValueTrackingTest { @@ -689,3 +693,240 @@ "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); expectKnownBits(/*zero*/ 2u, /*one*/ 0u); } + +class IsBytewiseValueTest : public ValueTrackingTest, + public ::testing::WithParamInterface< + std::pair> { +protected: +}; + +const std::pair IsBytewiseValueTests[] = { + { + "i8 0", + "i48* null", + }, + { + "i8 undef", + "i48* undef", + }, + { + "i8 0", + "i8 zeroinitializer", + }, + { + "i8 0", + "i8 0", + }, + { + "i8 -86", + "i8 -86", + }, + { + "i8 -1", + "i8 -1", + }, + { + "i8 undef", + "i16 undef", + }, + { + "i8 0", + "i16 0", + }, + { + "", + "i16 7", + }, + { + "i8 -86", + "i16 -21846", + }, + { + "i8 -1", + "i16 -1", + }, + { + "i8 0", + "i48 0", + }, + { + "i8 -1", + "i48 -1", + }, + { + "i8 0", + "i49 0", + }, + { + "", + "i49 -1", + }, + { + "i8 0", + "half 0xH0000", + }, + { + "i8 -85", + "half 0xHABAB", + }, + { + "i8 0", + "float 0.0", + }, + { + "i8 -1", + "float 0xFFFFFFFFE0000000", + }, + { + "i8 0", + "double 0.0", + }, + { + "i8 -15", + "double 0xF1F1F1F1F1F1F1F1", + }, + { + "i8 undef", + "i16* undef", + }, + { + "i8 0", + "i16* inttoptr (i64 0 to i16*)", + }, + { + "", + "i16* inttoptr (i64 -1 to i16*)", + }, + { + "", + "i16* inttoptr (i64 -6148914691236517206 to i16*)", + }, + { + "", + "i16* inttoptr (i48 -1 to i16*)", + }, + { + "", + "i16* inttoptr (i96 -1 to i16*)", + }, + { + "i8 0", + "[0 x i8] zeroinitializer", + }, + { + "i8 undef", + "[0 x i8] undef", + }, + { + "i8 0", + "[6 x i8] zeroinitializer", + }, + { + "i8 undef", + "[6 x i8] undef", + }, + { + "i8 1", + "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]", + }, + { + "", + "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]", + }, + { + "i8 -1", + "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]", + }, + { + "", + "[4 x i8] [i8 1, i8 2, i8 1, i8 1]", + }, + { + "i8 1", + "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]", + }, + { + "i8 0", + "<6 x i8> zeroinitializer", + }, + { + "i8 undef", + "<6 x i8> undef", + }, + { + "i8 1", + "<5 x i8> ", + }, + { + "", + "<5 x i64> ", + }, + { + "i8 -1", + "<5 x i64> ", + }, + { + "", + "<4 x i8> ", + }, + { + "", + "<2 x i8> < i8 5, i8 undef >", + }, + { + "i8 0", + "[2 x [2 x i16]] zeroinitializer", + }, + { + "i8 undef", + "[2 x [2 x i16]] undef", + }, + { + "i8 -86", + "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " + "[2 x i16] [i16 -21846, i16 -21846]]", + }, + { + "", + "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " + "[2 x i16] [i16 -21836, i16 -21846]]", + }, + { + "i8 0", + "{ } zeroinitializer", + }, + { + "i8 undef", + "{ } undef", + }, + { + "i8 0", + "{i8, i64, i16*} zeroinitializer", + }, + { + "i8 undef", + "{i8, i64, i16*} undef", + }, + { + "i8 -86", + "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}", + }, + { + "", + "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}", + }, +}; + +INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest, + ::testing::ValuesIn(IsBytewiseValueTests)); + +TEST_P(IsBytewiseValueTest, IsBytewiseValue) { + auto M = parseModule(std::string("@test = global ") + GetParam().second); + GlobalVariable *GV = dyn_cast(M->getNamedValue("test")); + Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout()); + std::string Buff; + raw_string_ostream S(Buff); + if (Actual) + S << *Actual; + EXPECT_EQ(GetParam().first, S.str()); +}