diff --git a/llvm/include/llvm/CodeGen/StackMaps.h b/llvm/include/llvm/CodeGen/StackMaps.h --- a/llvm/include/llvm/CodeGen/StackMaps.h +++ b/llvm/include/llvm/CodeGen/StackMaps.h @@ -171,7 +171,7 @@ public: explicit StatepointOpers(const MachineInstr *MI) : MI(MI) { - NumDefs = MI->getNumDefs(); + NumDefs = MI->getNumExplicitDefs(); } /// Get index of statepoint ID operand. diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -2261,7 +2261,9 @@ case TargetOpcode::STACKMAP: case TargetOpcode::PATCHPOINT: + return emitPatchPoint(MI, BB); case TargetOpcode::STATEPOINT: + MI.addOperand(*BB->getParent(), MachineOperand::CreateReg(AArch64::LR, true, true)); return emitPatchPoint(MI, BB); case AArch64::CATCHRET: diff --git a/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll b/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll --- a/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll +++ b/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll @@ -18,9 +18,13 @@ define i1 @test_i1_return() gc "statepoint-example" { ; CHECK-LABEL: test_i1_return: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl return_i1 -; CHECK-NEXT: .Ltmp2: +; CHECK-NEXT: .Ltmp0: ; CHECK-NEXT: and w0, w0, #0x1 +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret ; This is just checking that a i1 gets lowered normally when there's no extra ; state arguments to the statepoint @@ -33,8 +37,12 @@ define i32 @test_i32_return() gc "statepoint-example" { ; CHECK-LABEL: test_i32_return: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl return_i32 -; CHECK-NEXT: .Ltmp3: +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret entry: %safepoint_token = tail call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0) @@ -45,8 +53,12 @@ define i32* @test_i32ptr_return() gc "statepoint-example" { ; CHECK-LABEL: test_i32ptr_return: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl return_i32ptr -; CHECK-NEXT: .Ltmp4: +; CHECK-NEXT: .Ltmp2: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret entry: %safepoint_token = tail call token (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0) @@ -57,8 +69,12 @@ define float @test_float_return() gc "statepoint-example" { ; CHECK-LABEL: test_float_return: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl return_float -; CHECK-NEXT: .Ltmp5: +; CHECK-NEXT: .Ltmp3: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret entry: %safepoint_token = tail call token (i64, i32, float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(i64 0, i32 0, float ()* @return_float, i32 0, i32 0, i32 0, i32 0) @@ -69,8 +85,12 @@ define %struct @test_struct_return() gc "statepoint-example" { ; CHECK-LABEL: test_struct_return: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl return_struct -; CHECK-NEXT: .Ltmp6: +; CHECK-NEXT: .Ltmp4: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret entry: %safepoint_token = tail call token (i64, i32, %struct ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_structf(i64 0, i32 0, %struct ()* @return_struct, i32 0, i32 0, i32 0, i32 0) @@ -81,13 +101,13 @@ define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" { ; CHECK-LABEL: test_relocate: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: sub sp, sp, #16 // =16 +; CHECK-NEXT: stp x30, x0, [sp, #-16]! // 8-byte Folded Spill ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: str x0, [sp, #8] +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl return_i1 -; CHECK-NEXT: .Ltmp7: +; CHECK-NEXT: .Ltmp5: ; CHECK-NEXT: and w0, w0, #0x1 -; CHECK-NEXT: add sp, sp, #16 // =16 +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret ; Check that an ununsed relocate has no code-generation impact entry: @@ -100,10 +120,14 @@ define void @test_void_vararg() gc "statepoint-example" { ; CHECK-LABEL: test_void_vararg: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: mov w0, #42 ; CHECK-NEXT: mov w1, #43 ; CHECK-NEXT: bl varargf -; CHECK-NEXT: .Ltmp8: +; CHECK-NEXT: .Ltmp6: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret ; Check a statepoint wrapping a *void* returning vararg function works entry: @@ -116,9 +140,13 @@ define i1 @test_i1_return_patchable() gc "statepoint-example" { ; CHECK-LABEL: test_i1_return_patchable: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: nop -; CHECK-NEXT: .Ltmp9: +; CHECK-NEXT: .Ltmp7: ; CHECK-NEXT: and w0, w0, #0x1 +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret ; A patchable variant of test_i1_return entry: @@ -141,7 +169,7 @@ ; CHECK-NEXT: mov w20, w1 ; CHECK-NEXT: str x0, [sp, #8] ; CHECK-NEXT: bl return_i1 -; CHECK-NEXT: .Ltmp10: +; CHECK-NEXT: .Ltmp8: ; CHECK-NEXT: tbz w20, #0, .LBB8_2 ; CHECK-NEXT: // %bb.1: // %left ; CHECK-NEXT: mov w19, w0 @@ -176,18 +204,21 @@ define void @test_attributes(%struct2* byval(%struct2) %s) gc "statepoint-example" { ; CHECK-LABEL: test_attributes: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: sub sp, sp, #32 // =32 -; CHECK-NEXT: .cfi_def_cfa_offset 32 -; CHECK-NEXT: ldr x8, [sp, #48] -; CHECK-NEXT: ldr q0, [sp, #32] +; CHECK-NEXT: sub sp, sp, #48 // =48 +; CHECK-NEXT: str x30, [sp, #32] // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: .cfi_offset w30, -16 +; CHECK-NEXT: ldr x8, [sp, #64] +; CHECK-NEXT: ldr q0, [sp, #48] ; CHECK-NEXT: mov w0, #42 ; CHECK-NEXT: mov w1, #17 ; CHECK-NEXT: mov x18, xzr ; CHECK-NEXT: str x8, [sp, #16] ; CHECK-NEXT: str q0, [sp] ; CHECK-NEXT: bl consume_attributes -; CHECK-NEXT: .Ltmp11: -; CHECK-NEXT: add sp, sp, #32 // =32 +; CHECK-NEXT: .Ltmp9: +; CHECK-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload +; CHECK-NEXT: add sp, sp, #48 // =48 ; CHECK-NEXT: ret entry: ; Check that arguments with attributes are lowered correctly.