Commit a183e9e8 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r228525:

------------------------------------------------------------------------
r228525 | bsteinbr | 2015-02-08 09:07:14 -0800 (Sun, 08 Feb 2015) | 14 lines

Correctly combine alias.scope metadata by a union instead of intersecting

Summary:
The alias.scope metadata represents sets of things an instruction might
alias with. When generically combining the metadata from two
instructions the result must be the union of the original sets, because
the new instruction might alias with anything any of the original
instructions aliased with.

Reviewers: hfinkel

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D7490
------------------------------------------------------------------------

llvm-svn: 228561
parent 5bfe9136
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -693,6 +693,7 @@ public:
  static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);
  static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
  static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
  static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B);
};

/// \brief Uniquable metadata node.
+2 −2
Original line number Diff line number Diff line
@@ -623,8 +623,8 @@ void Instruction::getAAMetadata(AAMDNodes &N, bool Merge) const {
    N.TBAA = getMetadata(LLVMContext::MD_tbaa);

  if (Merge)
    N.Scope =
        MDNode::intersect(N.Scope, getMetadata(LLVMContext::MD_alias_scope));
    N.Scope = MDNode::getMostGenericAliasScope(
        N.Scope, getMetadata(LLVMContext::MD_alias_scope));
  else
    N.Scope = getMetadata(LLVMContext::MD_alias_scope);

+22 −0
Original line number Diff line number Diff line
@@ -826,6 +826,28 @@ MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
  return getOrSelfReference(A->getContext(), MDs);
}

MDNode *MDNode::getMostGenericAliasScope(MDNode *A, MDNode *B) {
  if (!A || !B)
    return nullptr;

  SmallVector<Metadata *, 4> MDs(B->op_begin(), B->op_end());
  for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) {
    Metadata *MD = A->getOperand(i);
    bool insert = true;
    for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j)
      if (MD == B->getOperand(j)) {
        insert = false;
        break;
      }
    if (insert)
        MDs.push_back(MD);
  }

  // FIXME: This preserves long-standing behaviour, but is it really the right
  // behaviour?  Or was that an unintended side-effect of node uniquing?
  return getOrSelfReference(A->getContext(), MDs);
}

MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
  if (!A || !B)
    return nullptr;
+2 −0
Original line number Diff line number Diff line
@@ -1328,6 +1328,8 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsign
        K->setMetadata(Kind, MDNode::getMostGenericTBAA(JMD, KMD));
        break;
      case LLVMContext::MD_alias_scope:
        K->setMetadata(Kind, MDNode::getMostGenericAliasScope(JMD, KMD));
        break;
      case LLVMContext::MD_noalias:
        K->setMetadata(Kind, MDNode::intersect(JMD, KMD));
        break;
+2 −0
Original line number Diff line number Diff line
@@ -208,6 +208,8 @@ static Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL) {
        MD = MDNode::getMostGenericTBAA(MD, IMD);
        break;
      case LLVMContext::MD_alias_scope:
        MD = MDNode::getMostGenericAliasScope(MD, IMD);
        break;
      case LLVMContext::MD_noalias:
        MD = MDNode::intersect(MD, IMD);
        break;
Loading