270 lines · plain
1; RUN: llc -mtriple=x86_64-apple-macosx -verify-machineinstrs -o - %s | FileCheck --check-prefix=CHECK %s2; RUN: llc -mtriple=x86_64-windows-msvc -verify-machineinstrs -o - %s | FileCheck --check-prefix=WINABI %s3 4; TODO: support marker generation with GlobalISel5target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"6 7declare ptr @foo0(i32)8declare ptr @foo1()9 10declare void @llvm.objc.release(ptr)11declare void @objc_object(ptr)12 13declare void @foo2(ptr)14 15declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)16 17declare ptr @_ZN1SD1Ev(ptr nonnull dereferenceable(1))18 19declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)20 21 22%struct.S = type { i8 }23 24@g = global ptr null, align 825@fptr = global ptr null, align 826 27define ptr @rv_marker_1_retain() {28; CHECK-LABEL: rv_marker_1_retain:29; CHECK: pushq %rax30; CHECK-NEXT: .cfi_def_cfa_offset 1631; CHECK-NEXT: callq _foo132; CHECK-NEXT: movq %rax, %rdi33; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue34; CHECK-NEXT: popq %rcx35; CHECK-NEXT: retq36;37; WINABI-LABEL: rv_marker_1_retain:38; WINABI: callq foo139; WINABI-NEXT: movq %rax, %rcx40; WINABI-NEXT: callq objc_retainAutoreleasedReturnValue41; WINABI-NEXT: nop42;43entry:44 %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]45 ret ptr %call46}47 48define ptr @rv_marker_1_unsafeClaim() {49; CHECK-LABEL: rv_marker_1_unsafeClaim:50; CHECK: pushq %rax51; CHECK-NEXT: .cfi_def_cfa_offset 1652; CHECK-NEXT: callq _foo153; CHECK-NEXT: movq %rax, %rdi54; CHECK-NEXT: callq _objc_unsafeClaimAutoreleasedReturnValue55; CHECK-NEXT: popq %rcx56; CHECK-NEXT: retq57;58entry:59 %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_unsafeClaimAutoreleasedReturnValue) ]60 ret ptr %call61}62 63define void @rv_marker_2_select(i32 %c) {64; CHECK-LABEL: rv_marker_2_select:65; CHECK: pushq %rax66; CHECK-NEXT: .cfi_def_cfa_offset 1667; CHECK-NEXT: xorl %eax, %eax68; CHECK-NEXT: cmpl $1, %edi69; CHECK-NEXT: adcl $1, %eax70; CHECK-NEXT: movl %eax, %edi71; CHECK-NEXT: callq _foo072; CHECK-NEXT: movq %rax, %rdi73; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue74; CHECK-NEXT: movq %rax, %rdi75; CHECK-NEXT: popq %rax76; CHECK-NEXT: jmp _foo277;78entry:79 %tobool.not = icmp eq i32 %c, 080 %.sink = select i1 %tobool.not, i32 2, i32 181 %call1 = call ptr @foo0(i32 %.sink) [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]82 tail call void @foo2(ptr %call1)83 ret void84}85 86define void @rv_marker_3() personality ptr @__gxx_personality_v0 {87; CHECK-LABEL: rv_marker_388; CHECK: pushq %r1489; CHECK-NEXT: .cfi_def_cfa_offset 1690; CHECK-NEXT: pushq %rbx91; CHECK-NEXT: .cfi_def_cfa_offset 2492; CHECK-NEXT: pushq %rax93; CHECK-NEXT: .cfi_def_cfa_offset 3294; CHECK-NEXT: .cfi_offset %rbx, -2495; CHECK-NEXT: .cfi_offset %r14, -1696; CHECK-NEXT: callq _foo197; CHECK-NEXT: movq %rax, %rdi98; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue99; CHECK-NEXT: movq %rax, %rbx100; CHECK-NEXT: Ltmp0:101;102entry:103 %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]104 invoke void @objc_object(ptr %call) #5105 to label %invoke.cont unwind label %lpad106 107invoke.cont: ; preds = %entry108 tail call void @llvm.objc.release(ptr %call)109 ret void110 111lpad: ; preds = %entry112 %0 = landingpad { ptr, i32 }113 cleanup114 tail call void @llvm.objc.release(ptr %call)115 resume { ptr, i32 } %0116}117 118define void @rv_marker_4() personality ptr @__gxx_personality_v0 {119; CHECK-LABEL: rv_marker_4120; CHECK: pushq %r14121; CHECK-NEXT: .cfi_def_cfa_offset 16122; CHECK-NEXT: pushq %rbx123; CHECK-NEXT: .cfi_def_cfa_offset 24124; CHECK-NEXT: pushq %rax125; CHECK-NEXT: .cfi_def_cfa_offset 32126; CHECK-NEXT: .cfi_offset %rbx, -24127; CHECK-NEXT: .cfi_offset %r14, -16128; CHECK-NEXT: Ltmp3:129; CHECK-NEXT: callq _foo1130; CHECK-NEXT: movq %rax, %rdi131; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue132; CHECK-NEXT: Ltmp4:133;134entry:135 %s = alloca %struct.S, align 1136 call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %s) #2137 %call = invoke ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]138 to label %invoke.cont unwind label %lpad139 140invoke.cont: ; preds = %entry141 invoke void @objc_object(ptr %call) #5142 to label %invoke.cont2 unwind label %lpad1143 144invoke.cont2: ; preds = %invoke.cont145 tail call void @llvm.objc.release(ptr %call)146 %call3 = call ptr @_ZN1SD1Ev(ptr nonnull dereferenceable(1) %s)147 call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %s)148 ret void149 150lpad: ; preds = %entry151 %0 = landingpad { ptr, i32 }152 cleanup153 br label %ehcleanup154 155lpad1: ; preds = %invoke.cont156 %1 = landingpad { ptr, i32 }157 cleanup158 tail call void @llvm.objc.release(ptr %call)159 br label %ehcleanup160 161ehcleanup: ; preds = %lpad1, %lpad162 %.pn = phi { ptr, i32 } [ %1, %lpad1 ], [ %0, %lpad ]163 %call4 = call ptr @_ZN1SD1Ev(ptr nonnull dereferenceable(1) %s)164 call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %s)165 resume { ptr, i32 } %.pn166}167 168; TODO: This should use "callq *_fptr(%rip)".169define ptr @rv_marker_5_indirect_call() {170; CHECK-LABEL: rv_marker_5_indirect_call171; CHECK: pushq %rbx172; CHECK-NEXT: .cfi_def_cfa_offset 16173; CHECK-NEXT: .cfi_offset %rbx, -16174; CHECK-NEXT: movq _fptr(%rip), %rax175; CHECK-NEXT: callq *%rax176; CHECK-NEXT: movq %rax, %rdi177; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue178; CHECK-NEXT: movq %rax, %rbx179; CHECK-NEXT: movq %rax, %rdi180; CHECK-NEXT: callq _foo2181; CHECK-NEXT: movq %rbx, %rax182; CHECK-NEXT: popq %rbx183; CHECK-NEXT: retq184;185entry:186 %lv = load ptr, ptr @fptr, align 8187 %call = call ptr %lv() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]188 tail call void @foo2(ptr %call)189 ret ptr %call190}191 192declare ptr @foo(i64, i64, i64)193 194define void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) {195; CHECK-LABEL: rv_marker_multiarg196; CHECK: pushq %rax197; CHECK-NEXT: .cfi_def_cfa_offset 16198; CHECK-NEXT: movq %rdi, %rax199; CHECK-NEXT: movq %rdx, %rdi200; CHECK-NEXT: movq %rax, %rdx201; CHECK-NEXT: callq _foo202; CHECK-NEXT: movq %rax, %rdi203; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue204; CHECK-NEXT: popq %rax205; CHECK-NEXT: retq206;207 %r = call ptr @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]208 ret void209}210 211define void @test_nonlazybind() {212; CHECK-LABEL: _test_nonlazybind:213; CHECK: bb.0:214; CHECK-NEXT: pushq %rax215; CHECK-NEXT: .cfi_def_cfa_offset 16216; CHECK-NEXT: callq *_foo_nonlazybind@GOTPCREL(%rip)217; CHECK-NEXT: movq %rax, %rdi218; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue219;220 %call1 = notail call ptr @foo_nonlazybind() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]221 ret void222}223 224declare ptr @foo_nonlazybind() nonlazybind225 226declare ptr @objc_retainAutoreleasedReturnValue(ptr)227declare ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr)228declare i32 @__gxx_personality_v0(...)229 230declare ptr @fn1()231declare ptr @fn2()232 233define ptr @rv_marker_block_placement(i1 %c.0) {234; CHECK-LABEL: _rv_marker_block_placement:235; CHECK: pushq %rax236; CHECK-NEXT: .cfi_def_cfa_offset 16237; CHECK-NEXT: testb $1, %dil238; CHECK-NEXT: je LBB8_2239 240; CHECK-NEXT: ## %bb.1:241; CHECK-NEXT: callq _fn1242; CHECK-NEXT: movq %rax, %rdi243; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue244; CHECK-NEXT: jmp LBB8_3245 246; CHECK-NEXT: LBB8_2:247; CHECK-NEXT: callq _fn2248; CHECK-NEXT: movq %rax, %rdi249; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue250 251; CHECK-NEXT: LBB8_3:252; CHECK-NEXT: xorl %eax, %eax253; CHECK-NEXT: popq %rcx254; CHECK-NEXT: retq255;256entry:257 br i1 %c.0, label %then, label %else258 259then:260 %call.0 = notail call ptr @fn1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]261 br label %exit262 263else:264 %call.1 = notail call ptr @fn2() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]265 br label %exit266 267exit:268 ret ptr null269}270