[llvm] 5e4b33f - [Verifier] Improve incompatible attribute type check

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 14 12:02:22 PDT 2021


Author: Nikita Popov
Date: 2021-07-14T21:02:10+02:00
New Revision: 5e4b33fe9218703f0b29e2446159bcf4202d15fa

URL: https://github.com/llvm/llvm-project/commit/5e4b33fe9218703f0b29e2446159bcf4202d15fa
DIFF: https://github.com/llvm/llvm-project/commit/5e4b33fe9218703f0b29e2446159bcf4202d15fa.diff

LOG: [Verifier] Improve incompatible attribute type check

A couple of attributes had explicit checks for incompatibility
with pointer types. However, this is already handled generically
by the typeIncompatible() check. We can drop these after adding
SwiftError to typeIncompatible().

However, the previous implementation of the check prints out all
attributes that are incompatible with a given type, even though
those attributes aren't actually used. This has the annoying
result that the error message changes every time a new attribute
is added to the list. Improve this by explicitly finding which
attribute isn't compatible and printing just that.

Added: 
    

Modified: 
    llvm/lib/IR/Attributes.cpp
    llvm/lib/IR/Verifier.cpp
    llvm/test/Verifier/align.ll
    llvm/test/Verifier/byref.ll
    llvm/test/Verifier/byval-1.ll
    llvm/test/Verifier/inalloca1.ll
    llvm/test/Verifier/noundef.ll
    llvm/test/Verifier/preallocated-invalid.ll
    llvm/test/Verifier/sret.ll
    llvm/test/Verifier/swifterror.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index beb8a24989e71..31cef097fb4ba 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -1923,11 +1923,12 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
         .addAttribute(Attribute::NoAlias)
         .addAttribute(Attribute::NoCapture)
         .addAttribute(Attribute::NonNull)
+        .addAttribute(Attribute::ReadNone)
+        .addAttribute(Attribute::ReadOnly)
+        .addAttribute(Attribute::SwiftError)
         .addAlignmentAttr(1)             // the int here is ignored
         .addDereferenceableAttr(1)       // the int here is ignored
         .addDereferenceableOrNullAttr(1) // the int here is ignored
-        .addAttribute(Attribute::ReadNone)
-        .addAttribute(Attribute::ReadOnly)
         .addPreallocatedAttr(Ty)
         .addInAllocaAttr(Ty)
         .addByValAttr(Ty)

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index bd7bcf3469e32..442857ecb6800 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1758,10 +1758,14 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
          V);
 
   AttrBuilder IncompatibleAttrs = AttributeFuncs::typeIncompatible(Ty);
-  Assert(!AttrBuilder(Attrs).overlaps(IncompatibleAttrs),
-         "Wrong types for attribute: " +
-             AttributeSet::get(Context, IncompatibleAttrs).getAsString(),
-         V);
+  for (Attribute Attr : Attrs) {
+    if (!Attr.isStringAttribute() &&
+        IncompatibleAttrs.contains(Attr.getKindAsEnum())) {
+      CheckFailed("Attribute '" + Attr.getAsString() +
+                  "' applied to incompatible type!", V);
+      return;
+    }
+  }
 
   if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
     if (Attrs.hasAttribute(Attribute::ByVal)) {
@@ -1810,17 +1814,6 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
                "Attribute 'inalloca' type does not match parameter!", V);
       }
     }
-  } else {
-    Assert(!Attrs.hasAttribute(Attribute::ByVal),
-           "Attribute 'byval' only applies to parameters with pointer type!",
-           V);
-    Assert(!Attrs.hasAttribute(Attribute::ByRef),
-           "Attribute 'byref' only applies to parameters with pointer type!",
-           V);
-    Assert(!Attrs.hasAttribute(Attribute::SwiftError),
-           "Attribute 'swifterror' only applies to parameters "
-           "with pointer type!",
-           V);
   }
 }
 

diff  --git a/llvm/test/Verifier/align.ll b/llvm/test/Verifier/align.ll
index 1f5c8da7654a4..76379eb08aa9a 100644
--- a/llvm/test/Verifier/align.ll
+++ b/llvm/test/Verifier/align.ll
@@ -1,12 +1,12 @@
 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
 
-; CHECK: Wrong types for attribute: nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) inalloca(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK: Attribute 'align 4' applied to incompatible type!
 ; CHECK-NEXT: @align_non_pointer1
 define void @align_non_pointer1(i32 align 4 %a) {
   ret void
 }
 
-; CHECK: Wrong types for attribute: nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) inalloca(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK: Attribute 'align 4' applied to incompatible type!
 ; CHECK-NEXT: @align_non_pointer2
 define align 4 void @align_non_pointer2(i32 %a) {
   ret void

diff  --git a/llvm/test/Verifier/byref.ll b/llvm/test/Verifier/byref.ll
index 6cd66eb60e5a6..6a8df2df2724c 100644
--- a/llvm/test/Verifier/byref.ll
+++ b/llvm/test/Verifier/byref.ll
@@ -56,7 +56,7 @@ define void @byref_nest(i32* byref(i32) nest) {
   ret void
 }
 
-; CHECK: Wrong types for attribute: nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) inalloca(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK: Attribute 'byref(i32)' applied to incompatible type!
 ; CHECK-NEXT: void (i32)* @byref_non_pointer
 define void @byref_non_pointer(i32 byref(i32)) {
   ret void

diff  --git a/llvm/test/Verifier/byval-1.ll b/llvm/test/Verifier/byval-1.ll
index 6344371bba5e0..6d0c46a79e0a2 100644
--- a/llvm/test/Verifier/byval-1.ll
+++ b/llvm/test/Verifier/byval-1.ll
@@ -1,5 +1,5 @@
 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
 
-; CHECK: Wrong types for attribute: nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) inalloca(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK: Attribute 'byval(i32)' applied to incompatible type!
 ; CHECK-NEXT: void (i32)* @h
 declare void @h(i32 byval(i32) %num)

diff  --git a/llvm/test/Verifier/inalloca1.ll b/llvm/test/Verifier/inalloca1.ll
index db911b2d5f60a..af31f89120629 100644
--- a/llvm/test/Verifier/inalloca1.ll
+++ b/llvm/test/Verifier/inalloca1.ll
@@ -27,8 +27,8 @@ define void @inalloca_mismatched_pointee_type0(i32* inalloca(i8)) {
   ret void
 }
 
-; CHECK: Wrong types for attribute:
+; CHECK: Attribute 'inalloca(i8)' applied to incompatible type!
 ; CHECK-NEXT: void (i8)* @inalloca_not_pointer
-define void @inalloca_not_pointer(i8 byref(i8)) {
+define void @inalloca_not_pointer(i8 inalloca(i8)) {
   ret void
 }

diff  --git a/llvm/test/Verifier/noundef.ll b/llvm/test/Verifier/noundef.ll
index 2ece2dd1a9ac1..9ee5a1859799e 100644
--- a/llvm/test/Verifier/noundef.ll
+++ b/llvm/test/Verifier/noundef.ll
@@ -1,6 +1,6 @@
 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
 
-; CHECK: Wrong types for attribute: nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) inalloca(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK: Attribute 'noundef' applied to incompatible type!
 ; CHECK-NEXT: @noundef_void
 define noundef void @noundef_void() {
   ret void

diff  --git a/llvm/test/Verifier/preallocated-invalid.ll b/llvm/test/Verifier/preallocated-invalid.ll
index 392937f677e9a..b0aa83eb1c034 100644
--- a/llvm/test/Verifier/preallocated-invalid.ll
+++ b/llvm/test/Verifier/preallocated-invalid.ll
@@ -145,6 +145,6 @@ define void @teardown_token_not_from_setup() {
     ret void
 }
 
-; CHECK: Wrong types for attribute:
+; CHECK: Attribute 'preallocated(i32)' applied to incompatible type!
 ; CHECK-NEXT: void (i32)* @not_pointer
 declare void @not_pointer(i32 preallocated(i32))

diff  --git a/llvm/test/Verifier/sret.ll b/llvm/test/Verifier/sret.ll
index 54e0d5b54d22b..6b4097a510313 100644
--- a/llvm/test/Verifier/sret.ll
+++ b/llvm/test/Verifier/sret.ll
@@ -6,6 +6,6 @@ declare void @a(i32* sret(i32) %a, i32* sret(i32) %b)
 declare void @b(i32* %a, i32* %b, i32* sret(i32) %c)
 ; CHECK: Attribute 'sret' is not on first or second parameter!
 
-; CHECK: Wrong types for attribute:
+; CHECK: Attribute 'sret(i32)' applied to incompatible type!
 ; CHECK-NEXT: void (i32)* @not_ptr
 declare void @not_ptr(i32 sret(i32) %x)

diff  --git a/llvm/test/Verifier/swifterror.ll b/llvm/test/Verifier/swifterror.ll
index d8eacf5480ed9..78c26d7512241 100644
--- a/llvm/test/Verifier/swifterror.ll
+++ b/llvm/test/Verifier/swifterror.ll
@@ -24,7 +24,7 @@ entry:
 ; CHECK: Cannot have multiple 'swifterror' parameters!
 declare void @a(i32** swifterror %a, i32** swifterror %b)
 
-; CHECK: Attribute 'swifterror' only applies to parameters with pointer type!
+; CHECK: Attribute 'swifterror' applied to incompatible type!
 declare void @b(i32 swifterror %a)
 
 ; CHECK: Attribute 'swifterror' only applies to parameters with pointer to pointer type!


        


More information about the llvm-commits mailing list