[llvm] r265361 - Fix non-determinism in order of LLVM attributes

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 4 16:06:06 PDT 2016


Author: rnk
Date: Mon Apr  4 18:06:05 2016
New Revision: 265361

URL: http://llvm.org/viewvc/llvm-project?rev=265361&view=rev
Log:
Fix non-determinism in order of LLVM attributes

We were using array_pod_sort on an array of type 'Attribute', which
wraps a pointer to AttributeImpl. For the most part this didn't matter
because the printing code prints enum attributes in a defined order, but
integer attributes such as 'align' and 'dereferenceable' were not
ordered.

Furthermore, AttributeImpl::operator< was broken for integer attributes.
An integer attribute is a kind and an integer value, and both pieces
need to be compared.

By fixing the comparison operator, we can go back to std::sort, and
things look good now.  This should fix clang arm-swiftcall.c test
failures on Windows.

Modified:
    llvm/trunk/lib/IR/Attributes.cpp
    llvm/trunk/unittests/IR/AttributesTest.cpp

Modified: llvm/trunk/lib/IR/Attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=265361&r1=265360&r2=265361&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Attributes.cpp (original)
+++ llvm/trunk/lib/IR/Attributes.cpp Mon Apr  4 18:06:05 2016
@@ -389,7 +389,11 @@ bool AttributeImpl::operator<(const Attr
 
   if (isIntAttribute()) {
     if (AI.isEnumAttribute()) return false;
-    if (AI.isIntAttribute()) return getValueAsInt() < AI.getValueAsInt();
+    if (AI.isIntAttribute()) {
+      if (getKindAsEnum() == AI.getKindAsEnum())
+        return getValueAsInt() < AI.getValueAsInt();
+      return getKindAsEnum() < AI.getKindAsEnum();
+    }
     if (AI.isStringAttribute()) return true;
   }
 
@@ -482,7 +486,7 @@ AttributeSetNode *AttributeSetNode::get(
   FoldingSetNodeID ID;
 
   SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
-  array_pod_sort(SortedAttrs.begin(), SortedAttrs.end());
+  std::sort(SortedAttrs.begin(), SortedAttrs.end());
 
   for (Attribute Attr : SortedAttrs)
     Attr.Profile(ID);

Modified: llvm/trunk/unittests/IR/AttributesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/AttributesTest.cpp?rev=265361&r1=265360&r2=265361&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/AttributesTest.cpp (original)
+++ llvm/trunk/unittests/IR/AttributesTest.cpp Mon Apr  4 18:06:05 2016
@@ -34,6 +34,15 @@ TEST(Attributes, Uniquing) {
 TEST(Attributes, Ordering) {
   LLVMContext C;
 
+  Attribute Align4 = Attribute::get(C, Attribute::Alignment, 4);
+  Attribute Align5 = Attribute::get(C, Attribute::Alignment, 5);
+  Attribute Deref4 = Attribute::get(C, Attribute::Dereferenceable, 4);
+  Attribute Deref5 = Attribute::get(C, Attribute::Dereferenceable, 5);
+  EXPECT_TRUE(Align4 < Align5);
+  EXPECT_TRUE(Align4 < Deref4);
+  EXPECT_TRUE(Align4 < Deref5);
+  EXPECT_TRUE(Align5 < Deref4);
+
   AttributeSet ASs[] = {
     AttributeSet::get(C, 2, Attribute::ZExt),
     AttributeSet::get(C, 1, Attribute::SExt)




More information about the llvm-commits mailing list