From 351b7a10e2560a835759748c58da09e53207b39d Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 22 Feb 2013 09:09:42 +0000 Subject: [PATCH] Use references to attribute groups on the call/invoke instructions. Listing all of the attributes for the callee of a call/invoke instruction is way too much and makes the IR unreadable. Use references to attributes instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175877 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/AsmWriter.cpp | 20 ++++---- test/Analysis/BasicAA/intrinsics.ll | 6 +-- test/Analysis/BasicAA/pure-const-dce.ll | 10 ++-- .../TypeBasedAliasAnalysis/intrinsics.ll | 4 +- .../2008-02-01-ReturnAttrs.ll | 4 +- .../DeadArgElim/2007-12-20-ParamAttrs.ll | 6 +-- .../DeadArgElim/2010-04-30-DbgInfo.ll | 3 +- .../IPConstantProp/user-with-multiple-uses.ll | 3 +- test/Transforms/Inline/inline_invoke.ll | 7 ++- .../InstCombine/2012-04-23-Neon-Intrinsics.ll | 6 ++- test/Transforms/InstCombine/getelementptr.ll | 4 +- test/Transforms/InstCombine/pow-1.ll | 14 +++--- test/Transforms/JumpThreading/basic.ll | 6 ++- .../LoopUnswitch/2011-11-18-SimpleSwitch.ll | 7 ++- .../2011-11-18-TwoSwitches-Threshold.ll | 7 ++- .../LoopUnswitch/2011-11-18-TwoSwitches.ll | 9 ++-- test/Transforms/LoopUnswitch/infinite-loop.ll | 8 +++- test/Transforms/MemCpyOpt/memcpy.ll | 6 ++- test/Transforms/ObjCARC/apelim.ll | 6 ++- test/Transforms/ObjCARC/basic.ll | 47 ++++++++++--------- test/Transforms/ObjCARC/cfg-hazards.ll | 22 ++++----- test/Transforms/ObjCARC/contract-marker.ll | 4 +- .../ObjCARC/contract-storestrong.ll | 30 ++++++------ test/Transforms/ObjCARC/contract-testcases.ll | 5 +- test/Transforms/ObjCARC/contract.ll | 18 +++---- ...e-that-exception-unwind-path-is-visited.ll | 8 +++- test/Transforms/ObjCARC/escape.ll | 7 ++- test/Transforms/ObjCARC/invoke.ll | 16 ++++--- .../move-and-form-retain-autorelease.ll | 4 +- test/Transforms/ObjCARC/nested.ll | 9 ++-- .../Transforms/ObjCARC/retain-block-alloca.ll | 6 ++- .../ObjCARC/retain-block-side-effects.ll | 5 +- test/Transforms/ObjCARC/retain-block.ll | 26 +++++----- .../Transforms/ObjCARC/retain-not-declared.ll | 4 +- test/Transforms/ObjCARC/rle-s2l.ll | 7 ++- test/Transforms/ObjCARC/rv.ll | 20 ++++---- test/Transforms/ObjCARC/split-backedge.ll | 14 +++--- test/Transforms/ObjCARC/weak-copies.ll | 4 +- test/Transforms/ScalarRepl/phi-cycle.ll | 5 +- .../SimplifyCFG/switch-on-const-select.ll | 9 ++-- 40 files changed, 248 insertions(+), 158 deletions(-) diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 3f32ac18e87..9954a29b3f7 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -554,13 +554,15 @@ void SlotTracker::processFunction() { if (MDNode *N = dyn_cast_or_null(I->getOperand(i))) CreateMetadataSlot(N); - // Add all the call attributes to the table. This is important for - // inline ASM, which may have attributes but no declaration. - if (CI->isInlineAsm()) { - AttributeSet Attrs = CI->getAttributes().getFnAttributes(); - if (Attrs.hasAttributes(AttributeSet::FunctionIndex)) - CreateAttributeSetSlot(Attrs); - } + // Add all the call attributes to the table. + AttributeSet Attrs = CI->getAttributes().getFnAttributes(); + if (Attrs.hasAttributes(AttributeSet::FunctionIndex)) + CreateAttributeSetSlot(Attrs); + } else if (const InvokeInst *II = dyn_cast(I)) { + // Add all the call attributes to the table. + AttributeSet Attrs = II->getAttributes().getFnAttributes(); + if (Attrs.hasAttributes(AttributeSet::FunctionIndex)) + CreateAttributeSetSlot(Attrs); } // Process metadata attached with this instruction. @@ -1935,7 +1937,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } Out << ')'; if (PAL.hasAttributes(AttributeSet::FunctionIndex)) - Out << ' ' << PAL.getAsString(AttributeSet::FunctionIndex); + Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes()); } else if (const InvokeInst *II = dyn_cast(&I)) { Operand = II->getCalledValue(); PointerType *PTy = cast(Operand->getType()); @@ -1975,7 +1977,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ')'; if (PAL.hasAttributes(AttributeSet::FunctionIndex)) - Out << ' ' << PAL.getAsString(AttributeSet::FunctionIndex); + Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes()); Out << "\n to "; writeOperand(II->getNormalDest(), true); diff --git a/test/Analysis/BasicAA/intrinsics.ll b/test/Analysis/BasicAA/intrinsics.ll index 1407efea358..c1cf587204c 100644 --- a/test/Analysis/BasicAA/intrinsics.ll +++ b/test/Analysis/BasicAA/intrinsics.ll @@ -7,7 +7,7 @@ target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32- ; CHECK: define <8 x i16> @test0(i8* noalias %p, i8* noalias %q, <8 x i16> %y) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind +; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) [[ATTR:#[0-9]+]] ; CHECK-NEXT: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) ; CHECK-NEXT: %c = add <8 x i16> %a, %a define <8 x i16> @test0(i8* noalias %p, i8* noalias %q, <8 x i16> %y) { @@ -22,7 +22,7 @@ entry: ; CHECK: define <8 x i16> @test1(i8* %p, <8 x i16> %y) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %q = getelementptr i8* %p, i64 16 -; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind +; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) [[ATTR]] ; CHECK-NEXT: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) ; CHECK-NEXT: %c = add <8 x i16> %a, %a define <8 x i16> @test1(i8* %p, <8 x i16> %y) { @@ -39,4 +39,4 @@ 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 } +; CHECK: attributes [[ATTR]] = { nounwind } diff --git a/test/Analysis/BasicAA/pure-const-dce.ll b/test/Analysis/BasicAA/pure-const-dce.ll index abdd7d3ee67..e48992860a6 100644 --- a/test/Analysis/BasicAA/pure-const-dce.ll +++ b/test/Analysis/BasicAA/pure-const-dce.ll @@ -4,11 +4,11 @@ ; CHECK: @test ; CHECK: entry -; CHECK: %tmp0 = call i32 @TestConst(i32 5) readnone -; CHECK-NEXT: %tmp1 = call i32 @TestPure(i32 6) readonly +; CHECK: %tmp0 = call i32 @TestConst(i32 5) [[READNONE:#[0-9]+]] +; CHECK-NEXT: %tmp1 = call i32 @TestPure(i32 6) [[READONLY:#[0-9]+]] ; CHECK-NEXT: %tmp2 = call i32 @TestNone(i32 7) ; CHECK-NEXT: store i32 1, i32* @g -; CHECK-NEXT: %tmp5 = call i32 @TestPure(i32 6) readonly +; CHECK-NEXT: %tmp5 = call i32 @TestPure(i32 6) [[READONLY]] ; CHECK-NEXT: %tmp7 = call i32 @TestNone(i32 7) ; CHECK-NEXT: %tmp8 = call i32 @TestNone(i32 7) ; CHECK-NEXT: %sum0 = add i32 %tmp0, %tmp1 @@ -50,5 +50,5 @@ declare i32 @TestPure(i32) readonly declare i32 @TestNone(i32) -; CHECK: attributes #0 = { readnone } -; CHECK: attributes #1 = { readonly } +; CHECK: attributes [[READNONE]] = { readnone } +; CHECK: attributes [[READONLY]] = { readonly } diff --git a/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll b/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll index e1d91ca4276..6f1c22da3ac 100644 --- a/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll +++ b/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll @@ -7,7 +7,7 @@ target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32- ; CHECK: define <8 x i16> @test0(i8* %p, i8* %q, <8 x i16> %y) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind +; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) [[NUW:#[0-9]+]] ; CHECK-NEXT: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) ; CHECK-NEXT: %c = add <8 x i16> %a, %a define <8 x i16> @test0(i8* %p, i8* %q, <8 x i16> %y) { @@ -23,7 +23,7 @@ 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 } +; CHECK: attributes [[NUW]] = { nounwind } !0 = metadata !{metadata !"tbaa root", null} !1 = metadata !{metadata !"A", metadata !0} diff --git a/test/Transforms/ArgumentPromotion/2008-02-01-ReturnAttrs.ll b/test/Transforms/ArgumentPromotion/2008-02-01-ReturnAttrs.ll index 2387a10daf7..1226b98a998 100644 --- a/test/Transforms/ArgumentPromotion/2008-02-01-ReturnAttrs.ll +++ b/test/Transforms/ArgumentPromotion/2008-02-01-ReturnAttrs.ll @@ -11,9 +11,9 @@ define i32 @f(i32 %x) { entry: %x_addr = alloca i32 store i32 %x, i32* %x_addr, align 4 -; CHECK: %tmp1 = call i32 @deref(i32 %x_addr.val) nounwind +; CHECK: %tmp1 = call i32 @deref(i32 %x_addr.val) [[NUW:#[0-9]+]] %tmp1 = call i32 @deref( i32* %x_addr ) nounwind ret i32 %tmp1 } -; CHECK: attributes #0 = { nounwind } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll b/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll index 72a269b976b..f049265ce4e 100644 --- a/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll +++ b/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll @@ -4,7 +4,7 @@ @g = global i8 0 -; CHECK: define internal void @foo(i8 signext %y) #0 +; CHECK: define internal void @foo(i8 signext %y) [[NUW:#[0-9]+]] define internal zeroext i8 @foo(i8* inreg %p, i8 signext %y, ... ) nounwind { store i8 %y, i8* @g @@ -12,9 +12,9 @@ define internal zeroext i8 @foo(i8* inreg %p, i8 signext %y, ... ) nounwind { } define i32 @bar() { -; CHECK: call void @foo(i8 signext 1) nounwind +; CHECK: call void @foo(i8 signext 1) [[NUW]] %A = call zeroext i8(i8*, i8, ...)* @foo(i8* inreg null, i8 signext 1, %struct* byval null ) nounwind ret i32 0 } -; CHECK: attributes #0 = { nounwind } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll index fc63da12352..f5d2588dd05 100644 --- a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll +++ b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll @@ -8,7 +8,7 @@ entry: call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !10) call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !11) call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !12) -; CHECK: call fastcc i8* @add_name_internal(i8* %name, i32 %hash) nounwind, !dbg !13 +; CHECK: call fastcc i8* @add_name_internal(i8* %name, i32 %hash) [[NUW:#[0-9]+]], !dbg !13 %0 = call fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext 0, i32 %flags) nounwind, !dbg !13 ; [#uses=1] ret i8* %0, !dbg !13 } @@ -41,6 +41,7 @@ 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 } +; CHECK: attributes [[NUW]] = { nounwind } !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 ] diff --git a/test/Transforms/IPConstantProp/user-with-multiple-uses.ll b/test/Transforms/IPConstantProp/user-with-multiple-uses.ll index ccbd91b4a7d..968718084e4 100644 --- a/test/Transforms/IPConstantProp/user-with-multiple-uses.ll +++ b/test/Transforms/IPConstantProp/user-with-multiple-uses.ll @@ -6,7 +6,7 @@ ; CHECK: define i32 @main() #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: %call2 = tail call i32 @wwrite(i64 0) nounwind +; CHECK-NEXT: %call2 = tail call i32 @wwrite(i64 0) [[NUW:#[0-9]+]] ; CHECK-NEXT: ret i32 123 define i32 @main() noreturn nounwind { @@ -31,3 +31,4 @@ return: ; CHECK: attributes #0 = { noreturn nounwind } ; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/Inline/inline_invoke.ll b/test/Transforms/Inline/inline_invoke.ll index 9f5f670b859..c53bb5aa17b 100644 --- a/test/Transforms/Inline/inline_invoke.ll +++ b/test/Transforms/Inline/inline_invoke.ll @@ -330,7 +330,7 @@ terminate: ; CHECK-NEXT: br label %[[JOIN]] ; CHECK: [[JOIN]]: ; CHECK-NEXT: phi { i8*, i32 } -; CHECK-NEXT: call void @opaque() nounwind +; CHECK-NEXT: call void @opaque() [[NUW:#[0-9]+]] ; CHECK-NEXT: br label %[[FIX:[^\s]+]] ; CHECK: lpad: ; CHECK-NEXT: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0 @@ -340,3 +340,8 @@ terminate: ; CHECK-NEXT: [[T1:%.*]] = phi i32 [ 0, %[[JOIN]] ], [ 1, %lpad ] ; CHECK-NEXT: call void @use(i32 [[T1]]) ; CHECK-NEXT: call void @_ZSt9terminatev() + +; CHECK: attributes [[NUW]] = { nounwind } +; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes #2 = { ssp uwtable } +; CHECK: attributes #3 = { noreturn nounwind } diff --git a/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll b/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll index 0907c490bb3..2dedd44e2be 100644 --- a/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll +++ b/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll @@ -50,7 +50,7 @@ entry: %b = add <4 x i32> zeroinitializer, %a ret <4 x i32> %b ; CHECK: entry: -; CHECK-NEXT: %a = tail call <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16> , <4 x i16> %x) nounwind +; CHECK-NEXT: %a = tail call <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16> , <4 x i16> %x) [[NUW:#[0-9]+]] ; CHECK-NEXT: ret <4 x i32> %a } @@ -66,3 +66,7 @@ entry: declare <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16>, <4 x i16>) nounwind readnone declare <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16>, <4 x i16>) nounwind readnone + +; CHECK: attributes #0 = { nounwind readnone ssp } +; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index 03e26eb67e9..bb07736ef80 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -424,7 +424,7 @@ define i32 @test35() nounwind { i8* getelementptr (%t1* bitcast (%t0* @s to %t1*), i32 0, i32 1, i32 0)) nounwind ret i32 0 ; CHECK: @test35 -; CHECK: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @"\01LC8", i64 0, i64 0), i8* getelementptr inbounds (%t0* @s, i64 0, i32 1, i64 0)) nounwind +; CHECK: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @"\01LC8", i64 0, i64 0), i8* getelementptr inbounds (%t0* @s, i64 0, i32 1, i64 0)) [[NUW:#[0-9]+]] } ; Instcombine should constant-fold the GEP so that indices that have @@ -508,3 +508,5 @@ define void @test39(%struct.ham* %arg, i8 %arg1) nounwind { ; CHECK: getelementptr inbounds %struct.ham* %arg, i64 0, i32 2 ; CHECK: getelementptr inbounds i8* %tmp3, i64 -8 } + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/InstCombine/pow-1.ll b/test/Transforms/InstCombine/pow-1.ll index c8e5f3806f9..8a311f0b74c 100644 --- a/test/Transforms/InstCombine/pow-1.ll +++ b/test/Transforms/InstCombine/pow-1.ll @@ -30,7 +30,7 @@ define double @test_simplify2(double %x) { define float @test_simplify3(float %x) { ; CHECK: @test_simplify3 %retval = call float @powf(float 2.0, float %x) -; CHECK-NEXT: [[EXP2F:%[a-z0-9]+]] = call float @exp2f(float %x) nounwind readonly +; CHECK-NEXT: [[EXP2F:%[a-z0-9]+]] = call float @exp2f(float %x) [[NUW_RO:#[0-9]+]] ret float %retval ; CHECK-NEXT: ret float [[EXP2F]] } @@ -38,7 +38,7 @@ define float @test_simplify3(float %x) { define double @test_simplify4(double %x) { ; CHECK: @test_simplify4 %retval = call double @pow(double 2.0, double %x) -; CHECK-NEXT: [[EXP2:%[a-z0-9]+]] = call double @exp2(double %x) nounwind readonly +; CHECK-NEXT: [[EXP2:%[a-z0-9]+]] = call double @exp2(double %x) [[NUW_RO]] ret double %retval ; CHECK-NEXT: ret double [[EXP2]] } @@ -64,8 +64,8 @@ define double @test_simplify6(double %x) { define float @test_simplify7(float %x) { ; CHECK: @test_simplify7 %retval = call float @powf(float %x, float 0.5) -; CHECK-NEXT: [[SQRTF:%[a-z0-9]+]] = call float @sqrtf(float %x) nounwind readonly -; CHECK-NEXT: [[FABSF:%[a-z0-9]+]] = call float @fabsf(float [[SQRTF]]) nounwind readonly +; CHECK-NEXT: [[SQRTF:%[a-z0-9]+]] = call float @sqrtf(float %x) [[NUW_RO]] +; CHECK-NEXT: [[FABSF:%[a-z0-9]+]] = call float @fabsf(float [[SQRTF]]) [[NUW_RO]] ; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq float %x, 0xFFF0000000000000 ; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], float 0x7FF0000000000000, float [[FABSF]] ret float %retval @@ -75,8 +75,8 @@ define float @test_simplify7(float %x) { define double @test_simplify8(double %x) { ; CHECK: @test_simplify8 %retval = call double @pow(double %x, double 0.5) -; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x) nounwind readonly -; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]]) nounwind readonly +; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x) [[NUW_RO]] +; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]]) [[NUW_RO]] ; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq double %x, 0xFFF0000000000000 ; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], double 0x7FF0000000000000, double [[FABS]] ret double %retval @@ -150,3 +150,5 @@ define double @test_simplify16(double %x) { ret double %retval ; CHECK-NEXT: ret double [[RECIPROCAL]] } + +; CHECK: attributes [[NUW_RO]] = { nounwind readonly } diff --git a/test/Transforms/JumpThreading/basic.ll b/test/Transforms/JumpThreading/basic.ll index 93fa29b006e..fe3dc77c9c1 100644 --- a/test/Transforms/JumpThreading/basic.ll +++ b/test/Transforms/JumpThreading/basic.ll @@ -497,8 +497,8 @@ l2: br label %l3 l3: -; CHECK: call void @g() noduplicate -; CHECK-NOT: call void @g() noduplicate +; CHECK: call void @g() [[NOD:#[0-9]+]] +; CHECK-NOT: call void @g() [[NOD]] call void @g() noduplicate %y = icmp ult i32 %p, 5 br i1 %y, label %l4, label %l5 @@ -512,3 +512,5 @@ l5: ret void ; CHECK: } } + +; CHECK: attributes [[NOD]] = { noduplicate } diff --git a/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll b/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll index 59a8236f132..bde52da87ae 100644 --- a/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll +++ b/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll @@ -19,7 +19,7 @@ ; CHECK-NEXT: i32 1, label %inc.us ; CHECK: inc.us: ; preds = %loop_begin.us -; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: call void @incf() [[NOR_NUW:#[0-9]+]] ; CHECK-NEXT: br label %loop_begin.backedge.us ; CHECK: .split: ; preds = %..split_crit_edge @@ -40,7 +40,7 @@ ; CHECK-NEXT: ] ; CHECK: dec.us3: ; preds = %loop_begin.us1 -; CHECK-NEXT: call void @decf() noreturn nounwind +; CHECK-NEXT: call void @decf() [[NOR_NUW]] ; CHECK-NEXT: br label %loop_begin.backedge.us5 ; CHECK: .split.split: ; preds = %.split..split.split_crit_edge @@ -89,3 +89,6 @@ loop_exit: declare void @incf() noreturn declare void @decf() noreturn + +; CHECK: attributes #0 = { noreturn } +; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } diff --git a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll index 67982feb7e4..c3bf5966ad0 100644 --- a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll +++ b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll @@ -25,7 +25,7 @@ ; CHECK-NEXT: ] ; CHECK: inc.us: ; preds = %second_switch.us, %loop_begin.us -; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: call void @incf() [[NOR_NUW:#[0-9]+]] ; CHECK-NEXT: br label %loop_begin.backedge.us ; CHECK: .split: ; preds = %..split_crit_edge @@ -45,7 +45,7 @@ ; CHECK-NEXT: ] ; CHECK: inc: ; preds = %loop_begin.inc_crit_edge, %second_switch -; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: call void @incf() [[NOR_NUW]] ; CHECK-NEXT: br label %loop_begin.backedge define i32 @test(i32* %var) { @@ -82,3 +82,6 @@ loop_exit: declare void @incf() noreturn declare void @decf() noreturn + +; CHECK: attributes #0 = { noreturn } +; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } diff --git a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll index 36b7effb90a..95303337da5 100644 --- a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll +++ b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll @@ -30,7 +30,7 @@ ; CHECK-NEXT: i32 1, label %inc.us.us ; CHECK: inc.us.us: ; preds = %second_switch.us.us, %loop_begin.us.us -; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: call void @incf() [[NOR_NUW:#[0-9]+]] ; CHECK-NEXT: br label %loop_begin.backedge.us.us ; CHECK: .split.us.split: ; preds = %.split.us..split.us.split_crit_edge @@ -50,7 +50,7 @@ ; CHECK-NEXT: br i1 true, label %us-unreachable8, label %inc.us ; CHECK: inc.us: ; preds = %second_switch.us.inc.us_crit_edge, %loop_begin.us -; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: call void @incf() [[NOR_NUW]] ; CHECK-NEXT: br label %loop_begin.backedge.us ; CHECK: .split: ; preds = %..split_crit_edge @@ -75,7 +75,7 @@ ; CHECK-NEXT: ] ; CHECK: inc.us4: ; preds = %loop_begin.inc_crit_edge.us, %second_switch.us3 -; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: call void @incf() [[NOR_NUW]] ; CHECK-NEXT: br label %loop_begin.backedge.us6 ; CHECK: loop_begin.inc_crit_edge.us: ; preds = %loop_begin.us1 @@ -136,3 +136,6 @@ loop_exit: declare void @incf() noreturn declare void @decf() noreturn + +; CHECK: attributes #0 = { noreturn } +; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } diff --git a/test/Transforms/LoopUnswitch/infinite-loop.ll b/test/Transforms/LoopUnswitch/infinite-loop.ll index 73391ca8d19..f3fba642f81 100644 --- a/test/Transforms/LoopUnswitch/infinite-loop.ll +++ b/test/Transforms/LoopUnswitch/infinite-loop.ll @@ -21,11 +21,11 @@ ; CHECK-NEXT: br label %cond.end.us ; CHECK: abort0.split: -; CHECK-NEXT: call void @end0() noreturn nounwind +; CHECK-NEXT: call void @end0() [[NOR_NUW:#[0-9]+]] ; CHECK-NEXT: unreachable ; CHECK: abort1: -; CHECK-NEXT: call void @end1() noreturn nounwind +; CHECK-NEXT: call void @end1() [[NOR_NUW]] ; CHECK-NEXT: unreachable ; CHECK: } @@ -51,3 +51,7 @@ abort1: declare void @end0() noreturn declare void @end1() noreturn + +; CHECK: attributes #0 = { nounwind } +; CHECK: attributes #1 = { noreturn } +; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } diff --git a/test/Transforms/MemCpyOpt/memcpy.ll b/test/Transforms/MemCpyOpt/memcpy.ll index 3fbc559ccff..582a57b5d39 100644 --- a/test/Transforms/MemCpyOpt/memcpy.ll +++ b/test/Transforms/MemCpyOpt/memcpy.ll @@ -123,7 +123,7 @@ entry: %call = call i32 @g(%struct.p* align 8 byval %agg.tmp) nounwind ret i32 %call ; CHECK: @test7 -; CHECK: call i32 @g(%struct.p* byval align 8 %q) nounwind +; CHECK: call i32 @g(%struct.p* byval align 8 %q) [[NUW:#[0-9]+]] } declare i32 @g(%struct.p* align 8 byval) @@ -170,3 +170,7 @@ entry: declare void @f1(%struct.big* sret) declare void @f2(%struct.big*) + +; CHECK: attributes [[NUW]] = { nounwind } +; CHECK: attributes #1 = { nounwind ssp } +; CHECK: attributes #2 = { nounwind ssp uwtable } diff --git a/test/Transforms/ObjCARC/apelim.ll b/test/Transforms/ObjCARC/apelim.ll index 8c7b5b1e654..4541b3f2fdf 100644 --- a/test/Transforms/ObjCARC/apelim.ll +++ b/test/Transforms/ObjCARC/apelim.ll @@ -38,8 +38,8 @@ entry: } ; CHECK: define internal void @_GLOBAL__I_y() -; CHECK: %0 = call i8* @objc_autoreleasePoolPush() nounwind -; CHECK: call void @objc_autoreleasePoolPop(i8* %0) nounwind +; CHECK: %0 = call i8* @objc_autoreleasePoolPush() [[NUW:#[0-9]+]] +; CHECK: call void @objc_autoreleasePoolPop(i8* %0) [[NUW]] ; CHECK: } define internal void @_GLOBAL__I_y() { entry: @@ -51,3 +51,5 @@ entry: declare i8* @objc_autoreleasePoolPush() declare void @objc_autoreleasePoolPop(i8*) + +; CHECK: attributes #0 = { nounwind } diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll index 4faffa55e7d..4c24ebf8652 100644 --- a/test/Transforms/ObjCARC/basic.ll +++ b/test/Transforms/ObjCARC/basic.ll @@ -92,10 +92,10 @@ alt_return: ; CHECK: define void @test1b( ; CHECK: entry: -; CHECK: tail call i8* @objc_retain(i8* %x) nounwind +; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW:#[0-9]+]] ; CHECK-NOT: @objc_ ; CHECK: if.end5: -; CHECK: tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 +; CHECK: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release !0 ; CHECK-NOT: @objc_ ; CHECK: } define void @test1b(i8* %x, i1 %p, i1 %q) { @@ -404,8 +404,8 @@ entry: ; a stack argument. ; CHECK: define void @test11( -; CHECK: tail call i8* @objc_retain(i8* %x) nounwind -; CHECK: call i8* @objc_autorelease(i8* %0) nounwind +; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] +; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]] ; CHECK: } define void @test11(i8* %x) nounwind { entry: @@ -431,8 +431,8 @@ entry: ; Same as test11 but the value is returned. Do an RV optimization. ; CHECK: define i8* @test11b( -; CHECK: tail call i8* @objc_retain(i8* %x) nounwind -; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %0) nounwind +; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] +; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %0) [[NUW]] ; CHECK: } define i8* @test11b(i8* %x) nounwind { entry: @@ -462,10 +462,10 @@ entry: ; Trivial retain,autorelease pair. Don't delete! ; CHECK: define void @test13( -; CHECK: tail call i8* @objc_retain(i8* %x) nounwind -; CHECK: tail call i8* @objc_retain(i8* %x) nounwind +; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] +; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] ; CHECK: @use_pointer(i8* %x) -; CHECK: call i8* @objc_autorelease(i8* %x) nounwind +; CHECK: call i8* @objc_autorelease(i8* %x) [[NUW]] ; CHECK: } define void @test13(i8* %x, i64 %n) { entry: @@ -716,7 +716,7 @@ entry: ; Bitcast insertion ; CHECK: define void @test20( -; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) nounwind +; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) [[NUW]] ; CHECK-NEXT: invoke define void @test20(double* %self) { if.then12: @@ -980,7 +980,7 @@ done: ; CHECK: call i8* @objc_retain( ; CHECK: call void @callee() ; CHECK: store -; CHECK: call void @objc_release(i8* %p) nounwind, !clang.imprecise_release +; CHECK: call void @objc_release(i8* %p) [[NUW]], !clang.imprecise_release ; CHECK: done: ; CHECK-NOT: @objc_ ; CHECK: } @@ -1450,9 +1450,9 @@ define void @test45(i8** %pp, i8** %qq) { ; Don't delete retain and autorelease here. ; CHECK: define void @test46( -; CHECK: tail call i8* @objc_retain(i8* %p) nounwind +; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]] ; CHECK: true: -; CHECK: call i8* @objc_autorelease(i8* %p) nounwind +; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]] define void @test46(i8* %p, i1 %a) { entry: call i8* @objc_retain(i8* %p) @@ -1565,7 +1565,7 @@ define void @test53(void ()** %zz, i8** %pp) { ; CHECK: define void @test54( ; CHECK: call i8* @returner() -; CHECK-NEXT: call void @objc_release(i8* %t) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: call void @objc_release(i8* %t) [[NUW]], !clang.imprecise_release !0 ; CHECK-NEXT: ret void define void @test54() { %t = call i8* @returner() @@ -1595,10 +1595,10 @@ entry: ; CHECK: define void @test56( ; CHECK-NOT: @objc ; CHECK: if.then: -; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]] ; CHECK-NEXT: tail call void @use_pointer(i8* %x) ; CHECK-NEXT: tail call void @use_pointer(i8* %x) -; CHECK-NEXT: tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release !0 ; CHECK-NEXT: br label %if.end ; CHECK-NOT: @objc ; CHECK: } @@ -1630,10 +1630,10 @@ if.end: ; preds = %entry, %if.then ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @use_pointer(i8* %x) ; CHECK-NEXT: call void @use_pointer(i8* %x) -; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]] ; CHECK-NEXT: call void @use_pointer(i8* %x) ; CHECK-NEXT: call void @use_pointer(i8* %x) -; CHECK-NEXT: call void @objc_release(i8* %x) nounwind +; CHECK-NEXT: call void @objc_release(i8* %x) [[NUW]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test57(i8* %x) nounwind { @@ -1673,10 +1673,10 @@ entry: ; CHECK: define void @test59( ; CHECK-NEXT: entry: -; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]] ; CHECK-NEXT: call void @use_pointer(i8* %x) ; CHECK-NEXT: call void @use_pointer(i8* %x) -; CHECK-NEXT: call void @objc_release(i8* %x) nounwind +; CHECK-NEXT: call void @objc_release(i8* %x) [[NUW]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test59(i8* %x) nounwind { @@ -1875,8 +1875,8 @@ return: ; preds = %if.then, %entry ; rdar://11931823 ; CHECK: define void @test66( -; CHECK: %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind -; CHECK: tail call void @objc_release(i8* %cond) nounwind +; CHECK: %tmp7 = tail call i8* @objc_retain(i8* %cond) [[NUW]] +; CHECK: tail call void @objc_release(i8* %cond) [[NUW]] ; CHECK: } define void @test66(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) { entry: @@ -2224,3 +2224,6 @@ end: ; preds = %if.end125, %if.end1 !0 = metadata !{} declare i32 @__gxx_personality_v0(...) + +; CHECK: attributes #0 = { nounwind readnone } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/cfg-hazards.ll b/test/Transforms/ObjCARC/cfg-hazards.ll index 58832b6700e..899298b5967 100644 --- a/test/Transforms/ObjCARC/cfg-hazards.ll +++ b/test/Transforms/ObjCARC/cfg-hazards.ll @@ -88,7 +88,7 @@ for.end: ; preds = %for.body ; CHECK: define void @test3(i8* %a) #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW:#[0-9]+]] ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ ; CHECK: exit: @@ -114,7 +114,7 @@ exit: ; CHECK: define void @test4(i8* %a) #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ ; CHECK: exit: @@ -144,7 +144,7 @@ exit: ; CHECK: define void @test5(i8* %a) #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] ; CHECK-NEXT: call void @callee() ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ @@ -178,7 +178,7 @@ exit: ; CHECK: define void @test6(i8* %a) #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ ; CHECK: exit: @@ -211,7 +211,7 @@ exit: ; CHECK: define void @test7(i8* %a) #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] ; CHECK-NEXT: call void @callee() ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ @@ -244,7 +244,7 @@ exit: ; CHECK: define void @test8(i8* %a) #0 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ ; CHECK: exit: @@ -364,13 +364,13 @@ exit: ; 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 +; CHECK-NEXT: %outer = tail call i8* @objc_retain(i8* %a) [[NUW]] +; CHECK-NEXT: %inner = tail call i8* @objc_retain(i8* %a) [[NUW]] ; CHECK-NEXT: br label %loop ; CHECK-NOT: @objc_ ; CHECK: exit: -; CHECK-NEXT: call void @objc_release(i8* %a) nounwind -; CHECK-NEXT: call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: call void @objc_release(i8* %a) [[NUW]] +; CHECK-NEXT: call void @objc_release(i8* %a) [[NUW]], !clang.imprecise_release !0 ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test12(i8* %a) nounwind { @@ -394,6 +394,6 @@ exit: ret void } -; CHECK: attributes #0 = { nounwind } +; CHECK: attributes [[NUW]] = { nounwind } !0 = metadata !{} diff --git a/test/Transforms/ObjCARC/contract-marker.ll b/test/Transforms/ObjCARC/contract-marker.ll index 01d978a0e21..01fd1e71436 100644 --- a/test/Transforms/ObjCARC/contract-marker.ll +++ b/test/Transforms/ObjCARC/contract-marker.ll @@ -3,7 +3,7 @@ ; CHECK: %call = tail call i32* @qux() ; CHECK-NEXT: %tcall = bitcast i32* %call to i8* ; CHECK-NEXT: call void asm sideeffect "mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue", ""() -; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %tcall) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %tcall) [[NUW:#[0-9]+]] define void @foo() { entry: @@ -21,3 +21,5 @@ declare void @bar(i8*) !clang.arc.retainAutoreleasedReturnValueMarker = !{!0} !0 = metadata !{metadata !"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"} + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/contract-storestrong.ll b/test/Transforms/ObjCARC/contract-storestrong.ll index 2922f816d58..6999237300e 100644 --- a/test/Transforms/ObjCARC/contract-storestrong.ll +++ b/test/Transforms/ObjCARC/contract-storestrong.ll @@ -10,7 +10,7 @@ declare void @use_pointer(i8*) ; CHECK: define void @test0( ; CHECK: entry: -; CHECK-NEXT: tail call void @objc_storeStrong(i8** @x, i8* %p) nounwind +; CHECK-NEXT: tail call void @objc_storeStrong(i8** @x, i8* %p) [[NUW:#[0-9]+]] ; CHECK-NEXT: ret void define void @test0(i8* %p) { entry: @@ -25,10 +25,10 @@ entry: ; CHECK: define void @test1(i8* %p) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) [[NUW]] ; CHECK-NEXT: %tmp = load volatile i8** @x, align 8 ; CHECK-NEXT: store i8* %0, i8** @x, align 8 -; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind +; CHECK-NEXT: tail call void @objc_release(i8* %tmp) [[NUW]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test1(i8* %p) { @@ -44,10 +44,10 @@ entry: ; CHECK: define void @test2(i8* %p) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) [[NUW]] ; CHECK-NEXT: %tmp = load i8** @x, align 8 ; CHECK-NEXT: store volatile i8* %0, i8** @x, align 8 -; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind +; CHECK-NEXT: tail call void @objc_release(i8* %tmp) [[NUW]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test2(i8* %p) { @@ -64,11 +64,11 @@ entry: ; CHECK: define void @test3(i8* %newValue) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind +; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) [[NUW]] ; CHECK-NEXT: %x1 = load i8** @x, align 8 ; CHECK-NEXT: store i8* %x0, i8** @x, align 8 ; CHECK-NEXT: tail call void @use_pointer(i8* %x1), !clang.arc.no_objc_arc_exceptions !0 -; CHECK-NEXT: tail call void @objc_release(i8* %x1) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: tail call void @objc_release(i8* %x1) [[NUW]], !clang.imprecise_release !0 ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test3(i8* %newValue) { @@ -85,11 +85,11 @@ entry: ; CHECK: define i1 @test4(i8* %newValue, i8* %foo) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind +; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) [[NUW]] ; CHECK-NEXT: %x1 = load i8** @x, align 8 ; CHECK-NEXT: store i8* %x0, i8** @x, align 8 ; CHECK-NEXT: %t = icmp eq i8* %x1, %foo -; CHECK-NEXT: tail call void @objc_release(i8* %x1) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: tail call void @objc_release(i8* %x1) [[NUW]], !clang.imprecise_release !0 ; CHECK-NEXT: ret i1 %t ; CHECK-NEXT: } define i1 @test4(i8* %newValue, i8* %foo) { @@ -106,7 +106,7 @@ entry: ; CHECK: define i1 @test5(i8* %newValue, i8* %foo) { ; CHECK: %t = icmp eq i8* %x1, %foo -; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) nounwind +; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) [[NUW]] define i1 @test5(i8* %newValue, i8* %foo) { entry: %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind @@ -121,7 +121,7 @@ entry: ; CHECK: define i1 @test6(i8* %newValue, i8* %foo) { ; CHECK: %t = icmp eq i8* %x1, %foo -; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) nounwind +; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) [[NUW]] define i1 @test6(i8* %newValue, i8* %foo) { entry: %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind @@ -136,9 +136,9 @@ entry: ; CHECK: define void @test7( ; CHECK-NEXT: entry: -; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) [[NUW]] ; CHECK-NEXT: %tmp = load i8** @x, align 8 -; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind +; CHECK-NEXT: tail call void @objc_release(i8* %tmp) [[NUW]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test7(i8* %p) { @@ -155,7 +155,7 @@ entry: ; CHECK-NEXT: entry: ; CHECK-NEXT: %tmp = load i8** @x, align 8 ; CHECK-NEXT: store i8* %p, i8** @x, align 8 -; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind +; CHECK-NEXT: tail call void @objc_release(i8* %tmp) [[NUW]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @test8(i8* %p) { @@ -167,3 +167,5 @@ entry: } !0 = metadata !{} + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/contract-testcases.ll b/test/Transforms/ObjCARC/contract-testcases.ll index 1510ed00e69..85b03be275e 100644 --- a/test/Transforms/ObjCARC/contract-testcases.ll +++ b/test/Transforms/ObjCARC/contract-testcases.ll @@ -69,7 +69,7 @@ bb7: ; preds = %bb6, %bb6, %bb5 ; CHECK: define void @_Z6doTestP8NSString() { ; CHECK: invoke.cont: ; preds = %entry ; CHECK-NEXT: call void asm sideeffect "mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue", ""() -; CHECK-NEXT: %tmp = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind +; CHECK-NEXT: %tmp = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) [[NUW:#[0-9]+]] define void @_Z6doTestP8NSString() { entry: %call = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* ()*)() @@ -88,3 +88,6 @@ lpad: ; preds = %entry !clang.arc.retainAutoreleasedReturnValueMarker = !{!0} !0 = metadata !{metadata !"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"} + +; CHECK: attributes #0 = { optsize } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/contract.ll b/test/Transforms/ObjCARC/contract.ll index 40b11a9d0e2..b6fba596034 100644 --- a/test/Transforms/ObjCARC/contract.ll +++ b/test/Transforms/ObjCARC/contract.ll @@ -34,7 +34,7 @@ entry: ; Merge objc_retain and objc_autorelease into objc_retainAutorelease. ; CHECK: define void @test2( -; CHECK: tail call i8* @objc_retainAutorelease(i8* %x) nounwind +; CHECK: tail call i8* @objc_retainAutorelease(i8* %x) [[NUW:#[0-9]+]] ; CHECK: } define void @test2(i8* %x) nounwind { entry: @@ -47,7 +47,7 @@ entry: ; Same as test2 but the value is returned. Do an RV optimization. ; CHECK: define i8* @test2b( -; CHECK: tail call i8* @objc_retainAutoreleaseReturnValue(i8* %x) nounwind +; CHECK: tail call i8* @objc_retainAutoreleaseReturnValue(i8* %x) [[NUW]] ; CHECK: } define i8* @test2b(i8* %x) nounwind { entry: @@ -59,7 +59,7 @@ entry: ; Merge a retain,autorelease pair around a call. ; CHECK: define void @test3( -; CHECK: tail call i8* @objc_retainAutorelease(i8* %x) nounwind +; CHECK: tail call i8* @objc_retainAutorelease(i8* %x) [[NUW]] ; CHECK: @use_pointer(i8* %0) ; CHECK: } define void @test3(i8* %x, i64 %n) { @@ -75,7 +75,7 @@ entry: ; CHECK: define void @test4( ; CHECK-NEXT: entry: -; CHECK-NEXT: @objc_retainAutorelease(i8* %x) nounwind +; CHECK-NEXT: @objc_retainAutorelease(i8* %x) [[NUW]] ; CHECK-NEXT: @use_pointer ; CHECK-NEXT: @objc_release ; CHECK-NEXT: ret void @@ -92,9 +92,9 @@ entry: ; Don't merge retain and autorelease if they're not control-equivalent. ; CHECK: define void @test5( -; CHECK: tail call i8* @objc_retain(i8* %p) nounwind +; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]] ; CHECK: true: -; CHECK: call i8* @objc_autorelease(i8* %0) nounwind +; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]] ; CHECK: } define void @test5(i8* %p, i1 %a) { entry: @@ -119,8 +119,8 @@ false: ; Those entrypoints don't exist yet though. ; CHECK: define i8* @test6( -; CHECK: call i8* @objc_retainAutoreleasedReturnValue(i8* %p) nounwind -; CHECK: %t = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind +; CHECK: call i8* @objc_retainAutoreleasedReturnValue(i8* %p) [[NUW]] +; CHECK: %t = tail call i8* @objc_autoreleaseReturnValue(i8* %1) [[NUW]] ; CHECK: } define i8* @test6() { %p = call i8* @returner() @@ -161,3 +161,5 @@ return: ; preds = %if.then, %entry %retval = phi i8* [ %c, %if.then ], [ null, %entry ] ret i8* %retval } + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll b/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll index 1fd03e7d9c6..05257d1d5cf 100644 --- a/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll +++ b/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll @@ -42,7 +42,7 @@ entry: ; CHECK: call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp2, i8* %tmp1) %call = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp2, i8* %tmp1), !dbg !37, !clang.arc.no_objc_arc_exceptions !38 call void @llvm.dbg.value(metadata !{i8* %call}, i64 0, metadata !12), !dbg !37 -; CHECK: call i8* @objc_retain(i8* %call) nounwind +; CHECK: call i8* @objc_retain(i8* %call) [[NUW:#[0-9]+]] %tmp3 = call i8* @objc_retain(i8* %call) nounwind, !dbg !39 call void @llvm.dbg.value(metadata !{i8* %call}, i64 0, metadata !25), !dbg !39 invoke fastcc void @ThrowFunc(i8* %call) @@ -104,6 +104,12 @@ declare void @NSLog(i8*, ...) declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone +; CHECK: attributes #0 = { ssp uwtable } +; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes #2 = { nonlazybind } +; CHECK: attributes #3 = { noinline ssp uwtable } +; CHECK: attributes [[NUW]] = { nounwind } + !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!33, !34, !35, !36} diff --git a/test/Transforms/ObjCARC/escape.ll b/test/Transforms/ObjCARC/escape.ll index 3f694cf1d5a..8f252a0d343 100644 --- a/test/Transforms/ObjCARC/escape.ll +++ b/test/Transforms/ObjCARC/escape.ll @@ -10,8 +10,8 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 ; with the objc_storeWeak call. ; CHECK: define void @test0( -; CHECK: %tmp7 = call i8* @objc_retainBlock(i8* %tmp6) nounwind, !clang.arc.copy_on_escape !0 -; CHECK: call void @objc_release(i8* %tmp7) nounwind, !clang.imprecise_release !0 +; CHECK: %tmp7 = call i8* @objc_retainBlock(i8* %tmp6) [[NUW:#[0-9]+]], !clang.arc.copy_on_escape !0 +; CHECK: call void @objc_release(i8* %tmp7) [[NUW]], !clang.imprecise_release !0 ; CHECK: } define void @test0() nounwind { entry: @@ -129,3 +129,6 @@ declare i8* @not_really_objc_storeWeak(i8**, i8*) declare void @objc_release(i8*) !0 = metadata !{} + +; CHECK: attributes [[NUW]] = { nounwind } +; CHECK: attributes #1 = { nounwind ssp } diff --git a/test/Transforms/ObjCARC/invoke.ll b/test/Transforms/ObjCARC/invoke.ll index 1a58e34940e..f528b4ac35b 100644 --- a/test/Transforms/ObjCARC/invoke.ll +++ b/test/Transforms/ObjCARC/invoke.ll @@ -12,10 +12,10 @@ declare i8* @returner() ; CHECK: define void @test0( ; CHECK: invoke.cont: -; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 +; CHECK: call void @objc_release(i8* %zipFile) [[NUW:#[0-9]+]], !clang.imprecise_release !0 ; CHECK: ret void ; CHECK: lpad: -; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 +; CHECK: call void @objc_release(i8* %zipFile) [[NUW]], !clang.imprecise_release !0 ; CHECK: ret void define void @test0(i8* %zipFile) { entry: @@ -39,11 +39,11 @@ lpad: ; preds = %entry ; CHECK: define void @test1( ; CHECK: invoke.cont: -; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 +; CHECK: call void @objc_release(i8* %zipFile) [[NUW]], !clang.imprecise_release !0 ; CHECK: call void @callee() ; CHECK: br label %done ; CHECK: lpad: -; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 +; CHECK: call void @objc_release(i8* %zipFile) [[NUW]], !clang.imprecise_release !0 ; CHECK: call void @callee() ; CHECK: br label %done ; CHECK: done: @@ -108,7 +108,7 @@ finally.rethrow: ; preds = %invoke.cont, %entry ; CHECK: define void @test3( ; CHECK: if.end: -; CHECK-NEXT: call void @objc_release(i8* %p) nounwind +; CHECK-NEXT: call void @objc_release(i8* %p) [[NUW]] ; CHECK-NEXT: ret void define void @test3(i8* %p, i1 %b) { entry: @@ -140,10 +140,10 @@ if.end: ; CHECK: lpad: ; CHECK-NEXT: %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) ; CHECK-NEXT: cleanup -; CHECK-NEXT: call void @objc_release(i8* %p) nounwind +; CHECK-NEXT: call void @objc_release(i8* %p) [[NUW]] ; CHECK-NEXT: ret void ; CHECK: if.end: -; CHECK-NEXT: call void @objc_release(i8* %p) nounwind +; CHECK-NEXT: call void @objc_release(i8* %p) [[NUW]] ; CHECK-NEXT: ret void define void @test4(i8* %p, i1 %b) { entry: @@ -215,4 +215,6 @@ if.end: declare i32 @__gxx_personality_v0(...) declare i32 @__objc_personality_v0(...) +; CHECK: attributes [[NUW]] = { nounwind } + !0 = metadata !{} diff --git a/test/Transforms/ObjCARC/move-and-form-retain-autorelease.ll b/test/Transforms/ObjCARC/move-and-form-retain-autorelease.ll index d7a54ab4308..5d058257c6e 100644 --- a/test/Transforms/ObjCARC/move-and-form-retain-autorelease.ll +++ b/test/Transforms/ObjCARC/move-and-form-retain-autorelease.ll @@ -4,7 +4,7 @@ ; and various scary looking things and fold it into an objc_retainAutorelease. ; CHECK: bb57: -; CHECK: tail call i8* @objc_retainAutorelease(i8* %tmp71x) nounwind +; CHECK: tail call i8* @objc_retainAutorelease(i8* %tmp71x) [[NUW:#[0-9]+]] ; CHECK: bb99: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -219,3 +219,5 @@ bb104: ; preds = %bb99, %bb57 tail call void @objc_release(i8* %tmp107) nounwind ret %14* %tmp106 } + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/nested.ll b/test/Transforms/ObjCARC/nested.ll index 32be03ec6ae..ca9c58bcb3e 100644 --- a/test/Transforms/ObjCARC/nested.ll +++ b/test/Transforms/ObjCARC/nested.ll @@ -770,9 +770,9 @@ forcoll.empty: @__block_d_tmp5 = external hidden constant { i64, i64, i8*, i8*, i8*, i8* } ; CHECK: define void @test11( -; CHECK: tail call i8* @objc_retain(i8* %call) nounwind -; CHECK: tail call i8* @objc_retain(i8* %call) nounwind -; CHECK: call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0 +; CHECK: tail call i8* @objc_retain(i8* %call) [[NUW:#[0-9]+]] +; CHECK: tail call i8* @objc_retain(i8* %call) [[NUW]] +; CHECK: call void @objc_release(i8* %call) [[NUW]], !clang.imprecise_release !0 ; CHECK: } define void @test11() { entry: @@ -820,3 +820,6 @@ entry: call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0 ret void } + +; CHECK: attributes [[NUW]] = { nounwind } +; CHECK: attributes #1 = { nonlazybind } diff --git a/test/Transforms/ObjCARC/retain-block-alloca.ll b/test/Transforms/ObjCARC/retain-block-alloca.ll index 01f208704c7..f40be238baf 100644 --- a/test/Transforms/ObjCARC/retain-block-alloca.ll +++ b/test/Transforms/ObjCARC/retain-block-alloca.ll @@ -9,7 +9,7 @@ @"\01L_OBJC_SELECTOR_REFERENCES_" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" ; CHECK: define void @test( -; CHECK: %3 = call i8* @objc_retainBlock(i8* %2) nounwind +; CHECK: %3 = call i8* @objc_retainBlock(i8* %2) [[NUW:#[0-9]+]] ; CHECK: @objc_msgSend ; CHECK-NEXT: @objc_release(i8* %3) define void @test(%0* %array) uwtable { @@ -87,4 +87,8 @@ declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind declare void @objc_release(i8*) +; CHECK: attributes #0 = { uwtable } +; CHECK: attributes #1 = { nonlazybind } +; CHECK: attributes [[NUW]] = { nounwind } + !0 = metadata !{} diff --git a/test/Transforms/ObjCARC/retain-block-side-effects.ll b/test/Transforms/ObjCARC/retain-block-side-effects.ll index e84d48f8691..7fa73cbfef1 100644 --- a/test/Transforms/ObjCARC/retain-block-side-effects.ll +++ b/test/Transforms/ObjCARC/retain-block-side-effects.ll @@ -4,7 +4,7 @@ ; objc_retainBlock stores into %repeater so the load from after the ; call isn't forwardable from the store before the call. -; CHECK: %tmp16 = call i8* @objc_retainBlock(i8* %tmp15) nounwind +; CHECK: %tmp16 = call i8* @objc_retainBlock(i8* %tmp15) [[NUW:#[0-9]+]] ; CHECK: %tmp17 = bitcast i8* %tmp16 to void ()* ; CHECK: %tmp18 = load %struct.__block_byref_repeater** %byref.forwarding, align 8 ; CHECK: %repeater12 = getelementptr inbounds %struct.__block_byref_repeater* %tmp18, i64 0, i32 6 @@ -37,3 +37,6 @@ entry: } declare i8* @objc_retainBlock(i8*) + +; CHECK: attributes #0 = { noreturn } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/retain-block.ll b/test/Transforms/ObjCARC/retain-block.ll index b3b62d30000..ee57049d8aa 100644 --- a/test/Transforms/ObjCARC/retain-block.ll +++ b/test/Transforms/ObjCARC/retain-block.ll @@ -28,8 +28,8 @@ entry: ; optimization possible. ; CHECK: define void @test0_no_metadata(i8* %tmp) { -; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind -; CHECK: tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0 +; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) [[NUW:#[0-9]+]] +; CHECK: tail call void @objc_release(i8* %tmp2) [[NUW]], !clang.imprecise_release !0 ; CHECK: } define void @test0_no_metadata(i8* %tmp) { entry: @@ -43,8 +43,8 @@ entry: ; optimization possible. ; CHECK: define void @test0_escape(i8* %tmp, i8** %z) { -; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0 -; CHECK: tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0 +; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) [[NUW]], !clang.arc.copy_on_escape !0 +; CHECK: tail call void @objc_release(i8* %tmp2) [[NUW]], !clang.imprecise_release !0 ; CHECK: } define void @test0_escape(i8* %tmp, i8** %z) { entry: @@ -58,8 +58,8 @@ entry: ; Same as test0_escape, but there's no intervening call. ; CHECK: define void @test0_just_escape(i8* %tmp, i8** %z) { -; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0 -; CHECK: tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0 +; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) [[NUW]], !clang.arc.copy_on_escape !0 +; CHECK: tail call void @objc_release(i8* %tmp2) [[NUW]], !clang.imprecise_release !0 ; CHECK: } define void @test0_just_escape(i8* %tmp, i8** %z) { entry: @@ -73,9 +73,9 @@ entry: ; CHECK: define void @test1(i8* %tmp) { ; CHECK-NOT: @objc -; CHECK: tail call i8* @objc_retain(i8* %tmp) nounwind +; CHECK: tail call i8* @objc_retain(i8* %tmp) [[NUW]] ; CHECK-NOT: @objc -; CHECK: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0 +; CHECK: tail call void @objc_release(i8* %tmp) [[NUW]], !clang.imprecise_release !0 ; CHECK-NOT: @objc ; CHECK: } define void @test1(i8* %tmp) { @@ -95,10 +95,10 @@ entry: ; CHECK: define void @test1_no_metadata(i8* %tmp) { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call i8* @objc_retainBlock(i8* %tmp) nounwind +; CHECK-NEXT: tail call i8* @objc_retainBlock(i8* %tmp) [[NUW]] ; CHECK-NEXT: @use_pointer(i8* %tmp2) ; CHECK-NEXT: @use_pointer(i8* %tmp2) -; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: tail call void @objc_release(i8* %tmp) [[NUW]], !clang.imprecise_release !0 ; CHECK-NOT: @objc ; CHECK: } define void @test1_no_metadata(i8* %tmp) { @@ -118,11 +118,11 @@ entry: ; CHECK: define void @test1_escape(i8* %tmp, i8** %z) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0 +; CHECK-NEXT: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) [[NUW]], !clang.arc.copy_on_escape !0 ; CHECK-NEXT: store i8* %tmp2, i8** %z ; CHECK-NEXT: @use_pointer(i8* %tmp2) ; CHECK-NEXT: @use_pointer(i8* %tmp2) -; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: tail call void @objc_release(i8* %tmp) [[NUW]], !clang.imprecise_release !0 ; CHECK-NOT: @objc ; CHECK: } define void @test1_escape(i8* %tmp, i8** %z) { @@ -136,3 +136,5 @@ entry: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0 ret void } + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/retain-not-declared.ll b/test/Transforms/ObjCARC/retain-not-declared.ll index f876e51592b..e834179bb71 100644 --- a/test/Transforms/ObjCARC/retain-not-declared.ll +++ b/test/Transforms/ObjCARC/retain-not-declared.ll @@ -13,7 +13,7 @@ declare void @objc_release(i8*) ; CHECK: define i8* @test0(i8* %p) { ; CHECK-NEXT: entry: -; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %p) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %p) [[NUW:#[0-9]+]] ; CHECK-NEXT: ret i8* %0 ; CHECK-NEXT: } @@ -65,3 +65,5 @@ lpad100: ; preds = %invoke.cont93 declare i32 @__gxx_personality_v0(...) !0 = metadata !{} + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/rle-s2l.ll b/test/Transforms/ObjCARC/rle-s2l.ll index 8f8d5c0d382..2865c94dc88 100644 --- a/test/Transforms/ObjCARC/rle-s2l.ll +++ b/test/Transforms/ObjCARC/rle-s2l.ll @@ -57,7 +57,7 @@ define void @test2(i8** %p) { ; CHECK: define void @test3(i8** %p) { ; CHECK-NEXT: %x = call i8* @objc_loadWeak(i8** %p) -; CHECK-NEXT: call void @use_pointer(i8* %x) readonly +; CHECK-NEXT: call void @use_pointer(i8* %x) [[RO:#[0-9]+]] ; CHECK-NEXT: %1 = tail call i8* @objc_retain(i8* %x) ; CHECK-NEXT: call void @use_pointer(i8* %x) ; CHECK-NEXT: ret void @@ -74,7 +74,7 @@ define void @test3(i8** %p) { ; CHECK: define void @test4(i8** %p) { ; CHECK-NEXT: %x = call i8* @objc_loadWeak(i8** %p) -; CHECK-NEXT: call void @use_pointer(i8* %x) readonly +; CHECK-NEXT: call void @use_pointer(i8* %x) [[RO]] ; CHECK-NEXT: call void @callee() ; CHECK-NEXT: %y = call i8* @objc_loadWeak(i8** %p) ; CHECK-NEXT: call void @use_pointer(i8* %y) @@ -133,3 +133,6 @@ define void @test7(i8** %p, i8* %n, i8** %q, i8* %m) { call void @use_pointer(i8* %y) ret void } + +; CHECK: attributes #0 = { nounwind } +; CHECK: attributes [[RO]] = { readonly } diff --git a/test/Transforms/ObjCARC/rv.ll b/test/Transforms/ObjCARC/rv.ll index 638b89ccc72..a2fef967495 100644 --- a/test/Transforms/ObjCARC/rv.ll +++ b/test/Transforms/ObjCARC/rv.ll @@ -29,7 +29,7 @@ declare i8* @returner() ; CHECK: define void @test0( ; CHECK-NEXT: entry: ; CHECK-NEXT: %x = call i8* @returner -; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %x) nounwind +; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %x) [[NUW:#[0-9]+]] ; CHECK: t: ; CHECK-NOT: @objc_ ; CHECK: return: @@ -159,8 +159,8 @@ define i8* @test9(i8* %p) { ; Apply the RV optimization. ; CHECK: define i8* @test10(i8* %p) -; CHECK: tail call i8* @objc_retain(i8* %p) nounwind -; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p) nounwind +; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]] +; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p) [[NUW]] ; CHECK-NEXT: ret i8* %p define i8* @test10(i8* %p) { %1 = call i8* @objc_retain(i8* %p) @@ -215,7 +215,7 @@ define i8* @test13() { ; argument is not a return value. ; CHECK: define void @test14( -; CHECK-NEXT: tail call i8* @objc_retain(i8* %p) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %p) [[NUW]] ; CHECK-NEXT: ret void define void @test14(i8* %p) { call i8* @objc_retainAutoreleasedReturnValue(i8* %p) @@ -227,7 +227,7 @@ define void @test14(i8* %p) { ; CHECK: define void @test15( ; CHECK-NEXT: %y = call i8* @returner() -; CHECK-NEXT: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %y) nounwind +; CHECK-NEXT: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %y) [[NUW]] ; CHECK-NEXT: ret void define void @test15() { %y = call i8* @returner() @@ -240,7 +240,7 @@ define void @test15() { ; CHECK: define void @test16( ; CHECK-NEXT: %y = call i8* @returner() -; CHECK-NEXT: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %y) nounwind +; CHECK-NEXT: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %y) [[NUW]] ; CHECK-NEXT: ret void define void @test16() { %y = call i8* @returner() @@ -252,7 +252,7 @@ define void @test16() { ; argument is not a return value. ; CHECK: define void @test17( -; CHECK-NEXT: tail call i8* @objc_retain(i8* %y) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %y) [[NUW]] ; CHECK-NEXT: ret void define void @test17(i8* %y) { call i8* @objc_retain(i8* %y) @@ -265,7 +265,7 @@ define void @test17(i8* %y) { ; CHECK: define void @test18( ; CHECK-NEXT: %y = call i8* @returner() ; CHECK-NEXT: call void @callee() -; CHECK-NEXT: tail call i8* @objc_retain(i8* %y) nounwind +; CHECK-NEXT: tail call i8* @objc_retain(i8* %y) [[NUW]] ; CHECK-NEXT: ret void define void @test18() { %y = call i8* @returner() @@ -323,7 +323,7 @@ define i8* @test22(i8* %p) { ; Convert autoreleaseRV to autorelease. ; CHECK: define void @test23( -; CHECK: call i8* @objc_autorelease(i8* %p) nounwind +; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]] define void @test23(i8* %p) { store i8 0, i8* %p call i8* @objc_autoreleaseReturnValue(i8* %p) @@ -340,3 +340,5 @@ define {}* @test24(i8* %p) { %s = bitcast i8* %p to {}* ret {}* %s } + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/split-backedge.ll b/test/Transforms/ObjCARC/split-backedge.ll index 08e2dce1f55..5ac278a45d5 100644 --- a/test/Transforms/ObjCARC/split-backedge.ll +++ b/test/Transforms/ObjCARC/split-backedge.ll @@ -4,12 +4,12 @@ ; rdar://11256239 ; CHECK: define void @test0 -; CHECK: call i8* @objc_retain(i8* %call) nounwind -; CHECK: call i8* @objc_retain(i8* %call) nounwind -; CHECK: call i8* @objc_retain(i8* %cond) nounwind -; CHECK: call void @objc_release(i8* %call) nounwind -; CHECK: call void @objc_release(i8* %call) nounwind -; CHECK: call void @objc_release(i8* %cond) nounwind +; CHECK: call i8* @objc_retain(i8* %call) [[NUW:#[0-9]+]] +; CHECK: call i8* @objc_retain(i8* %call) [[NUW]] +; CHECK: call i8* @objc_retain(i8* %cond) [[NUW]] +; CHECK: call void @objc_release(i8* %call) [[NUW]] +; CHECK: call void @objc_release(i8* %call) [[NUW]] +; CHECK: call void @objc_release(i8* %cond) [[NUW]] define void @test0() { entry: br label %while.body @@ -46,3 +46,5 @@ declare i8* @objc_retain(i8*) declare void @use_pointer(i8*) !0 = metadata !{} + +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/ObjCARC/weak-copies.ll b/test/Transforms/ObjCARC/weak-copies.ll index b576295e112..5dab4e049e2 100644 --- a/test/Transforms/ObjCARC/weak-copies.ll +++ b/test/Transforms/ObjCARC/weak-copies.ll @@ -19,7 +19,7 @@ target triple = "x86_64-apple-darwin11.0.0" ; CHECK: define void @foo() { ; CHECK-NEXT: entry: ; CHECK-NEXT: %call = call i8* @bar() -; CHECK-NEXT: call void @use(i8* %call) nounwind +; CHECK-NEXT: call void @use(i8* %call) [[NUW:#[0-9]+]] ; CHECK-NEXT: ret void ; CHECK-NEXT: } define void @foo() { @@ -84,6 +84,6 @@ declare i8* @objc_loadWeak(i8**) declare void @use(i8*) nounwind declare void @objc_destroyWeak(i8**) -; CHECK: attributes #0 = { nounwind } +; CHECK: attributes [[NUW]] = { nounwind } !0 = metadata !{} diff --git a/test/Transforms/ScalarRepl/phi-cycle.ll b/test/Transforms/ScalarRepl/phi-cycle.ll index cb5101c2dd8..05d9382cec4 100644 --- a/test/Transforms/ScalarRepl/phi-cycle.ll +++ b/test/Transforms/ScalarRepl/phi-cycle.ll @@ -67,7 +67,7 @@ while.cond.backedge.i: ; preds = %if.end.i, %while.bo ; CHECK: func.exit: ; CHECK-NOT: load -; CHECK: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp) nounwind +; CHECK: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp) [[NUW:#[0-9]+]] func.exit: ; preds = %while.body.i.func.exit_crit_edge, %while.cond.i.func.exit_crit_edge %tmp3 = load i32* %x.i, align 4 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp3) nounwind @@ -75,3 +75,6 @@ func.exit: ; preds = %while.body.i.func.e } declare i32 @printf(i8* nocapture, ...) nounwind + +; CHECK: attributes #0 = { nounwind uwtable } +; CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/Transforms/SimplifyCFG/switch-on-const-select.ll b/test/Transforms/SimplifyCFG/switch-on-const-select.ll index 673a62bf035..9cd709ff8ec 100644 --- a/test/Transforms/SimplifyCFG/switch-on-const-select.ll +++ b/test/Transforms/SimplifyCFG/switch-on-const-select.ll @@ -35,7 +35,7 @@ define i32 @bar(i64 %x, i64 %y) nounwind { ; CHECK: @bar entry: ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call void @bees.a() nounwind +; CHECK-NEXT: tail call void @bees.a() [[NUW:#[0-9]+]] ; CHECK-NEXT: ret i32 0 %lt = icmp slt i64 %x, %y %qux = select i1 %lt, i32 0, i32 2 @@ -61,7 +61,7 @@ define void @bazz(i64 %x, i64 %y) nounwind { ; CHECK: @bazz entry: ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call void @bees.b() nounwind +; CHECK-NEXT: tail call void @bees.b() [[NUW]] ; CHECK-NEXT: ret void %lt = icmp slt i64 %x, %y %qux = select i1 %lt, i32 10, i32 12 @@ -86,7 +86,7 @@ define void @quux(i64 %x, i64 %y) nounwind { ; CHECK: @quux entry: ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call void @bees.a() nounwind +; CHECK-NEXT: tail call void @bees.a() [[NUW]] ; CHECK-NEXT: ret void %lt = icmp slt i64 %x, %y %qux = select i1 %lt, i32 0, i32 0 @@ -136,3 +136,6 @@ bees: declare void @llvm.trap() nounwind noreturn declare void @bees.a() nounwind declare void @bees.b() nounwind + +; CHECK: attributes [[NUW]] = { nounwind } +; CHECK: attributes #1 = { noreturn nounwind } -- 2.34.1