1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs < %s | FileCheck %s 3 4target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-pc-linux-gnu" 6 7declare void @use(...) 8declare void @f() 9declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) 10declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) #3 11 12;; Two gc.relocates of the same input, should require only a single spill/fill 13define void @test_gcrelocate_uniqueing(ptr addrspace(1) %ptr) gc "statepoint-example" { 14; CHECK-LABEL: test_gcrelocate_uniqueing: 15; CHECK: # %bb.0: 16; CHECK-NEXT: pushq %rax 17; CHECK-NEXT: .cfi_def_cfa_offset 16 18; CHECK-NEXT: movq %rdi, (%rsp) 19; CHECK-NEXT: callq f@PLT 20; CHECK-NEXT: .Ltmp0: 21; CHECK-NEXT: movq (%rsp), %rdi 22; CHECK-NEXT: movq %rdi, %rsi 23; CHECK-NEXT: xorl %eax, %eax 24; CHECK-NEXT: callq use@PLT 25; CHECK-NEXT: popq %rax 26; CHECK-NEXT: .cfi_def_cfa_offset 8 27; CHECK-NEXT: retq 28 %tok = tail call token (i64, i32, ptr, i32, i32, ...) 29 @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %ptr, ptr addrspace(1) %ptr), "deopt" (ptr addrspace(1) %ptr, i32 undef)] 30 %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 31 %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 1, i32 1) 32 call void (...) @use(ptr addrspace(1) %a, ptr addrspace(1) %b) 33 ret void 34} 35 36;; Two gc.relocates of a bitcasted pointer should only require a single spill/fill 37define void @test_gcptr_uniqueing(ptr addrspace(1) %ptr) gc "statepoint-example" { 38; CHECK-LABEL: test_gcptr_uniqueing: 39; CHECK: # %bb.0: 40; CHECK-NEXT: pushq %rax 41; CHECK-NEXT: .cfi_def_cfa_offset 16 42; CHECK-NEXT: movq %rdi, (%rsp) 43; CHECK-NEXT: callq f@PLT 44; CHECK-NEXT: .Ltmp1: 45; CHECK-NEXT: movq (%rsp), %rdi 46; CHECK-NEXT: movq %rdi, %rsi 47; CHECK-NEXT: xorl %eax, %eax 48; CHECK-NEXT: callq use@PLT 49; CHECK-NEXT: popq %rax 50; CHECK-NEXT: .cfi_def_cfa_offset 8 51; CHECK-NEXT: retq 52 %tok = tail call token (i64, i32, ptr, i32, i32, ...) 53 @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %ptr, ptr addrspace(1) %ptr), "deopt" (ptr addrspace(1) %ptr, i32 undef)] 54 %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 55 %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 1, i32 1) 56 call void (...) @use(ptr addrspace(1) %a, ptr addrspace(1) %b) 57 ret void 58} 59 60;; A GC value is not dead, and does need to be spill (but not filed) if 61;; that same value is also in the deopt list. 62define void @test_deopt_use(ptr addrspace(1) %ptr) gc "statepoint-example" { 63; CHECK-LABEL: test_deopt_use: 64; CHECK: # %bb.0: 65; CHECK-NEXT: pushq %rax 66; CHECK-NEXT: .cfi_def_cfa_offset 16 67; CHECK-NEXT: movq %rdi, (%rsp) 68; CHECK-NEXT: callq f@PLT 69; CHECK-NEXT: .Ltmp2: 70; CHECK-NEXT: popq %rax 71; CHECK-NEXT: .cfi_def_cfa_offset 8 72; CHECK-NEXT: retq 73 tail call token (i64, i32, ptr, i32, i32, ...) 74 @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %ptr), "deopt" (ptr addrspace(1) %ptr, i32 undef)] 75 ret void 76} 77 78;; A GC value which is truely unused does not need to spilled or filled. 79define void @test_dse(ptr addrspace(1) %ptr) gc "statepoint-example" { 80; CHECK-LABEL: test_dse: 81; CHECK: # %bb.0: 82; CHECK-NEXT: pushq %rax 83; CHECK-NEXT: .cfi_def_cfa_offset 16 84; CHECK-NEXT: callq f@PLT 85; CHECK-NEXT: .Ltmp3: 86; CHECK-NEXT: popq %rax 87; CHECK-NEXT: .cfi_def_cfa_offset 8 88; CHECK-NEXT: retq 89 tail call token (i64, i32, ptr, i32, i32, ...) 90 @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %ptr)] 91 ret void 92} 93