130 lines · plain
1; RUN: llc -verify-machineinstrs < %s | FileCheck %s2; This file contains a collection of basic tests to ensure we didn't3; screw up normal call lowering when a statepoint is a GC transition.4 5target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"6target triple = "x86_64-pc-linux-gnu"7 8declare zeroext i1 @return_i1()9declare zeroext i32 @return_i32()10declare zeroext i32 @return_i32_with_args(i32, ptr)11declare ptr @return_i32ptr()12declare float @return_float()13declare void @varargf(i32, ...)14 15define i1 @test_i1_return() gc "statepoint-example" {16; CHECK-LABEL: test_i1_return17; This is just checking that a i1 gets lowered normally when there's no extra18; state arguments to the statepoint19; CHECK: pushq %rax20; CHECK: callq return_i121; CHECK: popq %rcx22; CHECK: retq23entry:24 %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 1, i32 0, i32 0)25 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)26 ret i1 %call127}28 29define i32 @test_i32_return() gc "statepoint-example" {30; CHECK-LABEL: test_i32_return31; CHECK: pushq %rax32; CHECK: callq return_i3233; CHECK: popq %rcx34; CHECK: retq35entry:36 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i32 ()) @return_i32, i32 0, i32 1, i32 0, i32 0)37 %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(token %safepoint_token)38 ret i32 %call139}40 41define ptr @test_i32ptr_return() gc "statepoint-example" {42; CHECK-LABEL: test_i32ptr_return43; CHECK: pushq %rax44; CHECK: callq return_i32ptr45; CHECK: popq %rcx46; CHECK: retq47entry:48 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(ptr ()) @return_i32ptr, i32 0, i32 1, i32 0, i32 0)49 %call1 = call ptr @llvm.experimental.gc.result.p0(token %safepoint_token)50 ret ptr %call151}52 53define float @test_float_return() gc "statepoint-example" {54; CHECK-LABEL: test_float_return55; CHECK: pushq %rax56; CHECK: callq return_float57; CHECK: popq %rax58; CHECK: retq59entry:60 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(float ()) @return_float, i32 0, i32 1, i32 0, i32 0)61 %call1 = call float @llvm.experimental.gc.result.f32(token %safepoint_token)62 ret float %call163}64 65define i1 @test_relocate(ptr addrspace(1) %a) gc "statepoint-example" {66; CHECK-LABEL: test_relocate67; Check that an ununsed relocate has no code-generation impact68; CHECK: pushq %rax69; CHECK: callq return_i170; CHECK-NEXT: .Ltmp4:71; CHECK-NEXT: popq %rcx72; CHECK-NEXT: .cfi_def_cfa_offset 873; CHECK-NEXT: retq74entry:75 %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 1, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]76 %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)77 %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)78 ret i1 %call279}80 81define void @test_void_vararg() gc "statepoint-example" {82; CHECK-LABEL: test_void_vararg83; Check a statepoint wrapping a *ptr returning vararg function works84; CHECK: callq varargf85entry:86 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (i32, ...)) @varargf, i32 2, i32 1, i32 42, i32 43, i32 0, i32 0)87 ;; if we try to use the result from a statepoint wrapping a88 ;; non-void-returning varargf, we will experience a crash.89 ret void90}91 92define i32 @test_transition_args() gc "statepoint-example" {93; CHECK-LABEL: test_transition_args94; CHECK: pushq %rax95; CHECK: callq return_i3296; CHECK: popq %rcx97; CHECK: retq98entry:99 %val = alloca i32100 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i32 ()) @return_i32, i32 0, i32 1, i32 0, i32 0) ["gc-transition" (ptr %val, i64 42)]101 %call1 = call i32 @llvm.experimental.gc.result.i32(token %safepoint_token)102 ret i32 %call1103}104 105define i32 @test_transition_args_2() gc "statepoint-example" {106; CHECK-LABEL: test_transition_args_2107; CHECK: pushq %rax108; CHECK: callq return_i32109; CHECK: popq %rcx110; CHECK: retq111entry:112 %val = alloca i32113 %arg = alloca i8114 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i32 (i32, ptr)) @return_i32_with_args, i32 2, i32 1, i32 0, ptr %arg, i32 0, i32 0) ["gc-transition" (ptr %val, i64 42)]115 %call1 = call i32 @llvm.experimental.gc.result.i32(token %safepoint_token)116 ret i32 %call1117}118 119declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)120declare i1 @llvm.experimental.gc.result.i1(token)121 122declare i32 @llvm.experimental.gc.result.i32(token)123 124declare ptr @llvm.experimental.gc.result.p0(token)125 126declare float @llvm.experimental.gc.result.f32(token)127 128 129declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)130