diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index b59b4022c4245..40fc8405426ea 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -261,10 +261,11 @@ static MachineInstrBuilder buildGoStackGrowthStatepoint(MachineFunction &MF, ArrayRef PointerSlots = MF.getInfo()->getGoArgPointerSlots(); uint64_t PointerSize = MF.getDataLayout().getPointerSize(); - int64_t StackBias = - goabi::isGoABI0CallingConv(MF.getFunction().getCallingConv()) - ? 0 - : static_cast(PointerSize); + // X86 entry RSP points at the return address for both Go calling + // conventions. GoArgPointerSlot::EntryOffset is a physical stack-map + // location even though the corresponding fixed home uses a logical Go + // argument-area offset. + int64_t StackMapBias = static_cast(PointerSize); AddConstant(MF.getFunction().getCallingConv()); AddConstant(0); // Statepoint flags. AddConstant(0); // Deopt arguments. @@ -274,7 +275,7 @@ static MachineInstrBuilder buildGoStackGrowthStatepoint(MachineFunction &MF, report_fatal_error( "X86 Go entry argument pointer slot is not a fixed object"); int64_t ExpectedOffset = - StackBias + static_cast(Slot.ArgWord) * PointerSize; + StackMapBias + static_cast(Slot.ArgWord) * PointerSize; if (PointerSize == 0 || Slot.EntryOffset != ExpectedOffset) report_fatal_error( "X86 Go entry argument pointer slot has invalid RSP offset"); diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp index 36a79a06130ee..04b7bda0828bd 100644 --- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp +++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp @@ -191,10 +191,11 @@ static SDValue lowerX86GoFormalArguments( const Function &F = MF.getFunction(); const X86Subtarget &Subtarget = MF.getSubtarget(); MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout()); - int64_t EntryStackBias = - goabi::isGoABI0CallingConv(F.getCallingConv()) - ? 0 - : static_cast(PtrVT.getStoreSize()); + // Fixed argument homes use offsets in the logical Go argument area. Stack + // map locations are instead relative to the physical entry RSP, which + // points at the return address for both Go calling conventions. + int64_t EntryStackMapBias = + static_cast(PtrVT.getStoreSize()); SmallVector LayoutMap; SmallVector ArgTys = getX86GoArgTypes(F, LayoutMap); @@ -250,7 +251,7 @@ static SDValue lowerX86GoFormalArguments( MFI.getObjectOffset(FI) + static_cast(WithinObject); int64_t ExpectedFixedObjectOffset = static_cast(PointerOffset); int64_t EntryOffset = - EntryStackBias + static_cast(PointerOffset); + EntryStackMapBias + static_cast(PointerOffset); if (FixedObjectOffset != ExpectedFixedObjectOffset || !isInt<32>(EntryOffset)) report_fatal_error( diff --git a/llvm/test/CodeGen/X86/goobj-stack-growth-statepoint.ll b/llvm/test/CodeGen/X86/goobj-stack-growth-statepoint.ll index 5b32443d7cd04..f194941e30360 100644 --- a/llvm/test/CodeGen/X86/goobj-stack-growth-statepoint.ll +++ b/llvm/test/CodeGen/X86/goobj-stack-growth-statepoint.ll @@ -11,6 +11,8 @@ i64, i64, i64, i64, i64, i64, i64, %pointer.aggregate } +declare goabiinternal void @use_three_pointers(ptr, ptr, ptr) + define goabiinternal i64 @morestack_statepoint(i64 %value) "go-stack-growth-statepoint" { entry: %buf = alloca [5000 x i8], align 8 @@ -19,6 +21,14 @@ entry: ret i64 %value } +define goabi0 void @abi0_pointer_arguments(ptr %first, ptr %second, ptr %third) + "frame-pointer"="non-leaf" "go-stack-growth-statepoint" { +entry: + call goabiinternal void @use_three_pointers( + ptr %first, ptr %second, ptr %third) + ret void +} + define goabiinternal %many.results @initialized_pointer_result(ptr %pointer) "go-stack-growth-statepoint" "go_results_tuple" { entry: @@ -77,6 +87,23 @@ entry: ; words themselves are numbered from the start of the Go ABI arg/result/home ; area, exactly as native Go ArgsPointerMaps numbers them. +; GoABI0 fixed homes retain their logical argument-area offsets, while loads +; and stack-map locations include the physical entry RSP return-address word. + +; CHECK-LABEL: name: abi0_pointer_arguments +; CHECK: fixedStack: +; CHECK: offset: 16, size: 8 +; CHECK: offset: 8, size: 8 +; CHECK: offset: 0, size: 8 +; CHECK: STATEPOINT 5147424658422983495, 0, 0, &runtime.morestack_noctxt, +; CHECK-SAME: 2, 23, 2, 0, 2, 0, 2, 3, +; CHECK-SAME: 1, 8, $rsp, 8, 1, 8, $rsp, 16, 1, 8, $rsp, 24, +; CHECK-SAME: 2, 0, 2, 3, 0, 0, 1, 1, 2, 2, +; CHECK-SAME: csr_64_go, implicit-def $rsp, implicit-def $ssp +; CHECK: renamable $rax = MOV64rm $rbp, 1, $noreg, 16, $noreg +; CHECK: renamable $rbx = MOV64rm $rbp, 1, $noreg, 24, $noreg +; CHECK: renamable $rcx = MOV64rm $rbp, 1, $noreg, 32, $noreg + ; CHECK-LABEL: name: initialized_pointer_result ; CHECK: MOV64mr $rsp, 1, $noreg, 72, $noreg, $rax ; CHECK: STATEPOINT 5147424658422983495, 0, 0, &runtime.morestack_noctxt,