153003e36SSacha Coppey; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 253003e36SSacha Coppey; RUN: llc -verify-machineinstrs < %s | FileCheck %s 353003e36SSacha Coppey; A collection of basic functionality tests for statepoint lowering - most 453003e36SSacha Coppey; interesting cornercases are exercised through the x86 tests. 553003e36SSacha Coppey 653003e36SSacha Coppeytarget datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 753003e36SSacha Coppeytarget triple = "riscv64" 853003e36SSacha Coppey 953003e36SSacha Coppey%struct = type { i64, i64 } 1053003e36SSacha Coppey 1153003e36SSacha Coppeydeclare zeroext i1 @return_i1() 1253003e36SSacha Coppeydeclare zeroext i32 @return_i32() 1353003e36SSacha Coppeydeclare ptr @return_i32ptr() 1453003e36SSacha Coppeydeclare float @return_float() 1553003e36SSacha Coppeydeclare %struct @return_struct() 1653003e36SSacha Coppeydeclare void @varargf(i32, ...) 1753003e36SSacha Coppey 1853003e36SSacha Coppeydefine i1 @test_i1_return() gc "statepoint-example" { 1953003e36SSacha Coppey; CHECK-LABEL: test_i1_return: 2053003e36SSacha Coppey; CHECK: # %bb.0: # %entry 2153003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 2253003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 2353003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 2453003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 2553003e36SSacha Coppey; CHECK-NEXT: call return_i1 2653003e36SSacha Coppey; CHECK-NEXT: .Ltmp0: 2753003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 28*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 2953003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 30*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 3153003e36SSacha Coppey; CHECK-NEXT: ret 3253003e36SSacha Coppey; This is just checking that a i1 gets lowered normally when there's no extra 3353003e36SSacha Coppey; state arguments to the statepoint 3453003e36SSacha Coppeyentry: 3553003e36SSacha Coppey %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) 3653003e36SSacha Coppey %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 3753003e36SSacha Coppey ret i1 %call1 3853003e36SSacha Coppey} 3953003e36SSacha Coppey 4053003e36SSacha Coppeydefine i32 @test_i32_return() gc "statepoint-example" { 4153003e36SSacha Coppey; CHECK-LABEL: test_i32_return: 4253003e36SSacha Coppey; CHECK: # %bb.0: # %entry 4353003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 4453003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 4553003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 4653003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 4753003e36SSacha Coppey; CHECK-NEXT: call return_i32 4853003e36SSacha Coppey; CHECK-NEXT: .Ltmp1: 4953003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 50*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 5153003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 52*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 5353003e36SSacha Coppey; CHECK-NEXT: ret 5453003e36SSacha Coppeyentry: 5553003e36SSacha Coppey %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) 5653003e36SSacha Coppey %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(token %safepoint_token) 5753003e36SSacha Coppey ret i32 %call1 5853003e36SSacha Coppey} 5953003e36SSacha Coppey 6053003e36SSacha Coppeydefine ptr @test_i32ptr_return() gc "statepoint-example" { 6153003e36SSacha Coppey; CHECK-LABEL: test_i32ptr_return: 6253003e36SSacha Coppey; CHECK: # %bb.0: # %entry 6353003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 6453003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 6553003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 6653003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 6753003e36SSacha Coppey; CHECK-NEXT: call return_i32ptr 6853003e36SSacha Coppey; CHECK-NEXT: .Ltmp2: 6953003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 70*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 7153003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 72*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 7353003e36SSacha Coppey; CHECK-NEXT: ret 7453003e36SSacha Coppeyentry: 7553003e36SSacha Coppey %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) 7653003e36SSacha Coppey %call1 = call ptr @llvm.experimental.gc.result.p0(token %safepoint_token) 7753003e36SSacha Coppey ret ptr %call1 7853003e36SSacha Coppey} 7953003e36SSacha Coppey 8053003e36SSacha Coppeydefine float @test_float_return() gc "statepoint-example" { 8153003e36SSacha Coppey; CHECK-LABEL: test_float_return: 8253003e36SSacha Coppey; CHECK: # %bb.0: # %entry 8353003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 8453003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 8553003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 8653003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 8753003e36SSacha Coppey; CHECK-NEXT: call return_float 8853003e36SSacha Coppey; CHECK-NEXT: .Ltmp3: 8953003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 90*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 9153003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 92*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 9353003e36SSacha Coppey; CHECK-NEXT: ret 9453003e36SSacha Coppeyentry: 9553003e36SSacha Coppey %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) 9653003e36SSacha Coppey %call1 = call float @llvm.experimental.gc.result.f32(token %safepoint_token) 9753003e36SSacha Coppey ret float %call1 9853003e36SSacha Coppey} 9953003e36SSacha Coppey 10053003e36SSacha Coppeydefine %struct @test_struct_return() gc "statepoint-example" { 10153003e36SSacha Coppey; CHECK-LABEL: test_struct_return: 10253003e36SSacha Coppey; CHECK: # %bb.0: # %entry 10353003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 10453003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 10553003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 10653003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 10753003e36SSacha Coppey; CHECK-NEXT: call return_struct 10853003e36SSacha Coppey; CHECK-NEXT: .Ltmp4: 10953003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 110*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 11153003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 112*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 11353003e36SSacha Coppey; CHECK-NEXT: ret 11453003e36SSacha Coppeyentry: 11553003e36SSacha Coppey %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) 11653003e36SSacha Coppey %call1 = call %struct @llvm.experimental.gc.result.struct(token %safepoint_token) 11753003e36SSacha Coppey ret %struct %call1 11853003e36SSacha Coppey} 11953003e36SSacha Coppey 12053003e36SSacha Coppeydefine i1 @test_relocate(ptr addrspace(1) %a) gc "statepoint-example" { 12153003e36SSacha Coppey; CHECK-LABEL: test_relocate: 12253003e36SSacha Coppey; CHECK: # %bb.0: # %entry 12353003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 12453003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 12553003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 12653003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 12753003e36SSacha Coppey; CHECK-NEXT: sd a0, 0(sp) 12853003e36SSacha Coppey; CHECK-NEXT: call return_i1 12953003e36SSacha Coppey; CHECK-NEXT: .Ltmp5: 13053003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 131*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 13253003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 133*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 13453003e36SSacha Coppey; CHECK-NEXT: ret 13553003e36SSacha Coppey; Check that an ununsed relocate has no code-generation impact 13653003e36SSacha Coppeyentry: 13753003e36SSacha Coppey %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)] 13853003e36SSacha Coppey %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 13953003e36SSacha Coppey %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 14053003e36SSacha Coppey ret i1 %call2 14153003e36SSacha Coppey} 14253003e36SSacha Coppey 14353003e36SSacha Coppeydefine void @test_void_vararg() gc "statepoint-example" { 14453003e36SSacha Coppey; CHECK-LABEL: test_void_vararg: 14553003e36SSacha Coppey; CHECK: # %bb.0: # %entry 14653003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 14753003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 14853003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 14953003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 15053003e36SSacha Coppey; CHECK-NEXT: li a0, 42 15153003e36SSacha Coppey; CHECK-NEXT: li a1, 43 15253003e36SSacha Coppey; CHECK-NEXT: call varargf 15353003e36SSacha Coppey; CHECK-NEXT: .Ltmp6: 15453003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 155*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 15653003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 157*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 15853003e36SSacha Coppey; CHECK-NEXT: ret 15953003e36SSacha Coppey; Check a statepoint wrapping a *ptr returning vararg function works 16053003e36SSacha Coppeyentry: 16153003e36SSacha Coppey %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) 16253003e36SSacha Coppey ;; if we try to use the result from a statepoint wrapping a 16353003e36SSacha Coppey ;; non-void-returning varargf, we will experience a crash. 16453003e36SSacha Coppey ret void 16553003e36SSacha Coppey} 16653003e36SSacha Coppey 16753003e36SSacha Coppeydefine i1 @test_i1_return_patchable() gc "statepoint-example" { 16853003e36SSacha Coppey; CHECK-LABEL: test_i1_return_patchable: 16953003e36SSacha Coppey; CHECK: # %bb.0: # %entry 17053003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -16 17153003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 16 17253003e36SSacha Coppey; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 17353003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 17453003e36SSacha Coppey; CHECK-NEXT: nop 17553003e36SSacha Coppey; CHECK-NEXT: .Ltmp7: 17653003e36SSacha Coppey; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 177*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 17853003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 16 179*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 18053003e36SSacha Coppey; CHECK-NEXT: ret 18153003e36SSacha Coppey; A patchable variant of test_i1_return 18253003e36SSacha Coppeyentry: 18353003e36SSacha Coppey %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 4, ptr elementtype(i1 ()) null, i32 0, i32 0, i32 0, i32 0) 18453003e36SSacha Coppey %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 18553003e36SSacha Coppey ret i1 %call1 18653003e36SSacha Coppey} 18753003e36SSacha Coppey 18853003e36SSacha Coppeydeclare void @consume(ptr addrspace(1) %obj) 18953003e36SSacha Coppey 19053003e36SSacha Coppeydefine i1 @test_cross_bb(ptr addrspace(1) %a, i1 %external_cond) gc "statepoint-example" { 19153003e36SSacha Coppey; CHECK-LABEL: test_cross_bb: 19253003e36SSacha Coppey; CHECK: # %bb.0: # %entry 19353003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -32 19453003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 32 19553003e36SSacha Coppey; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 19653003e36SSacha Coppey; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 19753003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 19853003e36SSacha Coppey; CHECK-NEXT: .cfi_offset s0, -16 19953003e36SSacha Coppey; CHECK-NEXT: andi s0, a1, 1 20053003e36SSacha Coppey; CHECK-NEXT: sd a0, 8(sp) 20153003e36SSacha Coppey; CHECK-NEXT: call return_i1 20253003e36SSacha Coppey; CHECK-NEXT: .Ltmp8: 20353003e36SSacha Coppey; CHECK-NEXT: beqz s0, .LBB8_2 20453003e36SSacha Coppey; CHECK-NEXT: # %bb.1: # %left 20553003e36SSacha Coppey; CHECK-NEXT: ld a1, 8(sp) 20653003e36SSacha Coppey; CHECK-NEXT: mv s0, a0 20753003e36SSacha Coppey; CHECK-NEXT: mv a0, a1 20853003e36SSacha Coppey; CHECK-NEXT: call consume 20953003e36SSacha Coppey; CHECK-NEXT: mv a0, s0 21053003e36SSacha Coppey; CHECK-NEXT: j .LBB8_3 21153003e36SSacha Coppey; CHECK-NEXT: .LBB8_2: # %right 21253003e36SSacha Coppey; CHECK-NEXT: li a0, 1 21353003e36SSacha Coppey; CHECK-NEXT: .LBB8_3: # %right 21453003e36SSacha Coppey; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 21553003e36SSacha Coppey; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 216*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 217*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore s0 21853003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 32 219*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 22053003e36SSacha Coppey; CHECK-NEXT: ret 22153003e36SSacha Coppeyentry: 22253003e36SSacha Coppey %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)] 22353003e36SSacha Coppey br i1 %external_cond, label %left, label %right 22453003e36SSacha Coppey 22553003e36SSacha Coppeyleft: 22653003e36SSacha Coppey %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 22753003e36SSacha Coppey %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 22853003e36SSacha Coppey call void @consume(ptr addrspace(1) %call1) 22953003e36SSacha Coppey ret i1 %call2 23053003e36SSacha Coppey 23153003e36SSacha Coppeyright: 23253003e36SSacha Coppey ret i1 true 23353003e36SSacha Coppey} 23453003e36SSacha Coppey 23553003e36SSacha Coppey%struct2 = type { i64, i64, i64 } 23653003e36SSacha Coppey 23753003e36SSacha Coppeydeclare void @consume_attributes(i32, ptr nest, i32, ptr byval(%struct2)) 23853003e36SSacha Coppey 23953003e36SSacha Coppeydefine void @test_attributes(ptr byval(%struct2) %s) gc "statepoint-example" { 24053003e36SSacha Coppey; CHECK-LABEL: test_attributes: 24153003e36SSacha Coppey; CHECK: # %bb.0: # %entry 24253003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, -32 24353003e36SSacha Coppey; CHECK-NEXT: .cfi_def_cfa_offset 32 24453003e36SSacha Coppey; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 24553003e36SSacha Coppey; CHECK-NEXT: .cfi_offset ra, -8 24653003e36SSacha Coppey; CHECK-NEXT: ld a1, 16(a0) 24753003e36SSacha Coppey; CHECK-NEXT: sd a1, 16(sp) 24853003e36SSacha Coppey; CHECK-NEXT: ld a1, 8(a0) 24953003e36SSacha Coppey; CHECK-NEXT: sd a1, 8(sp) 25053003e36SSacha Coppey; CHECK-NEXT: ld a0, 0(a0) 25153003e36SSacha Coppey; CHECK-NEXT: sd a0, 0(sp) 25253003e36SSacha Coppey; CHECK-NEXT: li a0, 42 25353003e36SSacha Coppey; CHECK-NEXT: li a1, 17 25453003e36SSacha Coppey; CHECK-NEXT: mv a2, sp 25553003e36SSacha Coppey; CHECK-NEXT: li t2, 0 25653003e36SSacha Coppey; CHECK-NEXT: call consume_attributes 25753003e36SSacha Coppey; CHECK-NEXT: .Ltmp9: 25853003e36SSacha Coppey; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 259*97982a8cSdlav-sc; CHECK-NEXT: .cfi_restore ra 26053003e36SSacha Coppey; CHECK-NEXT: addi sp, sp, 32 261*97982a8cSdlav-sc; CHECK-NEXT: .cfi_def_cfa_offset 0 26253003e36SSacha Coppey; CHECK-NEXT: ret 26353003e36SSacha Coppeyentry: 26453003e36SSacha Coppey; Check that arguments with attributes are lowered correctly. 26553003e36SSacha Coppey; We call a function that has a nest argument and a byval argument. 26653003e36SSacha Coppey %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) 26753003e36SSacha Coppey ret void 26853003e36SSacha Coppey} 26953003e36SSacha Coppey 27053003e36SSacha Coppeydeclare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) 27153003e36SSacha Coppeydeclare i1 @llvm.experimental.gc.result.i1(token) 27253003e36SSacha Coppey 27353003e36SSacha Coppeydeclare i32 @llvm.experimental.gc.result.i32(token) 27453003e36SSacha Coppey 27553003e36SSacha Coppeydeclare ptr @llvm.experimental.gc.result.p0(token) 27653003e36SSacha Coppey 27753003e36SSacha Coppeydeclare float @llvm.experimental.gc.result.f32(token) 27853003e36SSacha Coppey 27953003e36SSacha Coppeydeclare %struct @llvm.experimental.gc.result.struct(token) 28053003e36SSacha Coppey 28153003e36SSacha Coppey 28253003e36SSacha Coppey 28353003e36SSacha Coppeydeclare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) 284