diff options
Diffstat (limited to 'test/Transforms/DeadArgElim')
-rw-r--r-- | test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll | 80 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/aggregates.ll | 162 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/dbginfo.ll | 44 |
3 files changed, 224 insertions, 62 deletions
diff --git a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll index 077394f..dd283ae 100644 --- a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll +++ b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll @@ -4,10 +4,10 @@ define i8* @vfs_addname(i8* %name, i32 %len, i32 %hash, i32 %flags) nounwind ssp { entry: - call void @llvm.dbg.value(metadata !{i8* %name}, i64 0, metadata !0, metadata !{}) - call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !10, metadata !{}) - call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !11, metadata !{}) - call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !12, metadata !{}) + call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !0, metadata !{}) + call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !10, metadata !{}) + call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !11, metadata !{}) + call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !12, metadata !{}) ; CHECK: call fastcc i8* @add_name_internal(i8* %name, i32 %hash) [[NUW:#[0-9]+]], !dbg !{{[0-9]+}} %0 = call fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext 0, i32 %flags) nounwind, !dbg !13 ; <i8*> [#uses=1] ret i8* %0, !dbg !13 @@ -17,11 +17,11 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone 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, metadata !{}) - call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !20, metadata !{}) - call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !21, metadata !{}) - call void @llvm.dbg.value(metadata !{i8 %extra}, i64 0, metadata !22, metadata !{}) - call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !23, metadata !{}) + call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !15, metadata !{}) + call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !20, metadata !{}) + call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !21, metadata !{}) + call void @llvm.dbg.value(metadata i8 %extra, i64 0, metadata !22, metadata !{}) + call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !23, metadata !{}) %0 = icmp eq i32 %hash, 0, !dbg !24 ; <i1> [#uses=1] br i1 %0, label %bb, label %bb1, !dbg !24 @@ -45,34 +45,34 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon !llvm.dbg.cu = !{!3} !llvm.module.flags = !{!30} -!0 = metadata !{metadata !"0x101\00name\008\000", metadata !1, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ] -!1 = metadata !{metadata !"0x2e\00vfs_addname\00vfs_addname\00vfs_addname\0012\000\001\000\006\000\000\000", metadata !28, metadata !2, metadata !4, null, null, null, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{metadata !"0x29", metadata !28} ; [ DW_TAG_file_type ] -!3 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)\001\00\000\00\000", metadata !28, metadata !29, metadata !29, null, null, null} ; [ DW_TAG_compile_unit ] -!4 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !28, metadata !2, null, metadata !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] -!5 = metadata !{metadata !6, metadata !6, metadata !9, metadata !9, metadata !9} -!6 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", metadata !28, metadata !2, metadata !7} ; [ DW_TAG_pointer_type ] -!7 = metadata !{metadata !"0x26\00\000\008\008\000\000", metadata !28, metadata !2, metadata !8} ; [ DW_TAG_const_type ] -!8 = metadata !{metadata !"0x24\00char\000\008\008\000\000\006", metadata !28, metadata !2} ; [ DW_TAG_base_type ] -!9 = metadata !{metadata !"0x24\00unsigned int\000\0032\0032\000\000\007", metadata !28, metadata !2} ; [ DW_TAG_base_type ] -!10 = metadata !{metadata !"0x101\00len\009\000", metadata !1, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ] -!11 = metadata !{metadata !"0x101\00hash\0010\000", metadata !1, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ] -!12 = metadata !{metadata !"0x101\00flags\0011\000", metadata !1, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ] -!13 = metadata !{i32 13, i32 0, metadata !14, null} -!14 = metadata !{metadata !"0xb\0012\000\000", metadata !28, metadata !1} ; [ DW_TAG_lexical_block ] -!15 = metadata !{metadata !"0x101\00name\0017\000", metadata !16, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ] -!16 = metadata !{metadata !"0x2e\00add_name_internal\00add_name_internal\00add_name_internal\0022\001\001\000\006\000\000\000", metadata !28, metadata !2, metadata !17, null, null, null, null, null} ; [ DW_TAG_subprogram ] -!17 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !28, metadata !2, null, metadata !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] -!18 = metadata !{metadata !6, metadata !6, metadata !9, metadata !9, metadata !19, metadata !9} -!19 = metadata !{metadata !"0x24\00unsigned char\000\008\008\000\000\008", metadata !28, metadata !2} ; [ DW_TAG_base_type ] -!20 = metadata !{metadata !"0x101\00len\0018\000", metadata !16, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ] -!21 = metadata !{metadata !"0x101\00hash\0019\000", metadata !16, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ] -!22 = metadata !{metadata !"0x101\00extra\0020\000", metadata !16, metadata !2, metadata !19} ; [ DW_TAG_arg_variable ] -!23 = metadata !{metadata !"0x101\00flags\0021\000", metadata !16, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ] -!24 = metadata !{i32 23, i32 0, metadata !25, null} -!25 = metadata !{metadata !"0xb\0022\000\000", metadata !28, metadata !16} ; [ DW_TAG_lexical_block ] -!26 = metadata !{i32 24, i32 0, metadata !25, null} -!27 = metadata !{i32 26, i32 0, metadata !25, null} -!28 = metadata !{metadata !"tail.c", metadata !"/Users/echeng/LLVM/radars/r7927803/"} -!29 = metadata !{i32 0} -!30 = metadata !{i32 1, metadata !"Debug Info Version", i32 2} +!0 = !{!"0x101\00name\008\000", !1, !2, !6} ; [ DW_TAG_arg_variable ] +!1 = !{!"0x2e\00vfs_addname\00vfs_addname\00vfs_addname\0012\000\001\000\006\000\000\000", !28, !2, !4, null, null, null, null, null} ; [ DW_TAG_subprogram ] +!2 = !{!"0x29", !28} ; [ DW_TAG_file_type ] +!3 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)\001\00\000\00\000", !28, !29, !29, null, null, null} ; [ DW_TAG_compile_unit ] +!4 = !{!"0x15\00\000\000\000\000\000\000", !28, !2, null, !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!5 = !{!6, !6, !9, !9, !9} +!6 = !{!"0xf\00\000\0064\0064\000\000", !28, !2, !7} ; [ DW_TAG_pointer_type ] +!7 = !{!"0x26\00\000\008\008\000\000", !28, !2, !8} ; [ DW_TAG_const_type ] +!8 = !{!"0x24\00char\000\008\008\000\000\006", !28, !2} ; [ DW_TAG_base_type ] +!9 = !{!"0x24\00unsigned int\000\0032\0032\000\000\007", !28, !2} ; [ DW_TAG_base_type ] +!10 = !{!"0x101\00len\009\000", !1, !2, !9} ; [ DW_TAG_arg_variable ] +!11 = !{!"0x101\00hash\0010\000", !1, !2, !9} ; [ DW_TAG_arg_variable ] +!12 = !{!"0x101\00flags\0011\000", !1, !2, !9} ; [ DW_TAG_arg_variable ] +!13 = !MDLocation(line: 13, scope: !14) +!14 = !{!"0xb\0012\000\000", !28, !1} ; [ DW_TAG_lexical_block ] +!15 = !{!"0x101\00name\0017\000", !16, !2, !6} ; [ DW_TAG_arg_variable ] +!16 = !{!"0x2e\00add_name_internal\00add_name_internal\00add_name_internal\0022\001\001\000\006\000\000\000", !28, !2, !17, null, null, null, null, null} ; [ DW_TAG_subprogram ] +!17 = !{!"0x15\00\000\000\000\000\000\000", !28, !2, null, !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!18 = !{!6, !6, !9, !9, !19, !9} +!19 = !{!"0x24\00unsigned char\000\008\008\000\000\008", !28, !2} ; [ DW_TAG_base_type ] +!20 = !{!"0x101\00len\0018\000", !16, !2, !9} ; [ DW_TAG_arg_variable ] +!21 = !{!"0x101\00hash\0019\000", !16, !2, !9} ; [ DW_TAG_arg_variable ] +!22 = !{!"0x101\00extra\0020\000", !16, !2, !19} ; [ DW_TAG_arg_variable ] +!23 = !{!"0x101\00flags\0021\000", !16, !2, !9} ; [ DW_TAG_arg_variable ] +!24 = !MDLocation(line: 23, scope: !25) +!25 = !{!"0xb\0022\000\000", !28, !16} ; [ DW_TAG_lexical_block ] +!26 = !MDLocation(line: 24, scope: !25) +!27 = !MDLocation(line: 26, scope: !25) +!28 = !{!"tail.c", !"/Users/echeng/LLVM/radars/r7927803/"} +!29 = !{i32 0} +!30 = !{i32 1, !"Debug Info Version", i32 2} diff --git a/test/Transforms/DeadArgElim/aggregates.ll b/test/Transforms/DeadArgElim/aggregates.ll new file mode 100644 index 0000000..f54c6c9 --- /dev/null +++ b/test/Transforms/DeadArgElim/aggregates.ll @@ -0,0 +1,162 @@ +; RUN: opt -S -deadargelim %s | FileCheck %s + +; Case 0: the basic example: an entire aggregate use is returned, but it's +; actually only used in ways we can eliminate. We gain benefit from analysing +; the "use" and applying its results to all sub-values. + +; CHECK-LABEL: define internal void @agguse_dead() + +define internal { i32, i32 } @agguse_dead() { + ret { i32, i32 } { i32 0, i32 1 } +} + +define internal { i32, i32 } @test_agguse_dead() { + %val = call { i32, i32 } @agguse_dead() + ret { i32, i32 } %val +} + + + +; Case 1: an opaque use of the aggregate exists (in this case dead). Otherwise +; only one value is used, so function can be simplified. + +; CHECK-LABEL: define internal i32 @rets_independent_if_agguse_dead() +; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } { i32 0, i32 1 }, 1 +; CHECK: ret i32 [[RET]] + +define internal { i32, i32 } @rets_independent_if_agguse_dead() { + ret { i32, i32 } { i32 0, i32 1 } +} + +define internal { i32, i32 } @test_rets_independent_if_agguse_dead(i1 %tst) { + %val = call { i32, i32 } @rets_independent_if_agguse_dead() + br i1 %tst, label %use_1, label %use_aggregate + +use_1: + ; This use can be classified as applying only to ret 1. + %val0 = extractvalue { i32, i32 } %val, 1 + call void @callee(i32 %val0) + ret { i32, i32 } undef + +use_aggregate: + ; This use is assumed to apply to both 0 and 1. + ret { i32, i32 } %val +} + +; Case 2: an opaque use of the aggregate exists (in this case *live*). Other +; uses shouldn't matter. + +; CHECK-LABEL: define internal { i32, i32 } @rets_live_agguse() +; CHECK: ret { i32, i32 } { i32 0, i32 1 } + +define internal { i32, i32 } @rets_live_agguse() { + ret { i32, i32} { i32 0, i32 1 } +} + +define { i32, i32 } @test_rets_live_aggues(i1 %tst) { + %val = call { i32, i32 } @rets_live_agguse() + br i1 %tst, label %use_1, label %use_aggregate + +use_1: + ; This use can be classified as applying only to ret 1. + %val0 = extractvalue { i32, i32 } %val, 1 + call void @callee(i32 %val0) + ret { i32, i32 } undef + +use_aggregate: + ; This use is assumed to apply to both 0 and 1. + ret { i32, i32 } %val +} + +declare void @callee(i32) + +; Case 3: the insertvalue meant %in was live if ret-slot-1 was, but we were only +; tracking multiple ret-slots for struct types. So %in was eliminated +; incorrectly. + +; CHECK-LABEL: define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in) + +define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in) { + %ret = insertvalue [2 x i32] undef, i32 %in, 1 + ret [2 x i32] %ret +} + +define [2 x i32] @test_array_rets_have_multiple_slots() { + %res = call [2 x i32] @array_rets_have_multiple_slots(i32 42) + ret [2 x i32] %res +} + +; Case 4: we can remove some retvals from the array. It's nice to produce an +; array again having done so (rather than converting it to a struct). + +; CHECK-LABEL: define internal [2 x i32] @can_shrink_arrays() +; CHECK: [[VAL0:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 0 +; CHECK: [[RESTMP:%.*]] = insertvalue [2 x i32] undef, i32 [[VAL0]], 0 +; CHECK: [[VAL2:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 2 +; CHECK: [[RES:%.*]] = insertvalue [2 x i32] [[RESTMP]], i32 [[VAL2]], 1 +; CHECK: ret [2 x i32] [[RES]] + +; CHECK-LABEL: define void @test_can_shrink_arrays() + +define internal [3 x i32] @can_shrink_arrays() { + ret [3 x i32] [i32 42, i32 43, i32 44] +} + +define void @test_can_shrink_arrays() { + %res = call [3 x i32] @can_shrink_arrays() + + %res.0 = extractvalue [3 x i32] %res, 0 + call void @callee(i32 %res.0) + + %res.2 = extractvalue [3 x i32] %res, 2 + call void @callee(i32 %res.2) + + ret void +} + +; Case 5: %in gets passed directly to the return. It should mark be marked as +; used if *any* of the return values are, not just if value 0 is. + +; CHECK-LABEL: define internal i32 @ret_applies_to_all({ i32, i32 } %in) +; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } %in, 1 +; CHECK: ret i32 [[RET]] + +define internal {i32, i32} @ret_applies_to_all({i32, i32} %in) { + ret {i32, i32} %in +} + +define i32 @test_ret_applies_to_all() { + %val = call {i32, i32} @ret_applies_to_all({i32, i32} {i32 42, i32 43}) + %ret = extractvalue {i32, i32} %val, 1 + ret i32 %ret +} + +; Case 6: When considering @mid, the return instruciton has sub-value 0 +; unconditionally live, but 1 only conditionally live. Since at that level we're +; applying the results to the whole of %res, this means %res is live and cannot +; be reduced. There is scope for further optimisation here (though not visible +; in this test-case). + +; CHECK-LABEL: define internal { i8*, i32 } @inner() + +define internal {i8*, i32} @mid() { + %res = call {i8*, i32} @inner() + %intval = extractvalue {i8*, i32} %res, 1 + %tst = icmp eq i32 %intval, 42 + br i1 %tst, label %true, label %true + +true: + ret {i8*, i32} %res +} + +define internal {i8*, i32} @inner() { + ret {i8*, i32} {i8* null, i32 42} +} + +define internal i8 @outer() { + %res = call {i8*, i32} @mid() + %resptr = extractvalue {i8*, i32} %res, 0 + + %val = load i8* %resptr + ret i8 %val +}
\ No newline at end of file diff --git a/test/Transforms/DeadArgElim/dbginfo.ll b/test/Transforms/DeadArgElim/dbginfo.ll index b457f01..5bbf821 100644 --- a/test/Transforms/DeadArgElim/dbginfo.ll +++ b/test/Transforms/DeadArgElim/dbginfo.ll @@ -29,7 +29,7 @@ entry: ; Function Attrs: nounwind uwtable define internal void @_ZL2f1iz(i32, ...) #1 { entry: - call void @llvm.dbg.value(metadata !{i32 %0}, i64 0, metadata !17, metadata !18), !dbg !19 + call void @llvm.dbg.value(metadata i32 %0, i64 0, metadata !17, metadata !18), !dbg !19 ret void, !dbg !20 } @@ -47,24 +47,24 @@ attributes #2 = { nounwind readnone } !llvm.module.flags = !{!12, !13} !llvm.ident = !{!14} -!0 = metadata !{metadata !"0x11\004\00clang version 3.6.0 \000\00\000\00\001", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/dbg.cpp] [DW_LANG_C_plus_plus] -!1 = metadata !{metadata !"dbg.cpp", metadata !"/tmp/dbginfo"} -!2 = metadata !{} -!3 = metadata !{metadata !4, metadata !8} -!4 = metadata !{metadata !"0x2e\00f2\00f2\00_Z2f2v\004\000\001\000\000\00256\000\004", metadata !1, metadata !5, metadata !6, null, void ()* @_Z2f2v, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 4] [def] [f2] -!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/tmp/dbginfo/dbg.cpp] -!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] -!7 = metadata !{null} -!8 = metadata !{metadata !"0x2e\00f1\00f1\00_ZL2f1iz\001\001\001\000\000\00256\000\001", metadata !1, metadata !5, metadata !9, null, void (i32, ...)* @_ZL2f1iz, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [local] [def] [f1] -!9 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !10, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] -!10 = metadata !{null, metadata !11, null} -!11 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] -!12 = metadata !{i32 2, metadata !"Dwarf Version", i32 4} -!13 = metadata !{i32 2, metadata !"Debug Info Version", i32 2} -!14 = metadata !{metadata !"clang version 3.6.0 "} -!15 = metadata !{i32 5, i32 3, metadata !4, null} -!16 = metadata !{i32 6, i32 1, metadata !4, null} -!17 = metadata !{metadata !"0x101\00\0016777217\000", metadata !8, metadata !5, metadata !11} ; [ DW_TAG_arg_variable ] [line 1] -!18 = metadata !{metadata !"0x102"} ; [ DW_TAG_expression ] -!19 = metadata !{i32 1, i32 19, metadata !8, null} -!20 = metadata !{i32 2, i32 1, metadata !8, null} +!0 = !{!"0x11\004\00clang version 3.6.0 \000\00\000\00\001", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/dbg.cpp] [DW_LANG_C_plus_plus] +!1 = !{!"dbg.cpp", !"/tmp/dbginfo"} +!2 = !{} +!3 = !{!4, !8} +!4 = !{!"0x2e\00f2\00f2\00_Z2f2v\004\000\001\000\000\00256\000\004", !1, !5, !6, null, void ()* @_Z2f2v, null, null, !2} ; [ DW_TAG_subprogram ] [line 4] [def] [f2] +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/tmp/dbginfo/dbg.cpp] +!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!7 = !{null} +!8 = !{!"0x2e\00f1\00f1\00_ZL2f1iz\001\001\001\000\000\00256\000\001", !1, !5, !9, null, void (i32, ...)* @_ZL2f1iz, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [local] [def] [f1] +!9 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !10, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!10 = !{null, !11, null} +!11 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 2} +!14 = !{!"clang version 3.6.0 "} +!15 = !MDLocation(line: 5, column: 3, scope: !4) +!16 = !MDLocation(line: 6, column: 1, scope: !4) +!17 = !{!"0x101\00\0016777217\000", !8, !5, !11} ; [ DW_TAG_arg_variable ] [line 1] +!18 = !{!"0x102"} ; [ DW_TAG_expression ] +!19 = !MDLocation(line: 1, column: 19, scope: !8) +!20 = !MDLocation(line: 2, column: 1, scope: !8) |