493 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -max-registers-for-gc-values=4 -fixup-allow-gcptr-in-csr=true < %s | FileCheck %s3 4target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"5target triple = "x86_64-pc-linux-gnu"6 7declare i1 @return_i1()8declare void @func()9declare void @consume(ptr addrspace(1))10declare i32 @consume1(i32) gc "statepoint-example"11declare void @consume2(ptr addrspace(1), ptr addrspace(1))12declare void @consume3(float) gc "statepoint-example"13declare float @consume4(i64) gc "statepoint-example"14declare void @consume5(ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1))15 16declare void @use1(ptr addrspace(1), ptr addrspace(1))17 18; test most simple relocate19define i1 @test_relocate(ptr addrspace(1) %a) gc "statepoint-example" {20; CHECK-LABEL: test_relocate:21; CHECK: # %bb.0: # %entry22; CHECK-NEXT: pushq %rbp23; CHECK-NEXT: .cfi_def_cfa_offset 1624; CHECK-NEXT: pushq %rbx25; CHECK-NEXT: .cfi_def_cfa_offset 2426; CHECK-NEXT: pushq %rax27; CHECK-NEXT: .cfi_def_cfa_offset 3228; CHECK-NEXT: .cfi_offset %rbx, -2429; CHECK-NEXT: .cfi_offset %rbp, -1630; CHECK-NEXT: movq %rdi, %rbx31; CHECK-NEXT: callq return_i1@PLT32; CHECK-NEXT: .Ltmp0:33; CHECK-NEXT: movl %eax, %ebp34; CHECK-NEXT: movq %rbx, %rdi35; CHECK-NEXT: callq consume@PLT36; CHECK-NEXT: movl %ebp, %eax37; CHECK-NEXT: addq $8, %rsp38; CHECK-NEXT: .cfi_def_cfa_offset 2439; CHECK-NEXT: popq %rbx40; CHECK-NEXT: .cfi_def_cfa_offset 1641; CHECK-NEXT: popq %rbp42; CHECK-NEXT: .cfi_def_cfa_offset 843; CHECK-NEXT: retq44entry:45 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]46 %rel1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)47 %res1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)48 call void @consume(ptr addrspace(1) %rel1)49 ret i1 %res150}51 52; test pointer variables intermixed with pointer constants53define void @test_mixed(ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c) gc "statepoint-example" {54; CHECK-LABEL: test_mixed:55; CHECK: # %bb.0: # %entry56; CHECK-NEXT: pushq %r1557; CHECK-NEXT: .cfi_def_cfa_offset 1658; CHECK-NEXT: pushq %r1459; CHECK-NEXT: .cfi_def_cfa_offset 2460; CHECK-NEXT: pushq %rbx61; CHECK-NEXT: .cfi_def_cfa_offset 3262; CHECK-NEXT: .cfi_offset %rbx, -3263; CHECK-NEXT: .cfi_offset %r14, -2464; CHECK-NEXT: .cfi_offset %r15, -1665; CHECK-NEXT: movq %rdx, %rbx66; CHECK-NEXT: movq %rsi, %r1467; CHECK-NEXT: movq %rdi, %r1568; CHECK-NEXT: callq func@PLT69; CHECK-NEXT: .Ltmp1:70; CHECK-NEXT: movq %r15, %rdi71; CHECK-NEXT: xorl %esi, %esi72; CHECK-NEXT: movq %r14, %rdx73; CHECK-NEXT: xorl %ecx, %ecx74; CHECK-NEXT: movq %rbx, %r875; CHECK-NEXT: callq consume5@PLT76; CHECK-NEXT: popq %rbx77; CHECK-NEXT: .cfi_def_cfa_offset 2478; CHECK-NEXT: popq %r1479; CHECK-NEXT: .cfi_def_cfa_offset 1680; CHECK-NEXT: popq %r1581; CHECK-NEXT: .cfi_def_cfa_offset 882; CHECK-NEXT: retq83entry:84 %safepoint_token = tail 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) %a, ptr addrspace(1) null, ptr addrspace(1) %b, ptr addrspace(1) null, ptr addrspace(1) %c)]85 %rel1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)86 %rel2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 1, i32 1)87 %rel3 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 2, i32 2)88 %rel4 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 3, i32 3)89 %rel5 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 4, i32 4)90 call void @consume5(ptr addrspace(1) %rel1, ptr addrspace(1) %rel2, ptr addrspace(1) %rel3, ptr addrspace(1) %rel4, ptr addrspace(1) %rel5)91 ret void92}93 94; same as above, but for alloca95define ptr addrspace(1) @test_alloca(ptr addrspace(1) %ptr) gc "statepoint-example" {96; CHECK-LABEL: test_alloca:97; CHECK: # %bb.0: # %entry98; CHECK-NEXT: pushq %r1499; CHECK-NEXT: .cfi_def_cfa_offset 16100; CHECK-NEXT: pushq %rbx101; CHECK-NEXT: .cfi_def_cfa_offset 24102; CHECK-NEXT: pushq %rax103; CHECK-NEXT: .cfi_def_cfa_offset 32104; CHECK-NEXT: .cfi_offset %rbx, -24105; CHECK-NEXT: .cfi_offset %r14, -16106; CHECK-NEXT: movq %rdi, %rbx107; CHECK-NEXT: movq %rdi, (%rsp)108; CHECK-NEXT: callq return_i1@PLT109; CHECK-NEXT: .Ltmp2:110; CHECK-NEXT: movq (%rsp), %r14111; CHECK-NEXT: movq %rbx, %rdi112; CHECK-NEXT: callq consume@PLT113; CHECK-NEXT: movq %r14, %rax114; CHECK-NEXT: addq $8, %rsp115; CHECK-NEXT: .cfi_def_cfa_offset 24116; CHECK-NEXT: popq %rbx117; CHECK-NEXT: .cfi_def_cfa_offset 16118; CHECK-NEXT: popq %r14119; CHECK-NEXT: .cfi_def_cfa_offset 8120; CHECK-NEXT: retq121entry:122 %alloca = alloca ptr addrspace(1), align 8123 store ptr addrspace(1) %ptr, ptr %alloca124 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr %alloca, ptr addrspace(1) %ptr)]125 %rel1 = load ptr addrspace(1), ptr %alloca126 %rel2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 1, i32 1)127 call void @consume(ptr addrspace(1) %rel2)128 ret ptr addrspace(1) %rel1129}130 131; test base != derived132define void @test_base_derived(ptr addrspace(1) %base, ptr addrspace(1) %derived) gc "statepoint-example" {133; CHECK-LABEL: test_base_derived:134; CHECK: # %bb.0:135; CHECK-NEXT: pushq %r14136; CHECK-NEXT: .cfi_def_cfa_offset 16137; CHECK-NEXT: pushq %rbx138; CHECK-NEXT: .cfi_def_cfa_offset 24139; CHECK-NEXT: pushq %rax140; CHECK-NEXT: .cfi_def_cfa_offset 32141; CHECK-NEXT: .cfi_offset %rbx, -24142; CHECK-NEXT: .cfi_offset %r14, -16143; CHECK-NEXT: movq %rsi, %rbx144; CHECK-NEXT: movq %rdi, %r14145; CHECK-NEXT: callq func@PLT146; CHECK-NEXT: .Ltmp3:147; CHECK-NEXT: movq %rbx, %rdi148; CHECK-NEXT: callq consume@PLT149; CHECK-NEXT: addq $8, %rsp150; CHECK-NEXT: .cfi_def_cfa_offset 24151; CHECK-NEXT: popq %rbx152; CHECK-NEXT: .cfi_def_cfa_offset 16153; CHECK-NEXT: popq %r14154; CHECK-NEXT: .cfi_def_cfa_offset 8155; CHECK-NEXT: retq156 %safepoint_token = tail 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)]157 %reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1)158 call void @consume(ptr addrspace(1) %reloc)159 ret void160}161 162; deopt GC pointer not present in GC args goes on reg.163define void @test_deopt_gcpointer(ptr addrspace(1) %a, ptr addrspace(1) %b) gc "statepoint-example" {164; CHECK-LABEL: test_deopt_gcpointer:165; CHECK: # %bb.0:166; CHECK-NEXT: pushq %r14167; CHECK-NEXT: .cfi_def_cfa_offset 16168; CHECK-NEXT: pushq %rbx169; CHECK-NEXT: .cfi_def_cfa_offset 24170; CHECK-NEXT: pushq %rax171; CHECK-NEXT: .cfi_def_cfa_offset 32172; CHECK-NEXT: .cfi_offset %rbx, -24173; CHECK-NEXT: .cfi_offset %r14, -16174; CHECK-NEXT: movq %rsi, %rbx175; CHECK-NEXT: movq %rdi, %r14176; CHECK-NEXT: callq func@PLT177; CHECK-NEXT: .Ltmp4:178; CHECK-NEXT: movq %rbx, %rdi179; CHECK-NEXT: callq consume@PLT180; CHECK-NEXT: addq $8, %rsp181; CHECK-NEXT: .cfi_def_cfa_offset 24182; CHECK-NEXT: popq %rbx183; CHECK-NEXT: .cfi_def_cfa_offset 16184; CHECK-NEXT: popq %r14185; CHECK-NEXT: .cfi_def_cfa_offset 8186; CHECK-NEXT: retq187 %safepoint_token = tail 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) ["deopt" (ptr addrspace(1) %a), "gc-live" (ptr addrspace(1) %b)]188 %rel = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)189 call void @consume(ptr addrspace(1) %rel)190 ret void191}192 193;; Two gc.relocates of the same input, should require only a single spill/fill194define void @test_gcrelocate_uniqueing(ptr addrspace(1) %ptr) gc "statepoint-example" {195; CHECK-LABEL: test_gcrelocate_uniqueing:196; CHECK: # %bb.0:197; CHECK-NEXT: pushq %rbx198; CHECK-NEXT: .cfi_def_cfa_offset 16199; CHECK-NEXT: .cfi_offset %rbx, -16200; CHECK-NEXT: movq %rdi, %rbx201; CHECK-NEXT: callq func@PLT202; CHECK-NEXT: .Ltmp5:203; CHECK-NEXT: movq %rbx, %rdi204; CHECK-NEXT: movq %rbx, %rsi205; CHECK-NEXT: callq consume2@PLT206; CHECK-NEXT: popq %rbx207; CHECK-NEXT: .cfi_def_cfa_offset 8208; CHECK-NEXT: retq209 %tok = tail 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) ["deopt" (ptr addrspace(1) %ptr, i32 undef), "gc-live" (ptr addrspace(1) %ptr, ptr addrspace(1) %ptr)]210 %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0)211 %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 1, i32 1)212 call void @consume2(ptr addrspace(1) %a, ptr addrspace(1) %b)213 ret void214}215 216; Two gc.relocates of a bitcasted pointer should only require a single spill/fill217define void @test_gcptr_uniqueing(ptr addrspace(1) %ptr) gc "statepoint-example" {218; CHECK-LABEL: test_gcptr_uniqueing:219; CHECK: # %bb.0:220; CHECK-NEXT: pushq %rbx221; CHECK-NEXT: .cfi_def_cfa_offset 16222; CHECK-NEXT: .cfi_offset %rbx, -16223; CHECK-NEXT: movq %rdi, %rbx224; CHECK-NEXT: callq func@PLT225; CHECK-NEXT: .Ltmp6:226; CHECK-NEXT: movq %rbx, %rdi227; CHECK-NEXT: movq %rbx, %rsi228; CHECK-NEXT: callq use1@PLT229; CHECK-NEXT: popq %rbx230; CHECK-NEXT: .cfi_def_cfa_offset 8231; CHECK-NEXT: retq232 %tok = tail call token (i64, i32, ptr, i32, i32, ...)233 @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (ptr addrspace(1) %ptr, i32 undef), "gc-live" (ptr addrspace(1) %ptr, ptr addrspace(1) %ptr)]234 %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0)235 %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 1, i32 1)236 call void @use1(ptr addrspace(1) %a, ptr addrspace(1) %b)237 ret void238}239 240;241; Cross-basicblock relocates are handled with spilling for now.242define i1 @test_cross_bb(ptr addrspace(1) %a, i1 %external_cond) gc "statepoint-example" {243; CHECK-LABEL: test_cross_bb:244; CHECK: # %bb.0: # %entry245; CHECK-NEXT: pushq %rbp246; CHECK-NEXT: .cfi_def_cfa_offset 16247; CHECK-NEXT: pushq %rbx248; CHECK-NEXT: .cfi_def_cfa_offset 24249; CHECK-NEXT: pushq %rax250; CHECK-NEXT: .cfi_def_cfa_offset 32251; CHECK-NEXT: .cfi_offset %rbx, -24252; CHECK-NEXT: .cfi_offset %rbp, -16253; CHECK-NEXT: movl %esi, %ebp254; CHECK-NEXT: movq %rdi, %rbx255; CHECK-NEXT: callq return_i1@PLT256; CHECK-NEXT: .Ltmp7:257; CHECK-NEXT: testb $1, %bpl258; CHECK-NEXT: je .LBB7_2259; CHECK-NEXT: # %bb.1: # %left260; CHECK-NEXT: movq %rbx, %rdi261; CHECK-NEXT: movl %eax, %ebx262; CHECK-NEXT: callq consume@PLT263; CHECK-NEXT: movl %ebx, %eax264; CHECK-NEXT: jmp .LBB7_3265; CHECK-NEXT: .LBB7_2: # %right266; CHECK-NEXT: movb $1, %al267; CHECK-NEXT: .LBB7_3: # %right268; CHECK-NEXT: addq $8, %rsp269; CHECK-NEXT: .cfi_def_cfa_offset 24270; CHECK-NEXT: popq %rbx271; CHECK-NEXT: .cfi_def_cfa_offset 16272; CHECK-NEXT: popq %rbp273; CHECK-NEXT: .cfi_def_cfa_offset 8274; CHECK-NEXT: retq275entry:276 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]277 br i1 %external_cond, label %left, label %right278 279left:280 %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)281 %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)282 call void @consume(ptr addrspace(1) %call1)283 ret i1 %call2284 285right:286 ret i1 true287}288 289; No need to check post-regalloc output as it is the same290define i1 @duplicate_reloc() gc "statepoint-example" {291; CHECK-LABEL: duplicate_reloc:292; CHECK: # %bb.0: # %entry293; CHECK-NEXT: pushq %rax294; CHECK-NEXT: .cfi_def_cfa_offset 16295; CHECK-NEXT: callq func@PLT296; CHECK-NEXT: .Ltmp8:297; CHECK-NEXT: callq func@PLT298; CHECK-NEXT: .Ltmp9:299; CHECK-NEXT: movb $1, %al300; CHECK-NEXT: popq %rcx301; CHECK-NEXT: .cfi_def_cfa_offset 8302; CHECK-NEXT: retq303entry:304 %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)]305 %base = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)306 %derived = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1)307 %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)]308 %base_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 0)309 %derived_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 1)310 %cmp1 = icmp eq ptr addrspace(1) %base_reloc, null311 %cmp2 = icmp eq ptr addrspace(1) %derived_reloc, null312 %cmp = and i1 %cmp1, %cmp2313 ret i1 %cmp314}315 316; Vectors cannot go in VRegs317; No need to check post-regalloc output as it is lowered using old scheme318define <2 x ptr addrspace(1)> @test_vector(<2 x ptr addrspace(1)> %obj) gc "statepoint-example" {319; CHECK-LABEL: test_vector:320; CHECK: # %bb.0: # %entry321; CHECK-NEXT: subq $24, %rsp322; CHECK-NEXT: .cfi_def_cfa_offset 32323; CHECK-NEXT: movaps %xmm0, (%rsp)324; CHECK-NEXT: callq func@PLT325; CHECK-NEXT: .Ltmp10:326; CHECK-NEXT: movaps (%rsp), %xmm0327; CHECK-NEXT: addq $24, %rsp328; CHECK-NEXT: .cfi_def_cfa_offset 8329; CHECK-NEXT: retq330entry:331 %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" (<2 x ptr addrspace(1)> %obj)]332 %obj.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 0, i32 0) ; (%obj, %obj)333 ret <2 x ptr addrspace(1)> %obj.relocated334}335 336 337; test limit on amount of vregs338define void @test_limit(ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr addrspace(1) %d, ptr addrspace(1) %e) gc "statepoint-example" {339; CHECK-LABEL: test_limit:340; CHECK: # %bb.0: # %entry341; CHECK-NEXT: pushq %r15342; CHECK-NEXT: .cfi_def_cfa_offset 16343; CHECK-NEXT: pushq %r14344; CHECK-NEXT: .cfi_def_cfa_offset 24345; CHECK-NEXT: pushq %r12346; CHECK-NEXT: .cfi_def_cfa_offset 32347; CHECK-NEXT: pushq %rbx348; CHECK-NEXT: .cfi_def_cfa_offset 40349; CHECK-NEXT: pushq %rax350; CHECK-NEXT: .cfi_def_cfa_offset 48351; CHECK-NEXT: .cfi_offset %rbx, -40352; CHECK-NEXT: .cfi_offset %r12, -32353; CHECK-NEXT: .cfi_offset %r14, -24354; CHECK-NEXT: .cfi_offset %r15, -16355; CHECK-NEXT: movq %r8, %rbx356; CHECK-NEXT: movq %rcx, %r14357; CHECK-NEXT: movq %rdx, %r15358; CHECK-NEXT: movq %rsi, %r12359; CHECK-NEXT: movq %rdi, (%rsp)360; CHECK-NEXT: callq func@PLT361; CHECK-NEXT: .Ltmp11:362; CHECK-NEXT: movq (%rsp), %rdi363; CHECK-NEXT: movq %r12, %rsi364; CHECK-NEXT: movq %r15, %rdx365; CHECK-NEXT: movq %r14, %rcx366; CHECK-NEXT: movq %rbx, %r8367; CHECK-NEXT: callq consume5@PLT368; CHECK-NEXT: addq $8, %rsp369; CHECK-NEXT: .cfi_def_cfa_offset 40370; CHECK-NEXT: popq %rbx371; CHECK-NEXT: .cfi_def_cfa_offset 32372; CHECK-NEXT: popq %r12373; CHECK-NEXT: .cfi_def_cfa_offset 24374; CHECK-NEXT: popq %r14375; CHECK-NEXT: .cfi_def_cfa_offset 16376; CHECK-NEXT: popq %r15377; CHECK-NEXT: .cfi_def_cfa_offset 8378; CHECK-NEXT: retq379entry:380 %safepoint_token = tail 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) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr addrspace(1) %d, ptr addrspace(1) %e)]381 %rel1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)382 %rel2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 1, i32 1)383 %rel3 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 2, i32 2)384 %rel4 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 3, i32 3)385 %rel5 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 4, i32 4)386 call void @consume5(ptr addrspace(1) %rel1, ptr addrspace(1) %rel2, ptr addrspace(1) %rel3, ptr addrspace(1) %rel4, ptr addrspace(1) %rel5)387 ret void388}389 390; test ISEL for constant base pointer - must properly tie operands391define void @test_const_base(ptr addrspace(1) %a) gc "statepoint-example" {392; CHECK-LABEL: test_const_base:393; CHECK: # %bb.0: # %entry394; CHECK-NEXT: pushq %rbx395; CHECK-NEXT: .cfi_def_cfa_offset 16396; CHECK-NEXT: .cfi_offset %rbx, -16397; CHECK-NEXT: movq %rdi, %rbx398; CHECK-NEXT: callq func@PLT399; CHECK-NEXT: .Ltmp12:400; CHECK-NEXT: movq %rbx, %rdi401; CHECK-NEXT: callq consume@PLT402; CHECK-NEXT: popq %rbx403; CHECK-NEXT: .cfi_def_cfa_offset 8404; CHECK-NEXT: retq405entry:406 %token1 = tail 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) ["deopt" (i32 0, i32 1, i32 7, ptr addrspace(1) null, i32 9), "gc-live" (ptr addrspace(1) null, ptr addrspace(1) %a)]407 %rel = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token1, i32 0, i32 1)408 call void @consume(ptr addrspace(1) %rel)409 ret void410}411 412; test multiple statepoints/relocates within single block.413; relocates must be properly scheduled w.r.t. statepoints414define void @test_sched(float %0, i32 %1, ptr addrspace(1) %2) gc "statepoint-example" {415; CHECK-LABEL: test_sched:416; CHECK: # %bb.0: # %entry417; CHECK-NEXT: pushq %rbp418; CHECK-NEXT: .cfi_def_cfa_offset 16419; CHECK-NEXT: pushq %rbx420; CHECK-NEXT: .cfi_def_cfa_offset 24421; CHECK-NEXT: subq $24, %rsp422; CHECK-NEXT: .cfi_def_cfa_offset 48423; CHECK-NEXT: .cfi_offset %rbx, -24424; CHECK-NEXT: .cfi_offset %rbp, -16425; CHECK-NEXT: movq %rsi, %rbx426; CHECK-NEXT: movl %edi, %ebp427; CHECK-NEXT: movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill428; CHECK-NEXT: callq consume3@PLT429; CHECK-NEXT: .Ltmp13:430; CHECK-NEXT: xorps %xmm0, %xmm0431; CHECK-NEXT: cvtsi2sd %ebp, %xmm0432; CHECK-NEXT: movsd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill433; CHECK-NEXT: nopl 8(%rax,%rax)434; CHECK-NEXT: .Ltmp14:435; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload436; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero437; CHECK-NEXT: movss %xmm0, (%rsp)438; CHECK-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 8-byte Reload439; CHECK-NEXT: # xmm0 = mem[0],zero440; CHECK-NEXT: movsd %xmm0, {{[0-9]+}}(%rsp)441; CHECK-NEXT: nopl 8(%rax,%rax)442; CHECK-NEXT: .Ltmp15:443; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload444; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero445; CHECK-NEXT: movss %xmm0, (%rsp)446; CHECK-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 8-byte Reload447; CHECK-NEXT: # xmm1 = mem[0],zero448; CHECK-NEXT: movsd %xmm1, {{[0-9]+}}(%rsp)449; CHECK-NEXT: nopl 8(%rax,%rax)450; CHECK-NEXT: .Ltmp16:451; CHECK-NEXT: xorl %eax, %eax452; CHECK-NEXT: xorpd %xmm0, %xmm0453; CHECK-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 8-byte Reload454; CHECK-NEXT: # xmm1 = mem[0],zero455; CHECK-NEXT: ucomisd %xmm0, %xmm1456; CHECK-NEXT: movabsq $9223372036854775807, %rdi # imm = 0x7FFFFFFFFFFFFFFF457; CHECK-NEXT: cmovbeq %rax, %rdi458; CHECK-NEXT: movsd %xmm1, {{[0-9]+}}(%rsp)459; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload460; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero461; CHECK-NEXT: movss %xmm0, (%rsp)462; CHECK-NEXT: nopl 8(%rax,%rax)463; CHECK-NEXT: .Ltmp17:464; CHECK-NEXT: addq $24, %rsp465; CHECK-NEXT: .cfi_def_cfa_offset 24466; CHECK-NEXT: popq %rbx467; CHECK-NEXT: .cfi_def_cfa_offset 16468; CHECK-NEXT: popq %rbp469; CHECK-NEXT: .cfi_def_cfa_offset 8470; CHECK-NEXT: retq471entry:472 %token0 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 0, ptr nonnull elementtype(void (float)) @consume3, i32 1, i32 0, float %0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %2) ]473 %reloc1 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token0, i32 0, i32 0) ; (%2, %2)474 %tmp1 = sitofp i32 %1 to double475 %to_max.i29 = fcmp ogt double %tmp1, 0.000000e+00476 %token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(i32 (i32)) @consume1, i32 1, i32 0, i32 undef, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %reloc1) ]477 %reloc2 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token1, i32 0, i32 0) ; (%reloc1, %reloc1)478 %reloc3 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token1, i32 0, i32 0) ; (%reloc1, %reloc1)479 %token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(i32 (i32)) @consume1, i32 1, i32 0, i32 undef, i32 0, i32 0) [ "deopt"(float %0, double %tmp1), "gc-live"(ptr addrspace(1) %reloc2, ptr addrspace(1) %reloc3) ]480 %reloc4 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token2, i32 0, i32 0) ; (%reloc3, %reloc2)481 %reloc5 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token2, i32 1, i32 1) ; (%reloc3, %reloc3)482 %token3 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(void (float)) @consume3, i32 1, i32 0, float %0, i32 0, i32 0) [ "deopt"(float %0, double %tmp1), "gc-live"(ptr addrspace(1) %reloc4, ptr addrspace(1) %reloc5) ]483 %reloc6 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token3, i32 1, i32 0) ; (%reloc5, %reloc4)484 %tmp5 = select i1 %to_max.i29, i64 9223372036854775807, i64 0485 %token4 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(float (i64)) @consume4, i32 1, i32 0, i64 %tmp5, i32 0, i32 0) [ "deopt"(float %0, double %tmp1), "gc-live"() ]486ret void487}488 489declare token @llvm.experimental.gc.statepoint.p0(i64 immarg, i32 immarg, ptr, i32 immarg, i32 immarg, ...)490declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)491declare <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token, i32, i32)492declare i1 @llvm.experimental.gc.result.i1(token)493