Imported Upstream version 5.18.0.234

Former-commit-id: 8071ec1a8c5eaa9be24b41745add19297608001f
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-01-08 08:22:36 +00:00
parent f32dbaf0b2
commit 212f6bafcb
28494 changed files with 359 additions and 3867025 deletions

View File

@@ -1,11 +0,0 @@
; RUN: opt < %s -deadargelim -disable-output
define internal void @build_delaunay({ i32 }* sret %agg.result) {
ret void
}
define void @test() {
call void @build_delaunay( { i32 }* sret null )
ret void
}

View File

@@ -1,11 +0,0 @@
; RUN: opt < %s -deadargelim -S | grep "@test("
; RUN: opt < %s -deadargelim -S | not grep dead
define internal i32 @test(i32 %X, i32 %dead) {
ret i32 %X
}
define i32 @caller() {
%A = call i32 @test(i32 123, i32 456)
ret i32 %A
}

View File

@@ -1,12 +0,0 @@
; RUN: opt < %s -deadargelim -S | not grep "ret i32 0"
; PR1735
define internal i32 @test(i32 %A, ...) {
ret i32 %A
}
define i32 @foo() {
%A = call i32(i32, ...) @test(i32 1)
ret i32 %A
}

View File

@@ -1,20 +0,0 @@
; RUN: opt < %s -deadargelim -S | FileCheck %s
%struct = type { }
@g = global i8 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
ret i8 0
}
define i32 @bar() {
; 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 [[NUW]] = { nounwind }

View File

@@ -1,31 +0,0 @@
; RUN: opt < %s -deadargelim -S | grep byval
%struct.point = type { double, double }
@pts = global [4 x %struct.point] [ %struct.point { double 1.000000e+00, double 2.000000e+00 }, %struct.point { double 3.000000e+00, double 4.000000e+00 }, %struct.point { double 5.000000e+00, double 6.000000e+00 }, %struct.point { double 7.000000e+00, double 8.000000e+00 } ], align 32 ; <[4 x %struct.point]*> [#uses=1]
define internal i32 @va1(i32 %nargs, ...) {
entry:
%pi = alloca %struct.point ; <%struct.point*> [#uses=0]
%args = alloca i8* ; <i8**> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
%args1 = bitcast i8** %args to i8* ; <i8*> [#uses=1]
call void @llvm.va_start( i8* %args1 )
%args41 = bitcast i8** %args to i8* ; <i8*> [#uses=1]
call void @llvm.va_end( i8* %args41 )
ret i32 undef
}
declare void @llvm.va_start(i8*) nounwind
declare void @llvm.va_end(i8*) nounwind
define i32 @main() {
entry:
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
%tmp = getelementptr [4 x %struct.point], [4 x %struct.point]* @pts, i32 0, i32 0 ; <%struct.point*> [#uses=1]
%tmp1 = call i32 (i32, ...) @va1( i32 1, %struct.point* byval %tmp ) nounwind ; <i32> [#uses=0]
call void @exit( i32 0 ) noreturn nounwind
unreachable
}
declare void @exit(i32) noreturn nounwind

View File

@@ -1,23 +0,0 @@
; RUN: opt < %s -deadargelim -die -S > %t
; RUN: cat %t | grep 123
; This test tries to catch wrongful removal of return values for a specific case
; that was breaking llvm-gcc builds.
; This function has a live return value, it is used by @alive.
define internal i32 @test5() {
ret i32 123
}
; This function doesn't use the return value @test5 and tries to lure DAE into
; marking @test5's return value dead because only this call is unused.
define i32 @dead() {
%DEAD = call i32 @test5()
ret i32 0
}
; This function ensures the retval of @test5 is live.
define i32 @alive() {
%LIVE = call i32 @test5()
ret i32 %LIVE
}

View File

@@ -1,32 +0,0 @@
; RUN: opt < %s -deadargelim | llvm-dis
; PR3807
define internal { i32, i32 } @foo() {
ret {i32,i32} {i32 42, i32 4}
}
define i32 @bar() personality i32 (...)* @__gxx_personality_v0 {
%x = invoke {i32,i32} @foo() to label %T unwind label %T2
T:
%y = extractvalue {i32,i32} %x, 1
ret i32 %y
T2:
%exn = landingpad {i8*, i32}
cleanup
unreachable
}
define i32 @bar2() personality i32 (...)* @__gxx_personality_v0 {
entry:
%x = invoke {i32,i32} @foo() to label %T unwind label %T2
T:
%PN = phi i32 [0, %entry]
%y = extractvalue {i32,i32} %x, 1
ret i32 %y
T2:
%exn = landingpad {i8*, i32}
cleanup
unreachable
}
declare i32 @__gxx_personality_v0(...)

View File

@@ -1,78 +0,0 @@
; RUN: opt -S -deadargelim < %s | FileCheck %s
@.str = private constant [1 x i8] zeroinitializer, align 1 ; <[1 x i8]*> [#uses=1]
define i8* @vfs_addname(i8* %name, i32 %len, i32 %hash, i32 %flags) nounwind ssp {
entry:
call void @llvm.dbg.value(metadata i8* %name, metadata !0, metadata !DIExpression()), !dbg !DILocation(scope: !1)
call void @llvm.dbg.value(metadata i32 %len, metadata !10, metadata !DIExpression()), !dbg !DILocation(scope: !1)
call void @llvm.dbg.value(metadata i32 %hash, metadata !11, metadata !DIExpression()), !dbg !DILocation(scope: !1)
call void @llvm.dbg.value(metadata i32 %flags, metadata !12, metadata !DIExpression()), !dbg !DILocation(scope: !1)
; 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
}
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, metadata !15, metadata !DIExpression()), !dbg !DILocation(scope: !16)
call void @llvm.dbg.value(metadata i32 %len, metadata !20, metadata !DIExpression()), !dbg !DILocation(scope: !16)
call void @llvm.dbg.value(metadata i32 %hash, metadata !21, metadata !DIExpression()), !dbg !DILocation(scope: !16)
call void @llvm.dbg.value(metadata i8 %extra, metadata !22, metadata !DIExpression()), !dbg !DILocation(scope: !16)
call void @llvm.dbg.value(metadata i32 %flags, metadata !23, metadata !DIExpression()), !dbg !DILocation(scope: !16)
%0 = icmp eq i32 %hash, 0, !dbg !24 ; <i1> [#uses=1]
br i1 %0, label %bb, label %bb1, !dbg !24
bb: ; preds = %entry
br label %bb2, !dbg !26
bb1: ; preds = %entry
br label %bb2, !dbg !27
bb2: ; preds = %bb1, %bb
%.0 = phi i8* [ getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0), %bb ], [ %name, %bb1 ] ; <i8*> [#uses=1]
ret i8* %.0, !dbg !27
}
declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone
; CHECK: attributes #0 = { nounwind ssp }
; CHECK: attributes #1 = { nounwind readnone speculatable }
; CHECK: attributes #2 = { noinline nounwind ssp }
; CHECK: attributes [[NUW]] = { nounwind }
!llvm.dbg.cu = !{!3}
!llvm.module.flags = !{!30}
!0 = !DILocalVariable(name: "name", line: 8, arg: 1, scope: !1, file: !2, type: !6)
!1 = distinct !DISubprogram(name: "vfs_addname", linkageName: "vfs_addname", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !28, scope: !2, type: !4)
!2 = !DIFile(filename: "tail.c", directory: "/Users/echeng/LLVM/radars/r7927803/")
!3 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)", isOptimized: true, emissionKind: FullDebug, file: !28, enums: !29, retainedTypes: !29)
!4 = !DISubroutineType(types: !5)
!5 = !{!6, !6, !9, !9, !9}
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !28, scope: !2, baseType: !7)
!7 = !DIDerivedType(tag: DW_TAG_const_type, size: 8, align: 8, file: !28, scope: !2, baseType: !8)
!8 = !DIBasicType(tag: DW_TAG_base_type, name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
!9 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
!10 = !DILocalVariable(name: "len", line: 9, arg: 2, scope: !1, file: !2, type: !9)
!11 = !DILocalVariable(name: "hash", line: 10, arg: 3, scope: !1, file: !2, type: !9)
!12 = !DILocalVariable(name: "flags", line: 11, arg: 4, scope: !1, file: !2, type: !9)
!13 = !DILocation(line: 13, scope: !14)
!14 = distinct !DILexicalBlock(line: 12, column: 0, file: !28, scope: !1)
!15 = !DILocalVariable(name: "name", line: 17, arg: 1, scope: !16, file: !2, type: !6)
!16 = distinct !DISubprogram(name: "add_name_internal", linkageName: "add_name_internal", line: 22, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !28, scope: !2, type: !17)
!17 = !DISubroutineType(types: !18)
!18 = !{!6, !6, !9, !9, !19, !9}
!19 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned char", size: 8, align: 8, encoding: DW_ATE_unsigned_char)
!20 = !DILocalVariable(name: "len", line: 18, arg: 2, scope: !16, file: !2, type: !9)
!21 = !DILocalVariable(name: "hash", line: 19, arg: 3, scope: !16, file: !2, type: !9)
!22 = !DILocalVariable(name: "extra", line: 20, arg: 4, scope: !16, file: !2, type: !19)
!23 = !DILocalVariable(name: "flags", line: 21, arg: 5, scope: !16, file: !2, type: !9)
!24 = !DILocation(line: 23, scope: !25)
!25 = distinct !DILexicalBlock(line: 22, column: 0, file: !28, scope: !16)
!26 = !DILocation(line: 24, scope: !25)
!27 = !DILocation(line: 26, scope: !25)
!28 = !DIFile(filename: "tail.c", directory: "/Users/echeng/LLVM/radars/r7927803/")
!29 = !{}
!30 = !{i32 1, !"Debug Info Version", i32 3}

View File

@@ -1,25 +0,0 @@
; RUN: opt %s -deadargelim -S | FileCheck %s
@block_addr = global i8* blockaddress(@varargs_func, %l1)
; CHECK: @block_addr = global i8* blockaddress(@varargs_func, %l1)
; This function is referenced by a "blockaddress" constant but it is
; not address-taken, so the pass should be able to remove its unused
; varargs.
define internal i32 @varargs_func(i8* %addr, ...) {
indirectbr i8* %addr, [ label %l1, label %l2 ]
l1:
ret i32 1
l2:
ret i32 2
}
; CHECK: define internal i32 @varargs_func(i8* %addr) {
define i32 @caller(i8* %addr) {
%r = call i32 (i8*, ...) @varargs_func(i8* %addr)
ret i32 %r
}
; CHECK: %r = call i32 @varargs_func(i8* %addr)

View File

@@ -1,186 +0,0 @@
; 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, i8* %resptr
ret i8 %val
}
define internal { i32 } @agg_ret() {
entry:
unreachable
}
; CHECK-LABEL: define void @PR24906
; CHECK: %[[invoke:.*]] = invoke i32 @agg_ret()
; CHECK: %[[oldret:.*]] = insertvalue { i32 } undef, i32 %[[invoke]], 0
; CHECK: phi { i32 } [ %[[oldret]],
define void @PR24906() personality i32 (i32)* undef {
entry:
%tmp2 = invoke { i32 } @agg_ret()
to label %bb3 unwind label %bb4
bb3:
%tmp3 = phi { i32 } [ %tmp2, %entry ]
unreachable
bb4:
%tmp4 = landingpad { i8*, i32 }
cleanup
unreachable
}

View File

@@ -1,36 +0,0 @@
; RUN: opt < %s -deadargelim -S | not grep DEADARG
; test - an obviously dead argument
define internal i32 @test(i32 %v, i32 %DEADARG1, i32* %p) {
store i32 %v, i32* %p
ret i32 %v
}
; hardertest - an argument which is only used by a call of a function with a
; dead argument.
define internal i32 @hardertest(i32 %DEADARG2) {
%p = alloca i32 ; <i32*> [#uses=1]
%V = call i32 @test( i32 5, i32 %DEADARG2, i32* %p ) ; <i32> [#uses=1]
ret i32 %V
}
; evenhardertest - recursive dead argument...
define internal void @evenhardertest(i32 %DEADARG3) {
call void @evenhardertest( i32 %DEADARG3 )
ret void
}
define internal void @needarg(i32 %TEST) {
call i32 @needarg2( i32 %TEST ) ; <i32>:1 [#uses=0]
ret void
}
define internal i32 @needarg2(i32 %TEST) {
ret i32 %TEST
}
define internal void @needarg3(i32 %TEST3) {
call void @needarg( i32 %TEST3 )
ret void
}

View File

@@ -1,22 +0,0 @@
; RUN: opt -deadargelim -S < %s | FileCheck %s
; Checks if !prof metadata is corret in deadargelim.
define void @caller() #0 {
; CHECK: call void @test_vararg(), !prof ![[PROF:[0-9]]]
; CHECK: call void @test(), !prof ![[PROF]]
call void (i32, ...) @test_vararg(i32 1), !prof !0
call void @test(i32 1), !prof !0
ret void
}
define internal void @test_vararg(i32, ...) #1 {
ret void
}
define internal void @test(i32 %a) #1 {
ret void
}
; CHECK:![[PROF]] = !{!"branch_weights", i32 30}
!0 = !{!"branch_weights", i32 30}

View File

@@ -1,24 +0,0 @@
; This test shows a few canonicalizations made by deadargelim
; RUN: opt < %s -deadargelim -S > %t
; This test should remove {} and replace it with void
; RUN: cat %t | grep "define internal void @test"
; This test shouls replace the {i32} return value with just i32
; RUN: cat %t | grep "define internal i32 @test2"
define internal {} @test() {
ret {} undef
}
define internal {i32} @test2() {
ret {i32} undef
}
define void @caller() {
call {} @test()
%X = call {i32} @test2()
%Y = extractvalue {i32} %X, 0
call void @user(i32 %Y, {i32} %X)
ret void
}
declare void @user(i32, {i32})

View File

@@ -1,14 +0,0 @@
; RUN: opt -S < %s -deadargelim | FileCheck %s
$f = comdat any
define void @f() comdat {
call void @g(i32 0)
ret void
}
define internal void @g(i32 %dead) comdat($f) {
ret void
}
; CHECK: define internal void @g() comdat($f) {

View File

@@ -1,70 +0,0 @@
; RUN: opt -deadargelim -S < %s | FileCheck %s
; PR14016
; Built with clang (then manually running -mem2reg with opt) from the following source:
; static void f1(int, ...) {
; }
;
; void f2() {
; f1(1);
; }
; Test both varargs removal and removal of a traditional dead arg together, to
; test both the basic functionality, and a particular wrinkle involving updating
; the function->debug info mapping on update to ensure it's accurate when used
; again for the next removal.
; CHECK: define internal void @_ZL2f1iz({{.*}} !dbg [[SP:![0-9]+]]
; CHECK: [[SP]] = distinct !DISubprogram(name: "f1"
; Check that debug info metadata for subprograms stores pointers to
; updated LLVM functions.
; Function Attrs: uwtable
define void @_Z2f2v() #0 !dbg !4 {
entry:
call void (i32, ...) @_ZL2f1iz(i32 1), !dbg !15
ret void, !dbg !16
}
; Function Attrs: nounwind uwtable
define internal void @_ZL2f1iz(i32, ...) #1 !dbg !8 {
entry:
call void @llvm.dbg.value(metadata i32 %0, metadata !17, metadata !18), !dbg !19
ret void, !dbg !20
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
; Function Attrs: nounwind readnone
declare void @llvm.dbg.value(metadata, metadata, metadata) #2
attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!12, !13}
!llvm.ident = !{!14}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "dbg.cpp", directory: "/tmp/dbginfo")
!2 = !{}
!4 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", line: 4, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 4, file: !1, scope: !5, type: !6, variables: !2)
!5 = !DIFile(filename: "dbg.cpp", directory: "/tmp/dbginfo")
!6 = !DISubroutineType(types: !7)
!7 = !{null}
!8 = distinct !DISubprogram(name: "f1", linkageName: "_ZL2f1iz", line: 1, isLocal: true, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !9, variables: !2)
!9 = !DISubroutineType(types: !10)
!10 = !{null, !11, null}
!11 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!12 = !{i32 2, !"Dwarf Version", i32 4}
!13 = !{i32 2, !"Debug Info Version", i32 3}
!14 = !{!"clang version 3.6.0 "}
!15 = !DILocation(line: 5, column: 3, scope: !4)
!16 = !DILocation(line: 6, column: 1, scope: !4)
!17 = !DILocalVariable(name: "", line: 1, arg: 1, scope: !8, file: !5, type: !11)
!18 = !DIExpression()
!19 = !DILocation(line: 1, column: 19, scope: !8)
!20 = !DILocation(line: 2, column: 1, scope: !8)

View File

@@ -1,36 +0,0 @@
; RUN: opt < %s -deadargelim -S | FileCheck %s
define i32 @bar(i32 %A) {
call void (i32, ...) @thunk(i32 %A, i64 47, double 1.000000e+00)
%a = call i32 (i32, ...) @has_vastart(i32 %A, i64 47, double 1.000000e+00)
%b = call i32 (i32, ...) @no_vastart( i32 %A, i32 %A, i32 %A, i32 %A, i64 47, double 1.000000e+00 )
%c = add i32 %a, %b
ret i32 %c
}
; CHECK-LABEL: define i32 @bar
; CHECK: call void (i32, ...) @thunk(i32 %A, i64 47, double 1.000000e+00)
; CHECK: call i32 (i32, ...) @has_vastart(i32 %A, i64 47, double 1.000000e+00)
; CHECK: call i32 @no_vastart(i32 %A)
declare void @thunk_target(i32 %X, ...)
define internal void @thunk(i32 %X, ...) {
musttail call void(i32, ...) @thunk_target(i32 %X, ...)
ret void
}
; CHECK-LABEL: define internal void @thunk(i32 %X, ...)
; CHECK: musttail call void (i32, ...) @thunk_target(i32 %X, ...)
define internal i32 @has_vastart(i32 %X, ...) {
%valist = alloca i8
call void @llvm.va_start(i8* %valist)
ret i32 %X
}
; CHECK-LABEL: define internal i32 @has_vastart(i32 %X, ...)
declare void @llvm.va_start(i8*)
define internal i32 @no_vastart(i32 %X, ...) {
ret i32 %X
}
; CHECK-LABEL: define internal i32 @no_vastart(i32 %X)

View File

@@ -1,67 +0,0 @@
; RUN: opt -deadargelim -S < %s | FileCheck %s
define void @test(i32) {
ret void
}
define void @foo() {
call void @test(i32 0)
ret void
; CHECK-LABEL: @foo(
; CHECK: i32 undef
}
define void @f(i32 %X) {
entry:
tail call void @sideeffect() nounwind
ret void
}
declare void @sideeffect()
define void @g(i32 %n) {
entry:
%add = add nsw i32 %n, 1
; CHECK: tail call void @f(i32 undef)
tail call void @f(i32 %add)
ret void
}
define void @h() {
entry:
%i = alloca i32, align 4
store volatile i32 10, i32* %i, align 4
; CHECK: %tmp = load volatile i32, i32* %i, align 4
; CHECK-NEXT: call void @f(i32 undef)
%tmp = load volatile i32, i32* %i, align 4
call void @f(i32 %tmp)
ret void
}
; Check that callers are not transformed for weak definitions.
define weak i32 @weak_f(i32 %x) nounwind {
entry:
ret i32 0
}
define void @weak_f_caller() nounwind {
entry:
; CHECK: call i32 @weak_f(i32 10)
%call = tail call i32 @weak_f(i32 10)
ret void
}
%swift_error = type opaque
define void @unused_swifterror_arg(%swift_error** swifterror %dead_arg) {
tail call void @sideeffect() nounwind
ret void
}
; CHECK-LABEL: @dont_replace_by_undef
; CHECK-NOT: call void @unused_swifterror_arg({{.*}}undef)
define void @dont_replace_by_undef() {
%error_ptr_ref = alloca swifterror %swift_error*
store %swift_error* null, %swift_error** %error_ptr_ref
call void @unused_swifterror_arg(%swift_error** %error_ptr_ref)
ret void
}

View File

@@ -1,18 +0,0 @@
; RUN: opt < %s -deadargelim -S | not grep DEAD
; Dead arg only used by dead retval
define internal i32 @test(i32 %DEADARG) {
ret i32 %DEADARG
}
define i32 @test2(i32 %A) {
%DEAD = call i32 @test( i32 %A ) ; <i32> [#uses=0]
ret i32 123
}
define i32 @test3() {
%X = call i32 @test2( i32 3232 ) ; <i32> [#uses=1]
%Y = add i32 %X, -123 ; <i32> [#uses=1]
ret i32 %Y
}

View File

@@ -1,59 +0,0 @@
; RUN: opt < %s -deadargelim -die -S > %t
; RUN: cat %t | not grep DEAD
; RUN: cat %t | grep LIVE | count 4
@P = external global i32 ; <i32*> [#uses=1]
; Dead arg only used by dead retval
define internal i32 @test(i32 %DEADARG) {
ret i32 %DEADARG
}
define internal i32 @test2(i32 %DEADARG) {
%DEADRETVAL = call i32 @test( i32 %DEADARG ) ; <i32> [#uses=1]
ret i32 %DEADRETVAL
}
define void @test3(i32 %X) {
%DEADRETVAL = call i32 @test2( i32 %X ) ; <i32> [#uses=0]
ret void
}
define internal i32 @foo() {
%DEAD = load i32, i32* @P ; <i32> [#uses=1]
ret i32 %DEAD
}
define internal i32 @id(i32 %X) {
ret i32 %X
}
define void @test4() {
%DEAD = call i32 @foo( ) ; <i32> [#uses=1]
%DEAD2 = call i32 @id( i32 %DEAD ) ; <i32> [#uses=0]
ret void
}
; These test if returning another functions return value properly marks that
; other function's return value as live. We do this twice, with the functions in
; different orders (ie, first the caller, than the callee and first the callee
; and then the caller) since DAE processes functions one by one and handles
; these cases slightly different.
define internal i32 @test5() {
ret i32 123
}
define i32 @test6() {
%LIVE = call i32 @test5()
ret i32 %LIVE
}
define i32 @test7() {
%LIVE = call i32 @test8()
ret i32 %LIVE
}
define internal i32 @test8() {
ret i32 124
}

View File

@@ -1,29 +0,0 @@
; RUN: opt -S -deadargelim < %s | FileCheck %s
target triple = "x86_64-pc-windows-msvc"
define internal void @callee(i8*) {
entry:
call void @thunk()
ret void
}
define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
entry:
invoke void @thunk()
to label %good1 unwind label %bad1
good1: ; preds = %entry-block
ret void
bad1: ; preds = %entry-block
%pad1 = cleanuppad within none []
call void @callee(i8* null) [ "funclet"(token %pad1) ]
cleanupret from %pad1 unwind to caller
}
; CHECK-LABEL: define void @test1(
; CHECK: %[[pad:.*]] = cleanuppad within none []
; CHECK-NEXT: call void @callee() [ "funclet"(token %[[pad]]) ]
declare void @thunk()
declare i32 @__CxxFrameHandler3(...)

Some files were not shown because too many files have changed in this diff Show More