[TBAA] Don't generate invalid TBAA when merging nodes
authorSanjoy Das <sanjoy@playingwithpointers.com>
Sun, 11 Dec 2016 20:07:25 +0000 (20:07 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Sun, 11 Dec 2016 20:07:25 +0000 (20:07 +0000)
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

llvm-svn: 289403

llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp
llvm/unittests/Analysis/TBAATest.cpp

index 5c92adb..e920c4c 100644 (file)
@@ -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,
index 98899dd..3a1d2f4 100644 (file)
 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);
@@ -43,6 +42,14 @@ TEST_F(OldTBAATest, checkVerifierBehavior) {
                            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);
@@ -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