1
- ; RUN: llc -mtriple=x86_64-apple-macosx -o - %s | FileCheck --check-prefix=CHECK %s
1
+ ; RUN: llc -mtriple=x86_64-apple-macosx -verify-machineinstrs - o - %s | FileCheck --check-prefix=CHECK %s
2
2
3
3
; TODO: support marker generation with GlobalISel
4
4
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
@@ -23,16 +23,33 @@ declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
23
23
@g = global i8* null , align 8
24
24
@fptr = global i8* ()* null , align 8
25
25
26
- define i8* @rv_marker_1 () {
27
- ; CHECK-LABEL: rv_marker_1 :
26
+ define i8* @rv_marker_1_retain () {
27
+ ; CHECK-LABEL: rv_marker_1_retain :
28
28
; CHECK: pushq %rax
29
29
; CHECK-NEXT: .cfi_def_cfa_offset 16
30
30
; CHECK-NEXT: callq _foo1
31
+ ; CHECK-NEXT: movq %rax, %rdi
32
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
33
+ ; CHECK-NEXT: popq %rcx
34
+ ; CHECK-NEXT: retq
35
+ ;
36
+ entry:
37
+ %call = call i8* @foo1 () [ "clang.arc.attachedcall" (i64 0 ) ]
38
+ ret i8* %call
39
+ }
40
+
41
+ define i8* @rv_marker_1_claim () {
42
+ ; CHECK-LABEL: rv_marker_1_claim:
43
+ ; CHECK: pushq %rax
44
+ ; CHECK-NEXT: .cfi_def_cfa_offset 16
45
+ ; CHECK-NEXT: callq _foo1
46
+ ; CHECK-NEXT: movq %rax, %rdi
47
+ ; CHECK-NEXT: callq _objc_unsafeClaimAutoreleasedReturnValue
31
48
; CHECK-NEXT: popq %rcx
32
49
; CHECK-NEXT: retq
33
50
;
34
51
entry:
35
- %call = call "rv_marker" i8* @foo1 ()
52
+ %call = call i8* @foo1 () [ "clang.arc.attachedcall" ( i64 1 ) ]
36
53
ret i8* %call
37
54
}
38
55
@@ -45,13 +62,15 @@ define void @rv_marker_2_select(i32 %c) {
45
62
; CHECK-NEXT: adcl $0, %edi
46
63
; CHECK-NEXT: callq _foo0
47
64
; CHECK-NEXT: movq %rax, %rdi
65
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
66
+ ; CHECK-NEXT: movq %rax, %rdi
48
67
; CHECK-NEXT: popq %rax
49
68
; CHECK-NEXT: jmp _foo2
50
69
;
51
70
entry:
52
71
%tobool.not = icmp eq i32 %c , 0
53
72
%.sink = select i1 %tobool.not , i32 2 , i32 1
54
- %call1 = call "rv_marker" i8* @foo0 (i32 %.sink )
73
+ %call1 = call i8* @foo0 (i32 %.sink ) [ "clang.arc.attachedcall" ( i64 0 ) ]
55
74
tail call void @foo2 (i8* %call1 )
56
75
ret void
57
76
}
@@ -67,11 +86,13 @@ define void @rv_marker_3() personality i8* bitcast (i32 (...)* @__gxx_personalit
67
86
; CHECK-NEXT: .cfi_offset %rbx, -24
68
87
; CHECK-NEXT: .cfi_offset %r14, -16
69
88
; CHECK-NEXT: callq _foo1
89
+ ; CHECK-NEXT: movq %rax, %rdi
90
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
70
91
; CHECK-NEXT: movq %rax, %rbx
71
92
; CHECK-NEXT: Ltmp0:
72
93
;
73
94
entry:
74
- %call = call "rv_marker" i8* @foo1 ()
95
+ %call = call i8* @foo1 () [ "clang.arc.attachedcall" ( i64 0 ) ]
75
96
invoke void @objc_object (i8* %call ) #5
76
97
to label %invoke.cont unwind label %lpad
77
98
@@ -98,13 +119,15 @@ define void @rv_marker_4() personality i8* bitcast (i32 (...)* @__gxx_personalit
98
119
; CHECK-NEXT: .cfi_offset %r14, -16
99
120
; CHECK-NEXT: Ltmp3:
100
121
; CHECK-NEXT: callq _foo1
122
+ ; CHECK-NEXT: movq %rax, %rdi
123
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
101
124
; CHECK-NEXT: Ltmp4:
102
125
;
103
126
entry:
104
127
%s = alloca %struct.S , align 1
105
128
%0 = getelementptr inbounds %struct.S , %struct.S* %s , i64 0 , i32 0
106
129
call void @llvm.lifetime.start.p0i8 (i64 1 , i8* nonnull %0 ) #2
107
- %call = invoke "rv_marker" i8* @foo1 ()
130
+ %call = invoke i8* @foo1 () [ "clang.arc.attachedcall" ( i64 0 ) ]
108
131
to label %invoke.cont unwind label %lpad
109
132
110
133
invoke .cont: ; preds = %entry
@@ -135,12 +158,16 @@ ehcleanup: ; preds = %lpad1, %lpad
135
158
resume { i8* , i32 } %.pn
136
159
}
137
160
161
+ ; TODO: This should use "callq *_fptr(%rip)".
138
162
define i8* @rv_marker_5_indirect_call () {
139
163
; CHECK-LABEL: rv_marker_5_indirect_call
140
164
; CHECK: pushq %rbx
141
165
; CHECK-NEXT: .cfi_def_cfa_offset 16
142
166
; CHECK-NEXT: .cfi_offset %rbx, -16
143
- ; CHECK-NEXT: callq *_fptr(%rip)
167
+ ; CHECK-NEXT: movq _fptr(%rip), %rax
168
+ ; CHECK-NEXT: callq *%rax
169
+ ; CHECK-NEXT: movq %rax, %rdi
170
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
144
171
; CHECK-NEXT: movq %rax, %rbx
145
172
; CHECK-NEXT: movq %rax, %rdi
146
173
; CHECK-NEXT: callq _foo2
@@ -149,13 +176,13 @@ define i8* @rv_marker_5_indirect_call() {
149
176
; CHECK-NEXT: retq
150
177
;
151
178
entry:
152
- %0 = load i8* ()*, i8* ()** @fptr , align 8
153
- %call = call "rv_marker" i8* %0 ()
179
+ %lv = load i8* ()*, i8* ()** @fptr , align 8
180
+ %call = call i8* %lv () [ "clang.arc.attachedcall" ( i64 0 ) ]
154
181
tail call void @foo2 (i8* %call )
155
182
ret i8* %call
156
183
}
157
184
158
- declare void @foo (i64 , i64 , i64 )
185
+ declare i8* @foo (i64 , i64 , i64 )
159
186
160
187
define void @rv_marker_multiarg (i64 %a , i64 %b , i64 %c ) {
161
188
; CHECK-LABEL: rv_marker_multiarg
@@ -165,11 +192,28 @@ define void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) {
165
192
; CHECK-NEXT: movq %rdx, %rdi
166
193
; CHECK-NEXT: movq %rax, %rdx
167
194
; CHECK-NEXT: callq _foo
195
+ ; CHECK-NEXT: movq %rax, %rdi
196
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
168
197
; CHECK-NEXT: popq %rax
169
198
; CHECK-NEXT: retq
170
199
;
171
- call "rv_marker" void @foo (i64 %c , i64 %b , i64 %a )
200
+ %r = call i8* @foo (i64 %c , i64 %b , i64 %a ) [ "clang.arc.attachedcall" ( i64 0 ) ]
172
201
ret void
173
202
}
174
203
204
+ define void @test_nonlazybind () {
205
+ ; CHECK-LABEL: _test_nonlazybind:
206
+ ; CHECK: bb.0:
207
+ ; CHECK-NEXT: pushq %rax
208
+ ; CHECK-NEXT: .cfi_def_cfa_offset 16
209
+ ; CHECK-NEXT: callq *_foo_nonlazybind@GOTPCREL(%rip)
210
+ ; CHECK-NEXT: movq %rax, %rdi
211
+ ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue
212
+ ;
213
+ %call1 = notail call i8* @foo_nonlazybind () [ "clang.arc.attachedcall" (i64 0 ) ]
214
+ ret void
215
+ }
216
+
217
+ declare i8* @foo_nonlazybind () nonlazybind
218
+
175
219
declare i32 @__gxx_personality_v0 (...)
0 commit comments