@@ -46,3 +46,71 @@ entry:
46
46
call void @use_pointer (i8* %p )
47
47
ret void
48
48
}
49
+
50
+ ; Check that we can delete the autoreleaseRV+retainAutoreleasedRV pair even in
51
+ ; presence of instructions added by the inliner as part of the return sequence.
52
+
53
+ ; 1) Noop instructions: bitcasts and zero-indices GEPs.
54
+
55
+ ; CHECK-LABEL: define i8* @testNoop(
56
+ ; CHECK: entry:
57
+ ; CHECK-NEXT: %noop0 = bitcast i8* %call.i to i64*
58
+ ; CHECK-NEXT: %noop1 = getelementptr i8, i8* %call.i, i32 0
59
+ ; CHECK-NEXT: ret i8* %call.i
60
+ ; CHECK-NEXT: }
61
+ define i8* @testNoop (i8* %call.i ) {
62
+ entry:
63
+ %0 = tail call i8* @llvm.objc.autoreleaseReturnValue (i8* %call.i ) nounwind
64
+ %noop0 = bitcast i8* %call.i to i64*
65
+ %noop1 = getelementptr i8 , i8* %call.i , i32 0
66
+ %1 = tail call i8* @llvm.objc.retainAutoreleasedReturnValue (i8* %call.i ) nounwind
67
+ ret i8* %call.i
68
+ }
69
+
70
+ ; 2) Lifetime markers.
71
+
72
+ declare void @llvm.lifetime.start.p0i8 (i64 , i8* )
73
+ declare void @llvm.lifetime.end.p0i8 (i64 , i8* )
74
+
75
+ ; CHECK-LABEL: define i8* @testLifetime(
76
+ ; CHECK: entry:
77
+ ; CHECK-NEXT: %obj = alloca i8
78
+ ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* %obj)
79
+ ; CHECK-NEXT: %0 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call.i)
80
+ ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* %obj)
81
+ ; CHECK-NEXT: %1 = tail call i8* @llvm.objc.retain(i8* %call.i)
82
+ ; CHECK-NEXT: ret i8* %call.i
83
+ ; CHECK-NEXT: }
84
+ define i8* @testLifetime (i8* %call.i ) {
85
+ entry:
86
+ %obj = alloca i8
87
+ call void @llvm.lifetime.start.p0i8 (i64 8 , i8* %obj )
88
+ %0 = tail call i8* @llvm.objc.autoreleaseReturnValue (i8* %call.i ) nounwind
89
+ call void @llvm.lifetime.end.p0i8 (i64 8 , i8* %obj )
90
+ %1 = tail call i8* @llvm.objc.retainAutoreleasedReturnValue (i8* %call.i ) nounwind
91
+ ret i8* %call.i
92
+ }
93
+
94
+ ; 3) Dynamic alloca markers.
95
+
96
+ declare i8* @llvm.stacksave ()
97
+ declare void @llvm.stackrestore (i8* )
98
+
99
+ ; CHECK-LABEL: define i8* @testStack(
100
+ ; CHECK: entry:
101
+ ; CHECK-NEXT: %save = tail call i8* @llvm.stacksave()
102
+ ; CHECK-NEXT: %obj = alloca i8, i8 %arg
103
+ ; CHECK-NEXT: %0 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call.i)
104
+ ; CHECK-NEXT: call void @llvm.stackrestore(i8* %save)
105
+ ; CHECK-NEXT: %1 = tail call i8* @llvm.objc.retain(i8* %call.i)
106
+ ; CHECK-NEXT: ret i8* %call.i
107
+ ; CHECK-NEXT: }
108
+ define i8* @testStack (i8* %call.i , i8 %arg ) {
109
+ entry:
110
+ %save = tail call i8* @llvm.stacksave ()
111
+ %obj = alloca i8 , i8 %arg
112
+ %0 = tail call i8* @llvm.objc.autoreleaseReturnValue (i8* %call.i ) nounwind
113
+ call void @llvm.stackrestore (i8* %save )
114
+ %1 = tail call i8* @llvm.objc.retainAutoreleasedReturnValue (i8* %call.i ) nounwind
115
+ ret i8* %call.i
116
+ }
0 commit comments