1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs < %s | FileCheck %s 3 4; Check that we can export values of "duplicated" gc.relocates without a crash 5; "duplicate" here means maps to same SDValue. We previously had an 6; optimization which tried to reduce number of spills/stackmap entries in such 7; cases, but it incorrectly handled exports across basis block boundaries 8; leading to a crash in this case. 9 10target triple = "x86_64-pc-linux-gnu" 11 12declare void @func() 13 14define i1 @test() gc "statepoint-example" { 15; CHECK-LABEL: test: 16; CHECK: # %bb.0: # %entry 17; CHECK-NEXT: pushq %rax 18; CHECK-NEXT: .cfi_def_cfa_offset 16 19; CHECK-NEXT: callq func@PLT 20; CHECK-NEXT: .Ltmp0: 21; CHECK-NEXT: callq func@PLT 22; CHECK-NEXT: .Ltmp1: 23; CHECK-NEXT: movb $1, %al 24; CHECK-NEXT: popq %rcx 25; CHECK-NEXT: .cfi_def_cfa_offset 8 26; CHECK-NEXT: retq 27entry: 28 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) null, ptr addrspace(1) null)] 29 %base = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 30 %derived = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1) 31 %safepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %base, ptr addrspace(1) %derived)] 32 br label %next 33 34next: 35 %base_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 0) 36 %derived_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 1) 37 %cmp1 = icmp eq ptr addrspace(1) %base_reloc, null 38 %cmp2 = icmp eq ptr addrspace(1) %derived_reloc, null 39 %cmp = and i1 %cmp1, %cmp2 40 ret i1 %cmp 41} 42 43; Showing redundant fill on first statepoint and spill/fill on second one 44define i1 @test2(ptr addrspace(1) %arg) gc "statepoint-example" { 45; CHECK-LABEL: test2: 46; CHECK: # %bb.0: # %entry 47; CHECK-NEXT: pushq %rax 48; CHECK-NEXT: .cfi_def_cfa_offset 16 49; CHECK-NEXT: movq %rdi, (%rsp) 50; CHECK-NEXT: callq func@PLT 51; CHECK-NEXT: .Ltmp2: 52; CHECK-NEXT: callq func@PLT 53; CHECK-NEXT: .Ltmp3: 54; CHECK-NEXT: cmpq $0, (%rsp) 55; CHECK-NEXT: sete %al 56; CHECK-NEXT: popq %rcx 57; CHECK-NEXT: .cfi_def_cfa_offset 8 58; CHECK-NEXT: retq 59entry: 60 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %arg, ptr addrspace(1) %arg)] 61 %base = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 62 %derived = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1) 63 %safepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %base, ptr addrspace(1) %derived)] 64 br label %next 65 66next: 67 %base_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 0) 68 %derived_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 1) 69 %cmp1 = icmp eq ptr addrspace(1) %base_reloc, null 70 %cmp2 = icmp eq ptr addrspace(1) %derived_reloc, null 71 %cmp = and i1 %cmp1, %cmp2 72 ret i1 %cmp 73} 74 75 76declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) 77declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) 78