Modify the LLVM assembly output so that it uses references to represent function attributes.

This makes the LLVM assembly look better. E.g.:

     define void @foo() #0 { ret void }
     attributes #0 = { nounwind noinline ssp }


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175605 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2013-02-20 07:21:42 +00:00
parent 9030fc22dd
commit 7ab6c76ad1
28 changed files with 244 additions and 164 deletions

View File

@ -66,22 +66,21 @@ static const Module *getModuleFromVal(const Value *V) {
return 0;
}
static void PrintCallingConv(unsigned cc, raw_ostream &Out)
{
static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
switch (cc) {
case CallingConv::Fast: Out << "fastcc"; break;
case CallingConv::Cold: Out << "coldcc"; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;
case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break;
case CallingConv::Intel_OCL_BI: Out << "intel_ocl_bicc"; break;
case CallingConv::ARM_APCS: Out << "arm_apcscc"; break;
case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break;
case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc"; break;
case CallingConv::MSP430_INTR: Out << "msp430_intrcc"; break;
case CallingConv::PTX_Kernel: Out << "ptx_kernel"; break;
case CallingConv::PTX_Device: Out << "ptx_device"; break;
default: Out << "cc" << cc; break;
default: Out << "cc" << cc; break;
case CallingConv::Fast: Out << "fastcc"; break;
case CallingConv::Cold: Out << "coldcc"; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;
case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break;
case CallingConv::Intel_OCL_BI: Out << "intel_ocl_bicc"; break;
case CallingConv::ARM_APCS: Out << "arm_apcscc"; break;
case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break;
case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break;
case CallingConv::MSP430_INTR: Out << "msp430_intrcc"; break;
case CallingConv::PTX_Kernel: Out << "ptx_kernel"; break;
case CallingConv::PTX_Device: Out << "ptx_device"; break;
}
}
@ -510,6 +509,7 @@ void SlotTracker::processModule() {
CreateModuleSlot(I);
// Add all the function attributes to the table.
// FIXME: Add attributes of other objects?
AttributeSet FnAttrs = I->getAttributes().getFnAttributes();
if (FnAttrs.hasAttributes(AttributeSet::FunctionIndex))
CreateAttributeSetSlot(FnAttrs);
@ -1662,7 +1662,7 @@ void AssemblyWriter::printFunction(const Function *F) {
if (F->hasUnnamedAddr())
Out << " unnamed_addr";
if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
Out << ' ' << Attrs.getAsString(AttributeSet::FunctionIndex);
Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
if (F->hasSection()) {
Out << " section \"";
PrintEscapedString(F->getSection(), Out);

View File

@ -37,3 +37,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 #1 = { nounwind }

View File

@ -49,3 +49,6 @@ declare i32 @TestConst(i32) readnone
declare i32 @TestPure(i32) readonly
declare i32 @TestNone(i32)
; CHECK: attributes #0 = { readnone }
; CHECK: attributes #1 = { readonly }

View File

@ -9,13 +9,13 @@
; invalid, as it's possible that this only happens after optimization on a
; code path which isn't ever executed.
; CHECK: define void @test0_yes(i32* nocapture %p) nounwind readnone {
; CHECK: define void @test0_yes(i32* nocapture %p) #0 {
define void @test0_yes(i32* %p) nounwind {
store i32 0, i32* %p, !tbaa !1
ret void
}
; CHECK: define void @test0_no(i32* nocapture %p) nounwind {
; CHECK: define void @test0_no(i32* nocapture %p) #1 {
define void @test0_no(i32* %p) nounwind {
store i32 0, i32* %p, !tbaa !2
ret void
@ -24,13 +24,13 @@ define void @test0_no(i32* %p) nounwind {
; Add the readonly attribute, since there's just a call to a function which
; TBAA says doesn't modify any memory.
; CHECK: define void @test1_yes(i32* nocapture %p) nounwind readonly {
; CHECK: define void @test1_yes(i32* nocapture %p) #2 {
define void @test1_yes(i32* %p) nounwind {
call void @callee(i32* %p), !tbaa !1
ret void
}
; CHECK: define void @test1_no(i32* %p) nounwind {
; CHECK: define void @test1_no(i32* %p) #1 {
define void @test1_no(i32* %p) nounwind {
call void @callee(i32* %p), !tbaa !2
ret void
@ -43,13 +43,13 @@ define void @test1_no(i32* %p) nounwind {
; This is unusual, since the function is memcpy, but as above, this
; isn't necessarily invalid.
; CHECK: define void @test2_yes(i8* nocapture %p, i8* nocapture %q, i64 %n) nounwind readnone {
; CHECK: define void @test2_yes(i8* nocapture %p, i8* nocapture %q, i64 %n) #0 {
define void @test2_yes(i8* %p, i8* %q, i64 %n) nounwind {
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i32 1, i1 false), !tbaa !1
ret void
}
; CHECK: define void @test2_no(i8* nocapture %p, i8* nocapture %q, i64 %n) nounwind {
; CHECK: define void @test2_no(i8* nocapture %p, i8* nocapture %q, i64 %n) #1 {
define void @test2_no(i8* %p, i8* %q, i64 %n) nounwind {
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i32 1, i1 false), !tbaa !2
ret void
@ -57,13 +57,13 @@ define void @test2_no(i8* %p, i8* %q, i64 %n) nounwind {
; Similar to the others, va_arg only accesses memory through its operand.
; CHECK: define i32 @test3_yes(i8* nocapture %p) nounwind readnone {
; CHECK: define i32 @test3_yes(i8* nocapture %p) #0 {
define i32 @test3_yes(i8* %p) nounwind {
%t = va_arg i8* %p, i32, !tbaa !1
ret i32 %t
}
; CHECK: define i32 @test3_no(i8* nocapture %p) nounwind {
; CHECK: define i32 @test3_no(i8* nocapture %p) #1 {
define i32 @test3_no(i8* %p) nounwind {
%t = va_arg i8* %p, i32, !tbaa !2
ret i32 %t
@ -72,6 +72,10 @@ define i32 @test3_no(i8* %p) nounwind {
declare void @callee(i32* %p) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) nounwind
; CHECK: attributes #0 = { nounwind readnone }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { nounwind readonly }
; Root note.
!0 = metadata !{ }

View File

@ -22,6 +22,9 @@ 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 #1 = { nounwind }
!0 = metadata !{metadata !"tbaa root", null}
!1 = metadata !{metadata !"A", metadata !0}
!2 = metadata !{metadata !"B", metadata !0}

View File

@ -1,18 +1,21 @@
; Test function attributes
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; CHECK: define void @fn1() alwaysinline
; CHECK: define void @fn1() #0
define void @fn1() alwaysinline {
ret void
}
; CHECK: define void @fn2() noinline
; CHECK: define void @fn2() #1
define void @fn2() noinline {
ret void
}
; CHECK: define void @fn3()
; CHECK-NOT: define void @fn3(){{.*}}inline
; CHECK-NOT: define void @fn3() #{{.*}}
define void @fn3() {
ret void
}
; CHECK: attributes #0 = { alwaysinline }
; CHECK: attributes #1 = { noinline }

View File

@ -15,4 +15,6 @@ declare i32 @zed(%struct.foobar*, %struct.foobar*)
; CHECK: @bar.d = internal unnamed_addr constant %struct.foobar zeroinitializer, align 4
; CHECK: @foo.d = internal constant %struct.foobar zeroinitializer, align 4
; CHECK: define i32 @main() unnamed_addr nounwind ssp {
; CHECK: define i32 @main() unnamed_addr #0 {
; CHECK: attributes #0 = { nounwind ssp }

View File

@ -14,7 +14,7 @@ define void @f2(i8 signext)
}
define void @f3() noreturn
; CHECK: define void @f3() noreturn
; CHECK: define void @f3() #0
{
ret void;
}
@ -32,7 +32,7 @@ define void @f5(i8* sret)
}
define void @f6() nounwind
; CHECK: define void @f6() nounwind
; CHECK: define void @f6() #1
{
ret void;
}
@ -56,43 +56,43 @@ define void @f9(i8* nest)
}
define void @f10() readnone
; CHECK: define void @f10() readnone
; CHECK: define void @f10() #2
{
ret void;
}
define void @f11() readonly
; CHECK: define void @f11() readonly
; CHECK: define void @f11() #3
{
ret void;
}
define void @f12() noinline
; CHECK: define void @f12() noinline
; CHECK: define void @f12() #4
{
ret void;
}
define void @f13() alwaysinline
; CHECK: define void @f13() alwaysinline
; CHECK: define void @f13() #5
{
ret void;
}
define void @f14() optsize
; CHECK: define void @f14() optsize
; CHECK: define void @f14() #6
{
ret void;
}
define void @f15() ssp
; CHECK: define void @f15() ssp
; CHECK: define void @f15() #7
{
ret void;
}
define void @f16() sspreq
; CHECK: define void @f16() sspreq
; CHECK: define void @f16() #8
{
ret void;
}
@ -110,71 +110,71 @@ define void @f18(i8* nocapture)
}
define void @f19() noredzone
; CHECK: define void @f19() noredzone
; CHECK: define void @f19() #9
{
ret void;
}
define void @f20() noimplicitfloat
; CHECK: define void @f20() noimplicitfloat
; CHECK: define void @f20() #10
{
ret void;
}
define void @f21() naked
; CHECK: define void @f21() naked
; CHECK: define void @f21() #11
{
ret void;
}
define void @f22() inlinehint
; CHECK: define void @f22() inlinehint
; CHECK: define void @f22() #12
{
ret void;
}
define void @f23() alignstack(4)
; CHECK: define void @f23() alignstack(4)
; CHECK: define void @f23() #13
{
ret void;
}
define void @f24() returns_twice
; CHECK: define void @f24() returns_twice
; CHECK: define void @f24() #14
{
ret void;
}
define void @f25() uwtable
; CHECK: define void @f25() uwtable
; CHECK: define void @f25() #15
{
ret void;
}
define void @f26() nonlazybind
; CHECK: define void @f26() nonlazybind
; CHECK: define void @f26() #16
{
ret void;
}
define void @f27() address_safety
; CHECK: define void @f27() address_safety
; CHECK: define void @f27() #17
{
ret void;
}
define void @f28() thread_safety
; CHECK: define void @f28() thread_safety
; CHECK: define void @f28() #18
{
ret void;
}
define void @f29() uninitialized_checks
; CHECK: define void @f29() uninitialized_checks
; CHECK: define void @f29() #19
{
ret void;
}
define void @f30() "cpu"="cortex-a8"
; CHECK: define void @f30() "cpu"="cortex-a8"
; CHECK: define void @f30() #20
{
ret void;
}

View File

@ -13,10 +13,13 @@ entry:
ret i32 %add2
}
; CHECK: declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) #1
; CHECK: declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) #1
; CHECK: declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) #1
declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) nounwind readnone
declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone
declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: attributes #0 = { nounwind }
; CHECK: attributes #1 = { nounwind readnone }

View File

@ -13,10 +13,13 @@ entry:
ret i32 %add2
}
; CHECK: declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) #1
; CHECK: declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) #1
; CHECK: declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) #1
declare i32 @llvm.x86.sse41.ptestc(<4 x float>, <4 x float>) nounwind readnone
declare i32 @llvm.x86.sse41.ptestz(<4 x float>, <4 x float>) nounwind readnone
declare i32 @llvm.x86.sse41.ptestnzc(<4 x float>, <4 x float>) nounwind readnone
; CHECK: attributes #0 = { nounwind }
; CHECK: attributes #1 = { nounwind readnone }

View File

@ -0,0 +1,15 @@
; RUN: llvm-as < %s | llvm-dis > %t1.ll
; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
; RUN: diff %t1.ll %t2.ll
@.str = private unnamed_addr constant [14 x i8] c"hello world!\0A\00", align 1
define void @foo() #0 {
entry:
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0))
ret void
}
declare i32 @printf(i8*, ...)
attributes #0 = { nounwind ssp uwtable }

View File

@ -61,10 +61,14 @@ define void @libm() {
; FIXME: test ALL the intrinsics in this file.
; rdar://11542750
; CHECK: declare void @llvm.trap() noreturn nounwind
; CHECK: declare void @llvm.trap() #2
declare void @llvm.trap()
define void @trap() {
call void @llvm.trap()
ret void
}
; CHECK: attributes #0 = { nounwind readnone }
; CHECK: attributes #1 = { nounwind readonly }
; CHECK: attributes #2 = { noreturn nounwind }

View File

@ -1,7 +1,8 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
define void @test1() minsize {
; CHECK: define void @test1() minsize
; CHECK: define void @test1() #0
ret void
}
; CHECK: attributes #0 = { minsize }

View File

@ -118,64 +118,64 @@
; Duplicate all of the above as function return values rather than
; global initializers.
; PLAIN: define i8* @goo8() nounwind {
; PLAIN: define i8* @goo8() #0 {
; PLAIN: %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
; PLAIN: ret i8* %t
; PLAIN: }
; PLAIN: define i1* @goo1() nounwind {
; PLAIN: define i1* @goo1() #0 {
; PLAIN: %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
; PLAIN: ret i1* %t
; PLAIN: }
; PLAIN: define i8* @foo8() nounwind {
; PLAIN: define i8* @foo8() #0 {
; PLAIN: %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
; PLAIN: ret i8* %t
; PLAIN: }
; PLAIN: define i1* @foo1() nounwind {
; PLAIN: define i1* @foo1() #0 {
; PLAIN: %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
; PLAIN: ret i1* %t
; PLAIN: }
; PLAIN: define i8* @hoo8() nounwind {
; PLAIN: define i8* @hoo8() #0 {
; PLAIN: %t = bitcast i8* getelementptr (i8* null, i32 -1) to i8*
; PLAIN: ret i8* %t
; PLAIN: }
; PLAIN: define i1* @hoo1() nounwind {
; PLAIN: define i1* @hoo1() #0 {
; PLAIN: %t = bitcast i1* getelementptr (i1* null, i32 -1) to i1*
; PLAIN: ret i1* %t
; PLAIN: }
; OPT: define i8* @goo8() nounwind {
; OPT: define i8* @goo8() #0 {
; OPT: ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
; OPT: }
; OPT: define i1* @goo1() nounwind {
; OPT: define i1* @goo1() #0 {
; OPT: ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
; OPT: }
; OPT: define i8* @foo8() nounwind {
; OPT: define i8* @foo8() #0 {
; OPT: ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
; OPT: }
; OPT: define i1* @foo1() nounwind {
; OPT: define i1* @foo1() #0 {
; OPT: ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
; OPT: }
; OPT: define i8* @hoo8() nounwind {
; OPT: define i8* @hoo8() #0 {
; OPT: ret i8* getelementptr (i8* null, i32 -1)
; OPT: }
; OPT: define i1* @hoo1() nounwind {
; OPT: define i1* @hoo1() #0 {
; OPT: ret i1* getelementptr (i1* null, i32 -1)
; OPT: }
; TO: define i8* @goo8() nounwind {
; TO: define i8* @goo8() #0 {
; TO: ret i8* null
; TO: }
; TO: define i1* @goo1() nounwind {
; TO: define i1* @goo1() #0 {
; TO: ret i1* null
; TO: }
; TO: define i8* @foo8() nounwind {
; TO: define i8* @foo8() #0 {
; TO: ret i8* inttoptr (i64 -1 to i8*)
; TO: }
; TO: define i1* @foo1() nounwind {
; TO: define i1* @foo1() #0 {
; TO: ret i1* inttoptr (i64 -1 to i1*)
; TO: }
; TO: define i8* @hoo8() nounwind {
; TO: define i8* @hoo8() #0 {
; TO: ret i8* inttoptr (i64 -1 to i8*)
; TO: }
; TO: define i1* @hoo1() nounwind {
; TO: define i1* @hoo1() #0 {
; TO: ret i1* inttoptr (i64 -1 to i1*)
; TO: }
; SCEV: Classifying expressions for: @goo8
@ -220,94 +220,94 @@ define i1* @hoo1() nounwind {
ret i1* %t
}
; PLAIN: define i64 @fa() nounwind {
; PLAIN: define i64 @fa() #0 {
; PLAIN: %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fb() nounwind {
; PLAIN: define i64 @fb() #0 {
; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fc() nounwind {
; PLAIN: define i64 @fc() #0 {
; PLAIN: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fd() nounwind {
; PLAIN: define i64 @fd() #0 {
; PLAIN: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fe() nounwind {
; PLAIN: define i64 @fe() #0 {
; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr ({ double, float, double, double }* null, i64 0, i32 2) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @ff() nounwind {
; PLAIN: define i64 @ff() #0 {
; PLAIN: %t = bitcast i64 1 to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fg() nounwind {
; PLAIN: define i64 @fg() #0 {
; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fh() nounwind {
; PLAIN: define i64 @fh() #0 {
; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fi() nounwind {
; PLAIN: define i64 @fi() #0 {
; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr ({ i1, i1* }* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; OPT: define i64 @fa() nounwind {
; OPT: define i64 @fa() #0 {
; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
; OPT: }
; OPT: define i64 @fb() nounwind {
; OPT: define i64 @fb() #0 {
; OPT: ret i64 ptrtoint (double* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64)
; OPT: }
; OPT: define i64 @fc() nounwind {
; OPT: define i64 @fc() #0 {
; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
; OPT: }
; OPT: define i64 @fd() nounwind {
; OPT: define i64 @fd() #0 {
; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
; OPT: }
; OPT: define i64 @fe() nounwind {
; OPT: define i64 @fe() #0 {
; OPT: ret i64 ptrtoint (double* getelementptr ({ double, float, double, double }* null, i64 0, i32 2) to i64)
; OPT: }
; OPT: define i64 @ff() nounwind {
; OPT: define i64 @ff() #0 {
; OPT: ret i64 1
; OPT: }
; OPT: define i64 @fg() nounwind {
; OPT: define i64 @fg() #0 {
; OPT: ret i64 ptrtoint (double* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64)
; OPT: }
; OPT: define i64 @fh() nounwind {
; OPT: define i64 @fh() #0 {
; OPT: ret i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
; OPT: }
; OPT: define i64 @fi() nounwind {
; OPT: define i64 @fi() #0 {
; OPT: ret i64 ptrtoint (i1** getelementptr ({ i1, i1* }* null, i64 0, i32 1) to i64)
; OPT: }
; TO: define i64 @fa() nounwind {
; TO: define i64 @fa() #0 {
; TO: ret i64 18480
; TO: }
; TO: define i64 @fb() nounwind {
; TO: define i64 @fb() #0 {
; TO: ret i64 8
; TO: }
; TO: define i64 @fc() nounwind {
; TO: define i64 @fc() #0 {
; TO: ret i64 16
; TO: }
; TO: define i64 @fd() nounwind {
; TO: define i64 @fd() #0 {
; TO: ret i64 88
; TO: }
; TO: define i64 @fe() nounwind {
; TO: define i64 @fe() #0 {
; TO: ret i64 16
; TO: }
; TO: define i64 @ff() nounwind {
; TO: define i64 @ff() #0 {
; TO: ret i64 1
; TO: }
; TO: define i64 @fg() nounwind {
; TO: define i64 @fg() #0 {
; TO: ret i64 8
; TO: }
; TO: define i64 @fh() nounwind {
; TO: define i64 @fh() #0 {
; TO: ret i64 8
; TO: }
; TO: define i64 @fi() nounwind {
; TO: define i64 @fi() #0 {
; TO: ret i64 8
; TO: }
; SCEV: Classifying expressions for: @fa
@ -375,34 +375,34 @@ define i64 @fi() nounwind {
ret i64 %t
}
; PLAIN: define i64* @fM() nounwind {
; PLAIN: define i64* @fM() #0 {
; PLAIN: %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
; PLAIN: ret i64* %t
; PLAIN: }
; PLAIN: define i64* @fN() nounwind {
; PLAIN: define i64* @fN() #0 {
; PLAIN: %t = bitcast i64* getelementptr ({ i64, i64 }* null, i32 0, i32 1) to i64*
; PLAIN: ret i64* %t
; PLAIN: }
; PLAIN: define i64* @fO() nounwind {
; PLAIN: define i64* @fO() #0 {
; PLAIN: %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
; PLAIN: ret i64* %t
; PLAIN: }
; OPT: define i64* @fM() nounwind {
; OPT: define i64* @fM() #0 {
; OPT: ret i64* getelementptr (i64* null, i32 1)
; OPT: }
; OPT: define i64* @fN() nounwind {
; OPT: define i64* @fN() #0 {
; OPT: ret i64* getelementptr ({ i64, i64 }* null, i32 0, i32 1)
; OPT: }
; OPT: define i64* @fO() nounwind {
; OPT: define i64* @fO() #0 {
; OPT: ret i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
; OPT: }
; TO: define i64* @fM() nounwind {
; TO: define i64* @fM() #0 {
; TO: ret i64* inttoptr (i64 8 to i64*)
; TO: }
; TO: define i64* @fN() nounwind {
; TO: define i64* @fN() #0 {
; TO: ret i64* inttoptr (i64 8 to i64*)
; TO: }
; TO: define i64* @fO() nounwind {
; TO: define i64* @fO() #0 {
; TO: ret i64* inttoptr (i64 8 to i64*)
; TO: }
; SCEV: Classifying expressions for: @fM
@ -428,14 +428,14 @@ define i64* @fO() nounwind {
ret i64* %t
}
; PLAIN: define i32* @fZ() nounwind {
; PLAIN: define i32* @fZ() #0 {
; PLAIN: %t = bitcast i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
; PLAIN: ret i32* %t
; PLAIN: }
; OPT: define i32* @fZ() nounwind {
; OPT: define i32* @fZ() #0 {
; OPT: ret i32* getelementptr (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
; OPT: }
; TO: define i32* @fZ() nounwind {
; TO: define i32* @fZ() #0 {
; TO: ret i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
; TO: }
; SCEV: Classifying expressions for: @fZ
@ -446,3 +446,5 @@ define i32* @fZ() nounwind {
%t = bitcast i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
ret i32* %t
}
; CHECK: attributes #0 = { nounwind }

View File

@ -1,6 +1,6 @@
; RUN: opt < %s -argpromotion -S | FileCheck %s
; CHECK: define internal i32 @deref(i32 %x.val) nounwind {
; CHECK: define internal i32 @deref(i32 %x.val) #0 {
define internal i32 @deref(i32* %x) nounwind {
entry:
%tmp2 = load i32* %x, align 4
@ -15,3 +15,5 @@ entry:
%tmp1 = call i32 @deref( i32* %x_addr ) nounwind
ret i32 %tmp1
}
; CHECK: attributes #0 = { nounwind }

View File

@ -124,8 +124,10 @@ define double @test4(double %A1, double %A2, double %B1, double %B2, i32 %P) {
; CHECK: ret double %R
}
; CHECK: declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone
; CHECK: declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone
; CHECK: declare <2 x double> @llvm.cos.v2f64(<2 x double>) nounwind readonly
; CHECK: declare <2 x double> @llvm.powi.v2f64(<2 x double>, i32) nounwind readonly
; CHECK: declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) #0
; CHECK: declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>) #0
; CHECK: declare <2 x double> @llvm.cos.v2f64(<2 x double>) #1
; CHECK: declare <2 x double> @llvm.powi.v2f64(<2 x double>, i32) #1
; CHECK: attributes #0 = { nounwind readnone }
; CHECK: attributes #1 = { nounwind readonly }

View File

@ -4,7 +4,7 @@
@g = global i8 0
; CHECK: define internal void @foo(i8 signext %y) nounwind
; CHECK: define internal void @foo(i8 signext %y) #0
define internal zeroext i8 @foo(i8* inreg %p, i8 signext %y, ... ) nounwind {
store i8 %y, i8* @g
@ -16,3 +16,5 @@ define i32 @bar() {
%A = call zeroext i8(i8*, i8, ...)* @foo(i8* inreg null, i8 signext 1, %struct* byval null ) nounwind
ret i32 0
}
; CHECK: attributes #0 = { nounwind }

View File

@ -15,7 +15,7 @@ entry:
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
define internal fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext %extra, i32 %flags) nounwind noinline ssp {
define internal fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext %extra, i32 %flags) noinline nounwind ssp {
entry:
call void @llvm.dbg.value(metadata !{i8* %name}, i64 0, metadata !15)
call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !20)
@ -38,6 +38,10 @@ bb2: ; preds = %bb1, %bb
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
; CHECK: attributes #0 = { nounwind ssp }
; CHECK: attributes #1 = { nounwind readnone }
; CHECK: attributes #2 = { noinline nounwind ssp }
!0 = metadata !{i32 524545, metadata !1, metadata !"name", metadata !2, i32 8, metadata !6} ; [ DW_TAG_arg_variable ]
!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"vfs_addname", metadata !"vfs_addname", metadata !"vfs_addname", metadata !2, i32 12, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
!2 = metadata !{i32 524329, metadata !"tail.c", metadata !"/Users/echeng/LLVM/radars/r7927803/", metadata !3} ; [ DW_TAG_file_type ]

View File

@ -1,6 +1,4 @@
; RUN: opt < %s -deadargelim -S > %t
; RUN: grep "define internal zeroext i32 @test1() nounwind" %t
; RUN: grep "define internal <{ i32, i32 }> @test2" %t
; RUN: opt < %s -deadargelim -S | FileCheck %s
%Ty = type <{ i32, i32 }>
@ -9,11 +7,13 @@
; the function and then changing too much.
; This checks if the return value attributes are not removed
; CHECK: define internal zeroext i32 @test1() #0
define internal zeroext i32 @test1(i32 %DEADARG1) nounwind {
ret i32 1
}
; This checks if the struct doesn't get non-packed
; CHECK: define internal <{ i32, i32 }> @test2
define internal <{ i32, i32 }> @test2(i32 %DEADARG1) {
ret <{ i32, i32 }> <{ i32 1, i32 2 }>
}
@ -28,3 +28,4 @@ define void @caller() {
ret void
}
; CHECK: attributes #0 = { nounwind }

View File

@ -1,22 +1,24 @@
; RUN: opt < %s -basicaa -functionattrs -S | FileCheck %s
@x = global i32 0
; CHECK: declare i32 @e() readnone
; CHECK: declare i32 @e() #0
declare i32 @e() readnone
; CHECK: define i32 @f() readnone
; CHECK: define i32 @f() #0
define i32 @f() {
%tmp = call i32 @e( ) ; <i32> [#uses=1]
ret i32 %tmp
}
; CHECK: define i32 @g() readnone
; CHECK: define i32 @g() #0
define i32 @g() readonly {
ret i32 0
}
; CHECK: define i32 @h() readnone
; CHECK: define i32 @h() #0
define i32 @h() readnone {
%tmp = load i32* @x ; <i32> [#uses=1]
ret i32 %tmp
}
; CHECK: attributes #0 = { readnone }

View File

@ -1,11 +1,13 @@
; RUN: opt < %s -basicaa -functionattrs -S | FileCheck %s
; CHECK: define i32 @f() readonly
; CHECK: define i32 @f() #0
define i32 @f() {
entry:
%tmp = call i32 @e( )
ret i32 %tmp
}
; CHECK: declare i32 @e() readonly
; CHECK: declare i32 @e() #0
declare i32 @e() readonly
; CHECK: attributes #0 = { readonly }

View File

@ -3,7 +3,7 @@
; Atomic load/store to local doesn't affect whether a function is
; readnone/readonly.
define i32 @test1(i32 %x) uwtable ssp {
; CHECK: define i32 @test1(i32 %x) readnone ssp uwtable {
; CHECK: define i32 @test1(i32 %x) #0 {
entry:
%x.addr = alloca i32, align 4
store atomic i32 %x, i32* %x.addr seq_cst, align 4
@ -13,9 +13,11 @@ entry:
; A function with an Acquire load is not readonly.
define i32 @test2(i32* %x) uwtable ssp {
; CHECK: define i32 @test2(i32* nocapture %x) ssp uwtable {
; CHECK: define i32 @test2(i32* nocapture %x) #1 {
entry:
%r = load atomic i32* %x seq_cst, align 4
ret i32 %r
}
; CHECK: attributes #0 = { readnone ssp uwtable }
; CHECK: attributes #1 = { ssp uwtable }

View File

@ -4,7 +4,7 @@
; IPSCCP should propagate the 0 argument, eliminate the switch, and propagate
; the result.
; CHECK: define i32 @main() noreturn nounwind {
; CHECK: define i32 @main() #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: %call2 = tail call i32 @wwrite(i64 0) nounwind
; CHECK-NEXT: ret i32 123
@ -28,3 +28,6 @@ sw.default:
return:
ret i32 0
}
; CHECK: attributes #0 = { noreturn nounwind }
; CHECK: attributes #1 = { nounwind readnone }

View File

@ -39,35 +39,35 @@ entry:
define void @inline_req_req() nounwind sspreq uwtable {
entry:
; CHECK: @inline_req_req() nounwind sspreq uwtable
; CHECK: @inline_req_req() #0
call void @fun_sspreq()
ret void
}
define void @inline_req_strong() nounwind sspstrong uwtable {
entry:
; CHECK: @inline_req_strong() nounwind sspreq uwtable
; CHECK: @inline_req_strong() #0
call void @fun_sspreq()
ret void
}
define void @inline_req_ssp() nounwind ssp uwtable {
entry:
; CHECK: @inline_req_ssp() nounwind sspreq uwtable
; CHECK: @inline_req_ssp() #0
call void @fun_sspreq()
ret void
}
define void @inline_req_nossp() nounwind uwtable {
entry:
; CHECK: @inline_req_nossp() nounwind sspreq uwtable
; CHECK: @inline_req_nossp() #0
call void @fun_sspreq()
ret void
}
define void @inline_strong_req() nounwind sspreq uwtable {
entry:
; CHECK: @inline_strong_req() nounwind sspreq uwtable
; CHECK: @inline_strong_req() #0
call void @fun_sspstrong()
ret void
}
@ -75,28 +75,28 @@ entry:
define void @inline_strong_strong() nounwind sspstrong uwtable {
entry:
; CHECK: @inline_strong_strong() nounwind sspstrong uwtable
; CHECK: @inline_strong_strong() #1
call void @fun_sspstrong()
ret void
}
define void @inline_strong_ssp() nounwind ssp uwtable {
entry:
; CHECK: @inline_strong_ssp() nounwind sspstrong uwtable
; CHECK: @inline_strong_ssp() #1
call void @fun_sspstrong()
ret void
}
define void @inline_strong_nossp() nounwind uwtable {
entry:
; CHECK: @inline_strong_nossp() nounwind sspstrong uwtable
; CHECK: @inline_strong_nossp() #1
call void @fun_sspstrong()
ret void
}
define void @inline_ssp_req() nounwind sspreq uwtable {
entry:
; CHECK: @inline_ssp_req() nounwind sspreq uwtable
; CHECK: @inline_ssp_req() #0
call void @fun_ssp()
ret void
}
@ -104,28 +104,28 @@ entry:
define void @inline_ssp_strong() nounwind sspstrong uwtable {
entry:
; CHECK: @inline_ssp_strong() nounwind sspstrong uwtable
; CHECK: @inline_ssp_strong() #1
call void @fun_ssp()
ret void
}
define void @inline_ssp_ssp() nounwind ssp uwtable {
entry:
; CHECK: @inline_ssp_ssp() nounwind ssp uwtable
; CHECK: @inline_ssp_ssp() #2
call void @fun_ssp()
ret void
}
define void @inline_ssp_nossp() nounwind uwtable {
entry:
; CHECK: @inline_ssp_nossp() nounwind ssp uwtable
; CHECK: @inline_ssp_nossp() #2
call void @fun_ssp()
ret void
}
define void @inline_nossp_req() nounwind uwtable sspreq {
entry:
; CHECK: @inline_nossp_req() nounwind sspreq uwtable
; CHECK: @inline_nossp_req() #0
call void @fun_nossp()
ret void
}
@ -133,23 +133,28 @@ entry:
define void @inline_nossp_strong() nounwind sspstrong uwtable {
entry:
; CHECK: @inline_nossp_strong() nounwind sspstrong uwtable
; CHECK: @inline_nossp_strong() #1
call void @fun_nossp()
ret void
}
define void @inline_nossp_ssp() nounwind ssp uwtable {
entry:
; CHECK: @inline_nossp_ssp() nounwind ssp uwtable
; CHECK: @inline_nossp_ssp() #2
call void @fun_nossp()
ret void
}
define void @inline_nossp_nossp() nounwind uwtable {
entry:
; CHECK: @inline_nossp_nossp() nounwind uwtable
; CHECK: @inline_nossp_nossp() #3
call void @fun_nossp()
ret void
}
declare i32 @printf(i8*, ...)
; CHECK: attributes #0 = { nounwind sspreq uwtable }
; CHECK: attributes #1 = { nounwind sspstrong uwtable }
; CHECK: attributes #2 = { nounwind ssp uwtable }
; CHECK: attributes #3 = { nounwind uwtable }

View File

@ -4,7 +4,7 @@
; Indvars and loop deletion should be able to eliminate all looping
; in this testcase.
; CHECK: define i32 @pmat(i32 %m, i32 %n, double* %y) nounwind {
; CHECK: define i32 @pmat(i32 %m, i32 %n, double* %y) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 0
; CHECK-NEXT: }
@ -63,3 +63,5 @@ w.e:
w.e12:
ret i32 0
}
; CHECK: attributes #0 = { nounwind }

View File

@ -86,7 +86,7 @@ for.end: ; preds = %for.body
; Delete nested retain+release pairs around loops.
; CHECK: define void @test3(i8* %a) nounwind {
; CHECK: define void @test3(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: br label %loop
@ -112,7 +112,7 @@ exit:
ret void
}
; CHECK: define void @test4(i8* %a) nounwind {
; CHECK: define void @test4(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: br label %loop
@ -142,7 +142,7 @@ exit:
ret void
}
; CHECK: define void @test5(i8* %a) nounwind {
; CHECK: define void @test5(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: call void @callee()
@ -176,7 +176,7 @@ exit:
ret void
}
; CHECK: define void @test6(i8* %a) nounwind {
; CHECK: define void @test6(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: br label %loop
@ -209,7 +209,7 @@ exit:
ret void
}
; CHECK: define void @test7(i8* %a) nounwind {
; CHECK: define void @test7(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: call void @callee()
@ -242,7 +242,7 @@ exit:
ret void
}
; CHECK: define void @test8(i8* %a) nounwind {
; CHECK: define void @test8(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: br label %loop
@ -274,7 +274,7 @@ exit:
ret void
}
; CHECK: define void @test9(i8* %a) nounwind {
; CHECK: define void @test9(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label %loop
; CHECK-NOT: @objc_
@ -303,7 +303,7 @@ exit:
ret void
}
; CHECK: define void @test10(i8* %a) nounwind {
; CHECK: define void @test10(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label %loop
; CHECK-NOT: @objc_
@ -332,7 +332,7 @@ exit:
ret void
}
; CHECK: define void @test11(i8* %a) nounwind {
; CHECK: define void @test11(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label %loop
; CHECK-NOT: @objc_
@ -362,7 +362,7 @@ exit:
; Don't delete anything if they're not balanced.
; CHECK: define void @test12(i8* %a) nounwind {
; CHECK: define void @test12(i8* %a) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: %outer = tail call i8* @objc_retain(i8* %a) nounwind
; CHECK-NEXT: %inner = tail call i8* @objc_retain(i8* %a) nounwind
@ -394,4 +394,6 @@ exit:
ret void
}
; CHECK: attributes #0 = { nounwind }
!0 = metadata !{}

View File

@ -39,7 +39,7 @@ entry:
; Eliminate unnecessary weak pointer copies in a block initialization.
; CHECK: define void @qux(i8* %me) nounwind {
; CHECK: define void @qux(i8* %me) #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: %block = alloca %1, align 8
; CHECK-NOT: alloca
@ -84,4 +84,6 @@ declare i8* @objc_loadWeak(i8**)
declare void @use(i8*) nounwind
declare void @objc_destroyWeak(i8**)
; CHECK: attributes #0 = { nounwind }
!0 = metadata !{}

View File

@ -1,12 +1,12 @@
; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
; CHECK: declare noalias i8* @fopen(i8* nocapture, i8* nocapture) nounwind
; CHECK: declare noalias i8* @fopen(i8* nocapture, i8* nocapture) #0
declare i8* @fopen(i8*, i8*)
; CHECK: declare i8 @strlen(i8* nocapture) nounwind readonly
; CHECK: declare i8 @strlen(i8* nocapture) #1
declare i8 @strlen(i8*)
; CHECK: declare noalias i32* @realloc(i32* nocapture, i32) nounwind
; CHECK: declare noalias i32* @realloc(i32* nocapture, i32) #0
declare i32* @realloc(i32*, i32)
; Test deliberately wrong declaration
@ -16,3 +16,6 @@ declare i32 @strcpy(...)
; CHECK-NOT: strcpy{{.*}}nocapture
; CHECK-NOT: strcpy{{.*}}nounwind
; CHECK-NOT: strcpy{{.*}}readonly
; CHECK: attributes #0 = { nounwind }
; CHECK: attributes #1 = { nounwind readonly }