Fix PR1816. If a bitcast of a function only exists because of a
[oota-llvm.git] / lib / VMCore / Function.cpp
index 6c29371862652585285c8daaea452cbc3a492563..2b83e6b9172c64bafb3f905f7241571bf9b67de7 100644 (file)
@@ -86,7 +86,6 @@ ParamAttrsList::getParamAttrs(uint16_t Index) const {
   return ParamAttr::None;
 }
 
-
 std::string 
 ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
   std::string Result;
@@ -115,6 +114,50 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
   return Result;
 }
 
+/// onlyInformative - Returns whether only informative attributes are set.
+static inline bool onlyInformative(uint16_t attrs) {
+  return !(attrs & ~ParamAttr::Informative);
+}
+
+bool
+ParamAttrsList::areCompatible(const ParamAttrsList *A, const ParamAttrsList *B){
+  if (A == B)
+    return true;
+  unsigned ASize = A ? A->size() : 0;
+  unsigned BSize = B ? B->size() : 0;
+  unsigned AIndex = 0;
+  unsigned BIndex = 0;
+
+  while (AIndex < ASize && BIndex < BSize) {
+    uint16_t AIdx = A->getParamIndex(AIndex);
+    uint16_t BIdx = B->getParamIndex(BIndex);
+    uint16_t AAttrs = A->getParamAttrsAtIndex(AIndex);
+    uint16_t BAttrs = B->getParamAttrsAtIndex(AIndex);
+
+    if (AIdx < BIdx) {
+      if (!onlyInformative(AAttrs))
+        return false;
+      ++AIndex;
+    } else if (BIdx < AIdx) {
+      if (!onlyInformative(BAttrs))
+        return false;
+      ++BIndex;
+    } else {
+      if (!onlyInformative(AAttrs ^ BAttrs))
+        return false;
+      ++AIndex;
+      ++BIndex;
+    }
+  }
+  for (; AIndex < ASize; ++AIndex)
+    if (!onlyInformative(A->getParamAttrsAtIndex(AIndex)))
+      return false;
+  for (; BIndex < BSize; ++BIndex)
+    if (!onlyInformative(B->getParamAttrsAtIndex(AIndex)))
+      return false;
+  return true;
+}
+
 void 
 ParamAttrsList::Profile(FoldingSetNodeID &ID) const {
   for (unsigned i = 0; i < attrs.size(); ++i) {