43 changes: 29 additions & 14 deletions llvm/test/Analysis/BasicAA/cs-cs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind

declare void @a_readonly_func(i8 *) noinline nounwind readonly
declare void @a_writeonly_func(i8 *) noinline nounwind writeonly

define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
entry:
Expand All @@ -22,18 +23,18 @@ entry:
; CHECK-LABEL: Function: test1:

; CHECK: NoAlias: i8* %p, i8* %q
; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
}

define void @test2(i8* %P, i8* %Q) nounwind ssp {
Expand Down Expand Up @@ -233,9 +234,23 @@ define void @test6(i8* %P) nounwind ssp {
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
}

attributes #0 = { nounwind readonly argmemonly }
attributes #1 = { nounwind argmemonly }
define void @test7(i8* %P) nounwind ssp {
call void @a_writeonly_func(i8* %P)
call void @a_readonly_func(i8* %P)
ret void

; CHECK-LABEL: Function: test7:

; CHECK: Just Mod: Ptr: i8* %P <-> call void @a_writeonly_func(i8* %P)
; CHECK: Just Ref: Ptr: i8* %P <-> call void @a_readonly_func(i8* %P)
; CHECK: Just Mod: call void @a_writeonly_func(i8* %P) <-> call void @a_readonly_func(i8* %P)
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @a_writeonly_func(i8* %P)
}

attributes #0 = { argmemonly nounwind readonly }
attributes #1 = { argmemonly nounwind }
attributes #2 = { noinline nounwind readonly }
attributes #3 = { nounwind ssp }
attributes #4 = { nounwind }
attributes #3 = { noinline nounwind writeonly }
attributes #4 = { nounwind ssp }
attributes #5 = { nounwind }

Binary file modified llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc
Binary file not shown.
4 changes: 2 additions & 2 deletions llvm/test/Bindings/llvm-c/invalid-bitcode.test
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
; RUN: not llvm-c-test --module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
; RUN: not llvm-c-test --lazy-module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s

CHECK: Error parsing bitcode: Unknown attribute kind (52)
CHECK: Error parsing bitcode: Unknown attribute kind (63)


; RUN: not llvm-c-test --new-module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=NEW %s
; RUN: not llvm-c-test --lazy-new-module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=NEW %s

NEW: Error with new bitcode parser: Unknown attribute kind (52)
NEW: Error with new bitcode parser: Unknown attribute kind (63)

; RUN: llvm-c-test --test-diagnostic-handler < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=DIAGNOSTIC %s

Expand Down
11 changes: 9 additions & 2 deletions llvm/test/Bitcode/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ define void @f34()
; CHECK: define void @f34()
{
call void @nobuiltin() nobuiltin
; CHECK: call void @nobuiltin() #32
; CHECK: call void @nobuiltin() #33
ret void;
}

Expand Down Expand Up @@ -328,6 +328,12 @@ define i8* @f55(i32, i32) allocsize(0, 1) {
ret i8* null
}

; CHECK: define void @f56() #32
define void @f56() writeonly
{
ret void
}

; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { readnone }
Expand Down Expand Up @@ -360,4 +366,5 @@ define i8* @f55(i32, i32) allocsize(0, 1) {
; CHECK: attributes #29 = { inaccessiblemem_or_argmemonly }
; CHECK: attributes #30 = { allocsize(0) }
; CHECK: attributes #31 = { allocsize(0,1) }
; CHECK: attributes #32 = { nobuiltin }
; CHECK: attributes #32 = { writeonly }
; CHECK: attributes #33 = { nobuiltin }
7 changes: 5 additions & 2 deletions llvm/test/Bitcode/compatibility.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ exit:
; CHECK: select <2 x i1> <i1 true, i1 false>, <2 x i8> <i8 2, i8 3>, <2 x i8> <i8 3, i8 2>

call void @f.nobuiltin() builtin
; CHECK: call void @f.nobuiltin() #39
; CHECK: call void @f.nobuiltin() #40

call fastcc noalias i32* @f.noalias() noinline
; CHECK: call fastcc noalias i32* @f.noalias() #12
Expand Down Expand Up @@ -1590,6 +1590,8 @@ normal:
ret void
}

declare void @f.writeonly() writeonly
; CHECK: declare void @f.writeonly() #39

; CHECK: attributes #0 = { alignstack=4 }
; CHECK: attributes #1 = { alignstack=8 }
Expand Down Expand Up @@ -1630,7 +1632,8 @@ normal:
; CHECK: attributes #36 = { argmemonly nounwind readonly }
; CHECK: attributes #37 = { argmemonly nounwind }
; CHECK: attributes #38 = { nounwind readonly }
; CHECK: attributes #39 = { builtin }
; CHECK: attributes #39 = { writeonly }
; CHECK: attributes #40 = { builtin }

;; Metadata

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Bitcode/invalid.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s

; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (52)
; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (63)

; invalid.ll.bc has an invalid attribute number.
; The test checks that LLVM reports the error and doesn't access freed memory
Expand Down
Binary file modified llvm/test/Bitcode/invalid.ll.bc
Binary file not shown.
Binary file modified llvm/test/LTO/X86/Inputs/invalid.ll.bc
Binary file not shown.
2 changes: 1 addition & 1 deletion llvm/test/LTO/X86/invalid.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: not llvm-lto %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s


; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (52)
; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (63)
13 changes: 13 additions & 0 deletions llvm/test/Verifier/writeonly.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s

declare void @a() readnone writeonly
; CHECK: Attributes {{.*}} are incompatible

declare void @b() readonly writeonly
; CHECK: Attributes {{.*}} are incompatible

declare void @c(i32* readnone writeonly %p)
; CHECK: Attributes {{.*}} are incompatible

declare void @d(i32* readonly writeonly %p)
; CHECK: Attributes {{.*}} are incompatible
1 change: 1 addition & 0 deletions llvm/utils/TableGen/CodeGenIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ namespace llvm {
enum ArgAttribute {
NoCapture,
ReadOnly,
WriteOnly,
ReadNone
};
std::vector<std::pair<unsigned, ArgAttribute> > ArgumentAttributes;
Expand Down
3 changes: 3 additions & 0 deletions llvm/utils/TableGen/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,9 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
} else if (Property->isSubClassOf("ReadOnly")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
} else if (Property->isSubClassOf("WriteOnly")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.push_back(std::make_pair(ArgNo, WriteOnly));
} else if (Property->isSubClassOf("ReadNone")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
Expand Down
17 changes: 16 additions & 1 deletion llvm/utils/TableGen/IntrinsicEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,12 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << "Attribute::ReadOnly";
addComma = true;
break;
case CodeGenIntrinsic::WriteOnly:
if (addComma)
OS << ",";
OS << "Attribute::WriteOnly";
addComma = true;
break;
case CodeGenIntrinsic::ReadNone:
if (addComma)
OS << ",";
Expand Down Expand Up @@ -617,12 +623,21 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << "Attribute::ReadOnly";
break;
case CodeGenIntrinsic::WriteArgMem:
case CodeGenIntrinsic::ReadWriteArgMem:
if (addComma)
OS << ",";
OS << "Attribute::WriteOnly,";
OS << "Attribute::ArgMemOnly";
break;
case CodeGenIntrinsic::WriteMem:
if (addComma)
OS << ",";
OS << "Attribute::WriteOnly";
break;
case CodeGenIntrinsic::ReadWriteArgMem:
if (addComma)
OS << ",";
OS << "Attribute::ArgMemOnly";
break;
case CodeGenIntrinsic::ReadWriteMem:
break;
}
Expand Down