Skip to content

Commit

Permalink
[TBAA] Don't generate invalid TBAA when merging nodes
Browse files Browse the repository at this point in the history
Summary:
Fix a corner case in `MDNode::getMostGenericTBAA` where we can sometimes
generate invalid TBAA metadata.

Reviewers: chandlerc, hfinkel, mehdi_amini, manmanren

Subscribers: mcrosier, llvm-commits

Differential Revision: https://reviews.llvm.org/D26635

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289403 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
sanjoy committed Dec 11, 2016
1 parent a942d77 commit 965b15e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
6 changes: 5 additions & 1 deletion lib/Analysis/TypeBasedAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,12 @@ MDNode *MDNode::getMostGenericTBAA(MDNode *A, MDNode *B) {
--IB;
}

if (!Ret)
// We either did not find a match, or the only common base "type" is
// the root node. In either case, we don't have any useful TBAA
// metadata to attach.
if (!Ret || Ret->getNumOperands() < 2)
return nullptr;

// We need to convert from a type node to a tag node.
Type *Int64 = IntegerType::get(A->getContext(), 64);
Metadata *Ops[3] = {Ret, Ret,
Expand Down
40 changes: 34 additions & 6 deletions unittests/Analysis/TBAATest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,34 @@
namespace llvm {
namespace {

class OldTBAATest : public testing::Test {
class TBAATest : public testing::Test {
protected:
OldTBAATest() : M("MixedTBAATest", C), MD(C) {}
TBAATest() : M("TBAATest", C), MD(C) {}

LLVMContext C;
Module M;
MDBuilder MD;
};

TEST_F(OldTBAATest, checkVerifierBehavior) {
// C++ unit test case to avoid going through the auto upgrade logic.

static StoreInst *getFunctionWithSingleStore(Module *M, StringRef Name) {
auto &C = M->getContext();
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {});
auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
auto *F = cast<Function>(M->getOrInsertFunction(Name, FTy));
auto *BB = BasicBlock::Create(C, "entry", F);
auto *IntType = Type::getInt32Ty(C);
auto *PtrType = Type::getInt32PtrTy(C);
auto *SI = new StoreInst(ConstantInt::get(IntType, 42),
ConstantPointerNull::get(PtrType), BB);
ReturnInst::Create(C, nullptr, BB);

return SI;
}

TEST_F(TBAATest, checkVerifierBehaviorForOldTBAA) {
auto *SI = getFunctionWithSingleStore(&M, "f1");
auto *F = SI->getFunction();

// C++ unit test case to avoid going through the auto upgrade logic.
auto *RootMD = MD.createTBAARoot("Simple C/C++ TBAA");
auto *MD1 = MD.createTBAANode("omnipotent char", RootMD);
auto *MD2 = MD.createTBAANode("int", MD1);
Expand All @@ -59,5 +66,26 @@ TEST_F(OldTBAATest, checkVerifierBehavior) {
.startswith(ExpectedFailureMsg));
}

TEST_F(TBAATest, checkTBAAMerging) {
auto *SI = getFunctionWithSingleStore(&M, "f2");
auto *F = SI->getFunction();

auto *RootMD = MD.createTBAARoot("tbaa-root");
auto *MD1 = MD.createTBAANode("scalar-a", RootMD);
auto *StructTag1 = MD.createTBAAStructTagNode(MD1, MD1, 0);
auto *MD2 = MD.createTBAANode("scalar-b", RootMD);
auto *StructTag2 = MD.createTBAAStructTagNode(MD2, MD2, 0);

auto *GenericMD = MDNode::getMostGenericTBAA(StructTag1, StructTag2);

EXPECT_EQ(GenericMD, nullptr);

// Despite GenericMD being nullptr, we expect the setMetadata call to be well
// defined and produce a well-formed function.
SI->setMetadata(LLVMContext::MD_tbaa, GenericMD);

EXPECT_TRUE(!verifyFunction(*F));
}

} // end anonymous namspace
} // end llvm namespace

0 comments on commit 965b15e

Please sign in to comment.