summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-07 20:32:11 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-07 20:32:11 +0000
commit9c51b50a714d06561ac69dc30c394cb3fcef5bb8 (patch)
tree519ba4e239f79545f8b8e1e3a9d0f3e48430675f /llvm/lib
parentac8ee289eb5438bdc222252f3e45f156c6b6730e (diff)
downloadbcm5719-llvm-9c51b50a714d06561ac69dc30c394cb3fcef5bb8.tar.gz
bcm5719-llvm-9c51b50a714d06561ac69dc30c394cb3fcef5bb8.zip
IR: Revert r223618 behaviour of MDNode::concatenate()
r223618 including special handling of `MDNode::intersect()`: if the first operand is a self-reference with the same operands you're trying to return, return it instead. Reuse that handling in `MDNode::concatenate()` in the hopes that it fixes a polly test that seems to rely on the old behaviour [1]. [1]: http://lab.llvm.org:8011/builders/polly-amd64-linux/builds/25167 llvm-svn: 223619
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Metadata.cpp35
1 files changed, 23 insertions, 12 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 70415b01016..a2c7838bb83 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -376,6 +376,25 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
Store.insert(N);
}
+/// \brief Get a node, or a self-reference that looks like it.
+///
+/// Special handling for finding self-references, for use by \a
+/// MDNode::concatenate() and \a MDNode::intersect() to maintain behaviour from
+/// when self-referencing nodes were still uniqued. If the first operand has
+/// the same operands as \c Ops, return the first operand instead.
+static MDNode *getOrSelfReference(LLVMContext &Context, ArrayRef<Value *> Ops) {
+ if (!Ops.empty())
+ if (MDNode *N = dyn_cast_or_null<MDNode>(Ops[0]))
+ if (N->getNumOperands() == Ops.size() && N == N->getOperand(0)) {
+ for (unsigned I = 1, E = Ops.size(); I != E; ++I)
+ if (Ops[I] != N->getOperand(I))
+ return MDNode::get(Context, Ops);
+ return N;
+ }
+
+ return MDNode::get(Context, Ops);
+}
+
MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
if (!A)
return B;
@@ -391,7 +410,9 @@ MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++i)
Vals[j++] = B->getOperand(i);
- return MDNode::get(A->getContext(), Vals);
+ // 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(), Vals);
}
MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
@@ -408,19 +429,9 @@ MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
}
}
- // Handle alias scope self-references specially.
- //
// FIXME: This preserves long-standing behaviour, but is it really the right
// behaviour? Or was that an unintended side-effect of node uniquing?
- if (!Vals.empty())
- if (MDNode *N = dyn_cast_or_null<MDNode>(Vals[0]))
- if (N->getNumOperands() == Vals.size() && N == N->getOperand(0)) {
- for (unsigned I = 1, E = Vals.size(); I != E; ++I)
- if (Vals[I] != N->getOperand(I))
- return MDNode::get(A->getContext(), Vals);
- return N;
- }
- return MDNode::get(A->getContext(), Vals);
+ return getOrSelfReference(A->getContext(), Vals);
}
MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
OpenPOWER on IntegriCloud