Index: llvm/trunk/lib/Analysis/TypeBasedAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -417,15 +417,14 @@ return A; // For struct-path aware TBAA, we use the access type of the tag. - bool StructPath = isStructPathTBAA(A) && isStructPathTBAA(B); - if (StructPath) { - A = cast_or_null(MutableTBAAStructTagNode(A).getAccessType()); - if (!A) - return nullptr; - B = cast_or_null(MutableTBAAStructTagNode(B).getAccessType()); - if (!B) - return nullptr; - } + assert(isStructPathTBAA(A) && isStructPathTBAA(B) && + "Auto upgrade should have taken care of this!"); + A = cast_or_null(MutableTBAAStructTagNode(A).getAccessType()); + if (!A) + return nullptr; + B = cast_or_null(MutableTBAAStructTagNode(B).getAccessType()); + if (!B) + return nullptr; SmallSetVector PathA; MutableTBAANode TA(A); @@ -457,8 +456,6 @@ --IA; --IB; } - if (!StructPath) - return Ret; if (!Ret) return nullptr; @@ -492,52 +489,8 @@ /// Aliases - Test whether the type represented by A may alias the /// type represented by B. bool TypeBasedAAResult::Aliases(const MDNode *A, const MDNode *B) const { - // Make sure that both MDNodes are struct-path aware. - if (isStructPathTBAA(A) && isStructPathTBAA(B)) - return PathAliases(A, B); - - // Keep track of the root node for A and B. - TBAANode RootA, RootB; - - // Climb the tree from A to see if we reach B. - for (TBAANode T(A);;) { - if (T.getNode() == B) - // B is an ancestor of A. - return true; - - RootA = T; - T = T.getParent(); - if (!T.getNode()) - break; - } - - // Climb the tree from B to see if we reach A. - for (TBAANode T(B);;) { - if (T.getNode() == A) - // A is an ancestor of B. - return true; - - RootB = T; - T = T.getParent(); - if (!T.getNode()) - break; - } - - // Neither node is an ancestor of the other. - - // If they have different roots, they're part of different potentially - // unrelated type systems, so we must be conservative. - if (RootA.getNode() != RootB.getNode()) - return true; - - // If they have the same root, then we've proved there's no alias. - return false; -} - -/// Test whether the struct-path tag represented by A may alias the -/// struct-path tag represented by B. -bool TypeBasedAAResult::PathAliases(const MDNode *A, const MDNode *B) const { - // Verify that both input nodes are struct-path aware. + // Verify that both input nodes are struct-path aware. Auto-upgrade should + // have taken care of this. assert(isStructPathTBAA(A) && "MDNode A is not struct-path aware."); assert(isStructPathTBAA(B) && "MDNode B is not struct-path aware."); Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -391,6 +391,7 @@ void visitBasicBlock(BasicBlock &BB); void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty); void visitDereferenceableMetadata(Instruction& I, MDNode* MD); + void visitTBAAMetadata(Instruction &I, MDNode *MD); template bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); @@ -3658,6 +3659,15 @@ "dereferenceable_or_null metadata value must be an i64!", &I); } +void Verifier::visitTBAAMetadata(Instruction &I, MDNode *MD) { + bool IsStructPathTBAA = + isa(MD->getOperand(0)) && MD->getNumOperands() >= 3; + + Assert(IsStructPathTBAA, + "Old-style TBAA is no longer allowed, use struct-path TBAA instead", + &I); +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -3793,6 +3803,9 @@ if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) visitDereferenceableMetadata(I, MD); + if (MDNode *MD = I.getMetadata(LLVMContext::MD_tbaa)) + visitTBAAMetadata(I, MD); + if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) { Assert(I.getType()->isPointerTy(), "align applies only to pointer types", &I); Index: llvm/trunk/unittests/Analysis/CMakeLists.txt =================================================================== --- llvm/trunk/unittests/Analysis/CMakeLists.txt +++ llvm/trunk/unittests/Analysis/CMakeLists.txt @@ -14,7 +14,7 @@ LazyCallGraphTest.cpp LoopPassManagerTest.cpp ScalarEvolutionTest.cpp - MixedTBAATest.cpp + TBAATest.cpp ValueTrackingTest.cpp UnrollAnalyzer.cpp ) Index: llvm/trunk/unittests/Analysis/MixedTBAATest.cpp =================================================================== --- llvm/trunk/unittests/Analysis/MixedTBAATest.cpp +++ llvm/trunk/unittests/Analysis/MixedTBAATest.cpp @@ -1,79 +0,0 @@ -//===--- MixedTBAATest.cpp - Mixed TBAA unit tests ------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/TypeBasedAliasAnalysis.h" -#include "llvm/Analysis/AliasAnalysisEvaluator.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/MDBuilder.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/Support/CommandLine.h" -#include "gtest/gtest.h" - -namespace llvm { -namespace { - -class MixedTBAATest : public testing::Test { -protected: - MixedTBAATest() : M("MixedTBAATest", C), MD(C) {} - - LLVMContext C; - Module M; - MDBuilder MD; - legacy::PassManager PM; -}; - -TEST_F(MixedTBAATest, MixedTBAA) { - // Setup function. - FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), - std::vector(), false); - auto *F = cast(M.getOrInsertFunction("f", FTy)); - auto *BB = BasicBlock::Create(C, "entry", F); - auto IntType = Type::getInt32Ty(C); - auto PtrType = Type::getInt32PtrTy(C); - auto *Value = ConstantInt::get(IntType, 42); - auto *Addr = ConstantPointerNull::get(PtrType); - - auto *Store1 = new StoreInst(Value, Addr, BB); - auto *Store2 = new StoreInst(Value, Addr, BB); - ReturnInst::Create(C, nullptr, BB); - - // New TBAA metadata - { - auto RootMD = MD.createTBAARoot("Simple C/C++ TBAA"); - auto MD1 = MD.createTBAAScalarTypeNode("omnipotent char", RootMD); - auto MD2 = MD.createTBAAScalarTypeNode("int", MD1); - auto MD3 = MD.createTBAAStructTagNode(MD2, MD2, 0); - Store2->setMetadata(LLVMContext::MD_tbaa, MD3); - } - - // Old TBAA metadata - { - auto RootMD = MD.createTBAARoot("Simple C/C++ TBAA"); - auto MD1 = MD.createTBAANode("omnipotent char", RootMD); - auto MD2 = MD.createTBAANode("int", MD1); - Store1->setMetadata(LLVMContext::MD_tbaa, MD2); - } - - // Run the TBAA eval pass on a mixture of path-aware and non-path-aware TBAA. - // The order of the metadata (path-aware vs non-path-aware) is important, - // because the AA eval pass only runs one test per store-pair. - const char* args[] = { "MixedTBAATest", "-evaluate-aa-metadata" }; - cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args); - PM.add(createTypeBasedAAWrapperPass()); - PM.add(createAAEvalPass()); - PM.run(M); -} - -} // end anonymous namspace -} // end llvm namespace - Index: llvm/trunk/unittests/Analysis/TBAATest.cpp =================================================================== --- llvm/trunk/unittests/Analysis/TBAATest.cpp +++ llvm/trunk/unittests/Analysis/TBAATest.cpp @@ -0,0 +1,63 @@ +//===--- TBAATest.cpp - Mixed TBAA unit tests -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/AliasAnalysisEvaluator.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/CommandLine.h" +#include "gtest/gtest.h" + +namespace llvm { +namespace { + +class OldTBAATest : public testing::Test { +protected: + OldTBAATest() : M("MixedTBAATest", 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. + + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {}); + auto *F = cast(M.getOrInsertFunction("f", 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); + + auto *RootMD = MD.createTBAARoot("Simple C/C++ TBAA"); + auto *MD1 = MD.createTBAANode("omnipotent char", RootMD); + auto *MD2 = MD.createTBAANode("int", MD1); + SI->setMetadata(LLVMContext::MD_tbaa, MD2); + + SmallVector ErrorMsg; + raw_svector_ostream Outs(ErrorMsg); + + StringRef ExpectedFailureMsg( + "Old-style TBAA is no longer allowed, use struct-path TBAA instead"); + + EXPECT_TRUE(verifyFunction(*F, &Outs)); + EXPECT_TRUE(StringRef(ErrorMsg.begin(), ErrorMsg.size()) + .startswith(ExpectedFailureMsg)); +} + +} // end anonymous namspace +} // end llvm namespace