brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.8 KiB · 758cb8b Raw
309 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -verify-machineinstrs < %s | FileCheck %s3; This file contains a collection of basic tests to ensure we didn't4; screw up normal call lowering when there are no deopt or gc arguments.5 6target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"7target triple = "x86_64-pc-linux-gnu"8 9%struct = type { i64, i64 }10 11declare zeroext i1 @return_i1()12declare zeroext i32 @return_i32()13declare ptr @return_i32ptr()14declare float @return_float()15declare %struct @return_struct()16declare void @varargf(i32, ...)17 18define i1 @test_i1_return() gc "statepoint-example" {19; CHECK-LABEL: test_i1_return:20; CHECK:       # %bb.0: # %entry21; CHECK-NEXT:    pushq %rax22; CHECK-NEXT:    .cfi_def_cfa_offset 1623; CHECK-NEXT:    callq return_i1@PLT24; CHECK-NEXT:  .Ltmp0:25; CHECK-NEXT:    popq %rcx26; CHECK-NEXT:    .cfi_def_cfa_offset 827; CHECK-NEXT:    retq28; This is just checking that a i1 gets lowered normally when there's no extra29; state arguments to the statepoint30entry:31  %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)32  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)33  ret i1 %call134}35 36define i32 @test_i32_return() gc "statepoint-example" {37; CHECK-LABEL: test_i32_return:38; CHECK:       # %bb.0: # %entry39; CHECK-NEXT:    pushq %rax40; CHECK-NEXT:    .cfi_def_cfa_offset 1641; CHECK-NEXT:    callq return_i32@PLT42; CHECK-NEXT:  .Ltmp1:43; CHECK-NEXT:    popq %rcx44; CHECK-NEXT:    .cfi_def_cfa_offset 845; CHECK-NEXT:    retq46entry:47  %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 0, i32 0, i32 0)48  %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(token %safepoint_token)49  ret i32 %call150}51 52define ptr @test_i32ptr_return() gc "statepoint-example" {53; CHECK-LABEL: test_i32ptr_return:54; CHECK:       # %bb.0: # %entry55; CHECK-NEXT:    pushq %rax56; CHECK-NEXT:    .cfi_def_cfa_offset 1657; CHECK-NEXT:    callq return_i32ptr@PLT58; CHECK-NEXT:  .Ltmp2:59; CHECK-NEXT:    popq %rcx60; CHECK-NEXT:    .cfi_def_cfa_offset 861; CHECK-NEXT:    retq62entry:63  %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 0, i32 0, i32 0)64  %call1 = call ptr @llvm.experimental.gc.result.p0(token %safepoint_token)65  ret ptr %call166}67 68define float @test_float_return() gc "statepoint-example" {69; CHECK-LABEL: test_float_return:70; CHECK:       # %bb.0: # %entry71; CHECK-NEXT:    pushq %rax72; CHECK-NEXT:    .cfi_def_cfa_offset 1673; CHECK-NEXT:    callq return_float@PLT74; CHECK-NEXT:  .Ltmp3:75; CHECK-NEXT:    popq %rax76; CHECK-NEXT:    .cfi_def_cfa_offset 877; CHECK-NEXT:    retq78entry:79  %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 0, i32 0, i32 0)80  %call1 = call float @llvm.experimental.gc.result.f32(token %safepoint_token)81  ret float %call182}83 84define %struct @test_struct_return() gc "statepoint-example" {85; CHECK-LABEL: test_struct_return:86; CHECK:       # %bb.0: # %entry87; CHECK-NEXT:    pushq %rax88; CHECK-NEXT:    .cfi_def_cfa_offset 1689; CHECK-NEXT:    callq return_struct@PLT90; CHECK-NEXT:  .Ltmp4:91; CHECK-NEXT:    popq %rcx92; CHECK-NEXT:    .cfi_def_cfa_offset 893; CHECK-NEXT:    retq94entry:95  %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(%struct ()) @return_struct, i32 0, i32 0, i32 0, i32 0)96  %call1 = call %struct @llvm.experimental.gc.result.struct(token %safepoint_token)97  ret %struct %call198}99 100define i1 @test_relocate(ptr addrspace(1) %a) gc "statepoint-example" {101; CHECK-LABEL: test_relocate:102; CHECK:       # %bb.0: # %entry103; CHECK-NEXT:    pushq %rax104; CHECK-NEXT:    .cfi_def_cfa_offset 16105; CHECK-NEXT:    movq %rdi, (%rsp)106; CHECK-NEXT:    callq return_i1@PLT107; CHECK-NEXT:  .Ltmp5:108; CHECK-NEXT:    popq %rcx109; CHECK-NEXT:    .cfi_def_cfa_offset 8110; CHECK-NEXT:    retq111; Check that an ununsed relocate has no code-generation impact112entry:113  %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)]114  %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token,  i32 0, i32 0)115  %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)116  ret i1 %call2117}118 119define void @test_void_vararg() gc "statepoint-example" {120; CHECK-LABEL: test_void_vararg:121; CHECK:       # %bb.0: # %entry122; CHECK-NEXT:    pushq %rax123; CHECK-NEXT:    .cfi_def_cfa_offset 16124; CHECK-NEXT:    movl $42, %edi125; CHECK-NEXT:    movl $43, %esi126; CHECK-NEXT:    callq varargf@PLT127; CHECK-NEXT:  .Ltmp6:128; CHECK-NEXT:    popq %rax129; CHECK-NEXT:    .cfi_def_cfa_offset 8130; CHECK-NEXT:    retq131; Check a statepoint wrapping a *ptr returning vararg function works132entry:133  %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 0, i32 42, i32 43, i32 0, i32 0)134  ;; if we try to use the result from a statepoint wrapping a135  ;; non-void-returning varargf, we will experience a crash.136  ret void137}138 139define i1 @test_i1_return_patchable() gc "statepoint-example" {140; CHECK-LABEL: test_i1_return_patchable:141; CHECK:       # %bb.0: # %entry142; CHECK-NEXT:    pushq %rax143; CHECK-NEXT:    .cfi_def_cfa_offset 16144; CHECK-NEXT:    nopl (%rax)145; CHECK-NEXT:  .Ltmp7:146; CHECK-NEXT:    popq %rcx147; CHECK-NEXT:    .cfi_def_cfa_offset 8148; CHECK-NEXT:    retq149; A patchable variant of test_i1_return150entry:151  %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 3, ptr elementtype(i1 ()) null, i32 0, i32 0, i32 0, i32 0)152  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)153  ret i1 %call1154}155 156declare void @consume(ptr addrspace(1) %obj)157 158define i1 @test_cross_bb(ptr addrspace(1) %a, i1 %external_cond) gc "statepoint-example" {159; CHECK-LABEL: test_cross_bb:160; CHECK:       # %bb.0: # %entry161; CHECK-NEXT:    pushq %rbx162; CHECK-NEXT:    .cfi_def_cfa_offset 16163; CHECK-NEXT:    subq $16, %rsp164; CHECK-NEXT:    .cfi_def_cfa_offset 32165; CHECK-NEXT:    .cfi_offset %rbx, -16166; CHECK-NEXT:    movl %esi, %ebx167; CHECK-NEXT:    movq %rdi, {{[0-9]+}}(%rsp)168; CHECK-NEXT:    callq return_i1@PLT169; CHECK-NEXT:  .Ltmp8:170; CHECK-NEXT:    testb $1, %bl171; CHECK-NEXT:    je .LBB8_2172; CHECK-NEXT:  # %bb.1: # %left173; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rdi174; CHECK-NEXT:    movl %eax, %ebx175; CHECK-NEXT:    callq consume@PLT176; CHECK-NEXT:    movl %ebx, %eax177; CHECK-NEXT:    jmp .LBB8_3178; CHECK-NEXT:  .LBB8_2: # %right179; CHECK-NEXT:    movb $1, %al180; CHECK-NEXT:  .LBB8_3: # %right181; CHECK-NEXT:    addq $16, %rsp182; CHECK-NEXT:    .cfi_def_cfa_offset 16183; CHECK-NEXT:    popq %rbx184; CHECK-NEXT:    .cfi_def_cfa_offset 8185; CHECK-NEXT:    retq186entry:187  %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)]188  br i1 %external_cond, label %left, label %right189 190left:191  %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token,  i32 0, i32 0)192  %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)193  call void @consume(ptr addrspace(1) %call1)194  ret i1 %call2195 196right:197  ret i1 true198}199 200%struct2 = type { i64, i64, i64 }201 202declare void @consume_attributes(i32, ptr nest, i32, ptr byval(%struct2))203 204define void @test_attributes(ptr byval(%struct2) %s) gc "statepoint-example" {205; CHECK-LABEL: test_attributes:206; CHECK:       # %bb.0: # %entry207; CHECK-NEXT:    pushq %rax208; CHECK-NEXT:    .cfi_def_cfa_offset 16209; CHECK-NEXT:    subq $8, %rsp210; CHECK-NEXT:    .cfi_adjust_cfa_offset 8211; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rax212; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rcx213; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rdx214; CHECK-NEXT:    movl $42, %edi215; CHECK-NEXT:    xorl %r10d, %r10d216; CHECK-NEXT:    movl $17, %esi217; CHECK-NEXT:    pushq %rax218; CHECK-NEXT:    .cfi_adjust_cfa_offset 8219; CHECK-NEXT:    pushq %rdx220; CHECK-NEXT:    .cfi_adjust_cfa_offset 8221; CHECK-NEXT:    pushq %rcx222; CHECK-NEXT:    .cfi_adjust_cfa_offset 8223; CHECK-NEXT:    callq consume_attributes@PLT224; CHECK-NEXT:  .Ltmp9:225; CHECK-NEXT:    addq $32, %rsp226; CHECK-NEXT:    .cfi_adjust_cfa_offset -32227; CHECK-NEXT:    popq %rax228; CHECK-NEXT:    .cfi_def_cfa_offset 8229; CHECK-NEXT:    retq230entry:231; Check that arguments with attributes are lowered correctly.232; We call a function that has a nest argument and a byval argument.233  %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (i32, ptr, i32, ptr)) @consume_attributes, i32 4, i32 0, i32 42, ptr nest null, i32 17, ptr byval(%struct2) %s, i32 0, i32 0)234  ret void235}236 237declare signext i1 @signext_return_i1()238 239; Check that the generated code takes the zeroext and signext return attributes240; on the GC result into account. The attribute in the return position allows the241; caller to assume that the callee did the extension already.242 243define i8 @test_signext_return(ptr) gc "statepoint-example" {244; CHECK-LABEL: test_signext_return:245; CHECK:       # %bb.0: # %entry246; CHECK-NEXT:    pushq %rax247; CHECK-NEXT:    .cfi_def_cfa_offset 16248; CHECK-NEXT:    callq signext_return_i1@PLT249; CHECK-NEXT:  .Ltmp10:250; CHECK-NEXT:    popq %rcx251; CHECK-NEXT:    .cfi_def_cfa_offset 8252; CHECK-NEXT:    retq253entry:254  %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @signext_return_i1, i32 0, i32 0, i32 0, i32 0)255  %call1 = call signext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)256  %ext = sext i1 %call1 to i8257  ret i8 %ext258}259 260define i8 @test_zeroext_return() gc "statepoint-example" {261; CHECK-LABEL: test_zeroext_return:262; CHECK:       # %bb.0: # %entry263; CHECK-NEXT:    pushq %rax264; CHECK-NEXT:    .cfi_def_cfa_offset 16265; CHECK-NEXT:    callq return_i1@PLT266; CHECK-NEXT:  .Ltmp11:267; CHECK-NEXT:    popq %rcx268; CHECK-NEXT:    .cfi_def_cfa_offset 8269; CHECK-NEXT:    retq270entry:271  %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)272  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)273  %ext = zext i1 %call1 to i8274  ret i8 %ext275}276 277define signext i1 @test_noext_signext_return() gc "statepoint-example" {278; CHECK-LABEL: test_noext_signext_return:279; CHECK:       # %bb.0: # %entry280; CHECK-NEXT:    pushq %rax281; CHECK-NEXT:    .cfi_def_cfa_offset 16282; CHECK-NEXT:    callq return_i1@PLT283; CHECK-NEXT:  .Ltmp12:284; CHECK-NEXT:    andb $1, %al285; CHECK-NEXT:    negb %al286; CHECK-NEXT:    popq %rcx287; CHECK-NEXT:    .cfi_def_cfa_offset 8288; CHECK-NEXT:    retq289entry:290  %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)291  %call1 = call i1 @llvm.experimental.gc.result.i1(token %safepoint_token)292  ret i1 %call1293}294 295declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)296declare i1 @llvm.experimental.gc.result.i1(token)297 298declare i32 @llvm.experimental.gc.result.i32(token)299 300declare ptr @llvm.experimental.gc.result.p0(token)301 302declare float @llvm.experimental.gc.result.f32(token)303 304declare %struct @llvm.experimental.gc.result.struct(token)305 306 307 308declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)309