Alignment attributes need to be dropped for non-pointer values.
This also introduces a check into the verifier to ensure you don't use
`align` on anything but a pointer. Test needed to be adjusted
accordingly.
Reviewed By: fhahn
Differential Revision: https://reviews.llvm.org/D87304
.addAttribute(Attribute::NoAlias)
.addAttribute(Attribute::NoCapture)
.addAttribute(Attribute::NonNull)
+ .addAlignmentAttr(1) // the int here is ignored
.addDereferenceableAttr(1) // the int here is ignored
.addDereferenceableOrNullAttr(1) // the int here is ignored
.addAttribute(Attribute::ReadNone)
ret void;
}
-define void @f17(i8 align 4 %0)
-; CHECK: define void @f17(i8 align 4 %0)
+define void @f17(i8* align 4 %0)
+; CHECK: define void @f17(i8* align 4 %0)
{
ret void;
}
ret void;
}
-define void @f17(i8 align 4 %0)
-; CHECK: define void @f17(i8 align 4 %0)
+define void @f17(i8* align 4 %0)
+; CHECK: define void @f17(i8* align 4 %0)
{
ret void;
}
ret %Ty* %this
}
+; Drop all these attributes
+; CHECK-LABEL: define internal void @test6
+define internal align 8 dereferenceable_or_null(2) noalias i8* @test6() {
+ ret i8* null
+}
+
define %Ty* @caller(%Ty* %this) {
%1 = call %Ty* @test1(%Ty* %this)
%2 = call %Ty* @test2(%Ty* %this)
; ...instead, drop 'returned' form the call site
; CHECK: call void @test5(%Ty* %this)
%5 = call %Ty* @test5(%Ty* returned %this)
+ %6 = call i8* @test6()
ret %Ty* %this
}
; When loopsimplify generates dedicated exit block for blocks that are landing
; pads (i.e. innerLoopExit in this test), we should not get confused with the
; unreachable pred (unreachableB) to innerLoopExit.
-define align 8 void @baz(i32 %trip) personality i32* ()* @wobble {
+define void @baz(i32 %trip) personality i32* ()* @wobble {
entry:
br label %outerHeader
--- /dev/null
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK-NEXT: @align_non_pointer1
+define void @align_non_pointer1(i32 align 4 %a) {
+ ret void
+}
+
+; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly signext zeroext byref(void) byval(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1)
+; CHECK-NEXT: @align_non_pointer2
+define align 4 void @align_non_pointer2(i32 %a) {
+ ret void
+}
ret void
}
-; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly sret byref(i32) byval(i32) preallocated(i32) dereferenceable(1) dereferenceable_or_null(1)
+; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly sret byref(i32) byval(i32) preallocated(i32) align 1 dereferenceable(1) dereferenceable_or_null(1)
; CHECK-NEXT: void (i32)* @byref_non_pointer
define void @byref_non_pointer(i32 byref(i32)) {
ret void