mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 22:30:33 +00:00
Emit argmemonly attribute for intrinsics.
Differential Revision: http://reviews.llvm.org/D11352 llvm-svn: 244920
This commit is contained in:
parent
25813b5a03
commit
15b7b9c050
@ -22,18 +22,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(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
||||
; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
||||
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.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(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
||||
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
||||
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> call void @llvm.arm.neon.vst1.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(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
||||
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4
|
||||
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
||||
}
|
||||
|
||||
define void @test2(i8* %P, i8* %Q) nounwind ssp {
|
||||
@ -233,7 +233,9 @@ 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 }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #0 = { nounwind readonly argmemonly }
|
||||
attributes #1 = { nounwind argmemonly }
|
||||
attributes #2 = { noinline nounwind readonly }
|
||||
attributes #3 = { nounwind ssp }
|
||||
attributes #4 = { nounwind }
|
||||
|
||||
|
@ -38,5 +38,6 @@ entry:
|
||||
declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*, i32) nounwind readonly
|
||||
declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind
|
||||
|
||||
; CHECK: attributes #0 = { nounwind readonly }
|
||||
; CHECK: attributes #0 = { nounwind readonly argmemonly }
|
||||
; CHECK: attributes #1 = { nounwind argmemonly }
|
||||
; CHECK: attributes [[ATTR]] = { nounwind }
|
||||
|
@ -22,7 +22,8 @@ entry:
|
||||
declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*, i32) nounwind readonly
|
||||
declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind
|
||||
|
||||
; CHECK: attributes #0 = { nounwind readonly }
|
||||
; CHECK: attributes #0 = { nounwind readonly argmemonly }
|
||||
; CHECK: attributes #1 = { nounwind argmemonly }
|
||||
; CHECK: attributes [[NUW]] = { nounwind }
|
||||
|
||||
!0 = !{!"tbaa root", null}
|
||||
|
@ -981,7 +981,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() #31
|
||||
; CHECK: call void @f.nobuiltin() #33
|
||||
|
||||
call fastcc noalias i32* @f.noalias() noinline
|
||||
; CHECK: call fastcc noalias i32* @f.noalias() #11
|
||||
@ -1179,7 +1179,11 @@ define void @intrinsics.codegen() {
|
||||
; CHECK: attributes #26 = { sspstrong }
|
||||
; CHECK: attributes #27 = { uwtable }
|
||||
; CHECK: attributes #28 = { "cpu"="cortex-a8" }
|
||||
; CHECK: attributes #31 = { builtin }
|
||||
; CHECK: attributes #29 = { nounwind readnone }
|
||||
; CHECK: attributes #30 = { nounwind readonly argmemonly }
|
||||
; CHECK: attributes #31 = { nounwind argmemonly }
|
||||
; CHECK: attributes #32 = { nounwind readonly }
|
||||
; CHECK: attributes #33 = { builtin }
|
||||
|
||||
;; Metadata
|
||||
|
||||
|
@ -1024,7 +1024,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() #34
|
||||
; CHECK: call void @f.nobuiltin() #36
|
||||
|
||||
call fastcc noalias i32* @f.noalias() noinline
|
||||
; CHECK: call fastcc noalias i32* @f.noalias() #12
|
||||
@ -1245,8 +1245,10 @@ define void @misc.metadata() {
|
||||
; CHECK: attributes #30 = { uwtable }
|
||||
; CHECK: attributes #31 = { "cpu"="cortex-a8" }
|
||||
; CHECK: attributes #32 = { nounwind readnone }
|
||||
; CHECK: attributes #33 = { nounwind readonly }
|
||||
; CHECK: attributes #34 = { builtin }
|
||||
; CHECK: attributes #33 = { nounwind readonly argmemonly }
|
||||
; CHECK: attributes #34 = { nounwind argmemonly }
|
||||
; CHECK: attributes #35 = { nounwind readonly }
|
||||
; CHECK: attributes #36 = { builtin }
|
||||
|
||||
;; Metadata
|
||||
|
||||
|
@ -344,4 +344,5 @@ terminate:
|
||||
; CHECK: attributes [[NUW]] = { nounwind }
|
||||
; CHECK: attributes #1 = { nounwind readnone }
|
||||
; CHECK: attributes #2 = { ssp uwtable }
|
||||
; CHECK: attributes #3 = { noreturn nounwind }
|
||||
; CHECK: attributes #3 = { nounwind argmemonly }
|
||||
; CHECK: attributes #4 = { noreturn nounwind }
|
||||
|
@ -16,24 +16,25 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 {
|
||||
define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
|
||||
entry:
|
||||
tail call void @hello(i8* %a, i8* %c, i8* %b)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 {
|
||||
; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
|
||||
; CHECK: entry:
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 16, i32 16, i1 false) #0, !noalias !0
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c, i64 16, i32 16, i1 false) #0, !noalias !3
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %c, i64 16, i32 16, i1 false) #0, !alias.scope !5
|
||||
; CHECK: call void @hey() #0, !noalias !5
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %c, i64 16, i32 16, i1 false) #0, !noalias !3
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 16, i32 16, i1 false) #1, !noalias !0
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c, i64 16, i32 16, i1 false) #1, !noalias !3
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %c, i64 16, i32 16, i1 false) #1, !alias.scope !5
|
||||
; CHECK: call void @hey() #1, !noalias !5
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %c, i64 16, i32 16, i1 false) #1, !noalias !3
|
||||
; CHECK: ret void
|
||||
; CHECK: }
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
attributes #1 = { nounwind uwtable }
|
||||
attributes #0 = { nounwind argmemonly }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind uwtable }
|
||||
|
||||
; CHECK: !0 = !{!1}
|
||||
; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
|
||||
|
@ -206,5 +206,6 @@ declare void @f1(%struct.big* nocapture sret)
|
||||
declare void @f2(%struct.big*)
|
||||
|
||||
; CHECK: attributes [[NUW]] = { nounwind }
|
||||
; CHECK: attributes #1 = { nounwind ssp }
|
||||
; CHECK: attributes #2 = { nounwind ssp uwtable }
|
||||
; CHECK: attributes #1 = { nounwind argmemonly }
|
||||
; CHECK: attributes #2 = { nounwind ssp }
|
||||
; CHECK: attributes #3 = { nounwind ssp uwtable }
|
||||
|
@ -819,5 +819,7 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: attributes [[NUW]] = { nounwind }
|
||||
|
||||
; CHECK: attributes #0 = { nounwind argmemonly }
|
||||
; CHECK: attributes #1 = { nonlazybind }
|
||||
; CHECK: attributes [[NUW]] = { nounwind }
|
||||
|
@ -60,9 +60,10 @@ namespace llvm {
|
||||
IntrinsicSignature IS;
|
||||
|
||||
// Memory mod/ref behavior of this intrinsic.
|
||||
enum {
|
||||
enum ModRefKind {
|
||||
NoMem, ReadArgMem, ReadMem, ReadWriteArgMem, ReadWriteMem
|
||||
} ModRef;
|
||||
};
|
||||
ModRefKind ModRef;
|
||||
|
||||
/// This is set to true if the intrinsic is overloaded by its argument
|
||||
/// types.
|
||||
|
@ -502,28 +502,6 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum ModRefKind {
|
||||
MRK_none,
|
||||
MRK_readonly,
|
||||
MRK_readnone
|
||||
};
|
||||
}
|
||||
|
||||
static ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) {
|
||||
switch (intrinsic.ModRef) {
|
||||
case CodeGenIntrinsic::NoMem:
|
||||
return MRK_readnone;
|
||||
case CodeGenIntrinsic::ReadArgMem:
|
||||
case CodeGenIntrinsic::ReadMem:
|
||||
return MRK_readonly;
|
||||
case CodeGenIntrinsic::ReadWriteArgMem:
|
||||
case CodeGenIntrinsic::ReadWriteMem:
|
||||
return MRK_none;
|
||||
}
|
||||
llvm_unreachable("bad mod-ref kind");
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct AttributeComparator {
|
||||
bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
|
||||
@ -541,8 +519,8 @@ struct AttributeComparator {
|
||||
return R->isConvergent;
|
||||
|
||||
// Try to order by readonly/readnone attribute.
|
||||
ModRefKind LK = getModRefKind(*L);
|
||||
ModRefKind RK = getModRefKind(*R);
|
||||
CodeGenIntrinsic::ModRefKind LK = L->ModRef;
|
||||
CodeGenIntrinsic::ModRefKind RK = R->ModRef;
|
||||
if (LK != RK) return (LK > RK);
|
||||
|
||||
// Order by argument attributes.
|
||||
@ -649,10 +627,10 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
|
||||
}
|
||||
}
|
||||
|
||||
ModRefKind modRef = getModRefKind(intrinsic);
|
||||
|
||||
if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn ||
|
||||
intrinsic.isNoDuplicate || intrinsic.isConvergent) {
|
||||
if (!intrinsic.canThrow ||
|
||||
intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem ||
|
||||
intrinsic.isNoReturn || intrinsic.isNoDuplicate ||
|
||||
intrinsic.isConvergent) {
|
||||
OS << " const Attribute::AttrKind Atts[] = {";
|
||||
bool addComma = false;
|
||||
if (!intrinsic.canThrow) {
|
||||
@ -678,17 +656,29 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
|
||||
addComma = true;
|
||||
}
|
||||
|
||||
switch (modRef) {
|
||||
case MRK_none: break;
|
||||
case MRK_readonly:
|
||||
switch (intrinsic.ModRef) {
|
||||
case CodeGenIntrinsic::NoMem:
|
||||
if (addComma)
|
||||
OS << ",";
|
||||
OS << "Attribute::ReadNone";
|
||||
break;
|
||||
case CodeGenIntrinsic::ReadArgMem:
|
||||
if (addComma)
|
||||
OS << ",";
|
||||
OS << "Attribute::ReadOnly,";
|
||||
OS << "Attribute::ArgMemOnly";
|
||||
break;
|
||||
case CodeGenIntrinsic::ReadMem:
|
||||
if (addComma)
|
||||
OS << ",";
|
||||
OS << "Attribute::ReadOnly";
|
||||
break;
|
||||
case MRK_readnone:
|
||||
case CodeGenIntrinsic::ReadWriteArgMem:
|
||||
if (addComma)
|
||||
OS << ",";
|
||||
OS << "Attribute::ReadNone";
|
||||
OS << "Attribute::ArgMemOnly";
|
||||
break;
|
||||
case CodeGenIntrinsic::ReadWriteMem:
|
||||
break;
|
||||
}
|
||||
OS << "};\n";
|
||||
|
Loading…
Reference in New Issue
Block a user