[llvm] 0ad92c0 - [StatepointLowering] Take return attributes of `gc.result` into account (#68439)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 14 09:38:24 PDT 2023
Author: Markus Böck
Date: 2023-10-14T18:38:18+02:00
New Revision: 0ad92c0cbb34a6e24a9a32f03f3ddeb2114b378e
URL: https://github.com/llvm/llvm-project/commit/0ad92c0cbb34a6e24a9a32f03f3ddeb2114b378e
DIFF: https://github.com/llvm/llvm-project/commit/0ad92c0cbb34a6e24a9a32f03f3ddeb2114b378e.diff
LOG: [StatepointLowering] Take return attributes of `gc.result` into account (#68439)
The current lowering of statepoints does not take into account return
attributes present on the `gc.result` leading to different code being
generated than if one were to not use statepoints. These return
attributes can affect the ABI which is why it is important that they are
applied in the lowering.
Added:
Modified:
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll
llvm/test/CodeGen/X86/statepoint-call-lowering.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 187e000d0272d2e..da92f7d99df4397 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4397,8 +4397,14 @@ class TargetLowering : public TargetLoweringBase {
}
CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType,
- SDValue Target, ArgListTy &&ArgsList) {
+ SDValue Target, ArgListTy &&ArgsList,
+ AttributeSet ResultAttrs = {}) {
RetTy = ResultType;
+ IsInReg = ResultAttrs.hasAttribute(Attribute::InReg);
+ RetSExt = ResultAttrs.hasAttribute(Attribute::SExt);
+ RetZExt = ResultAttrs.hasAttribute(Attribute::ZExt);
+ NoMerge = ResultAttrs.hasAttribute(Attribute::NoMerge);
+
Callee = Target;
CallConv = CC;
NumFixedArgs = ArgsList.size();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index c5fd56795a5201a..4bb0ba6f083109b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -9728,7 +9728,7 @@ SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
void SelectionDAGBuilder::populateCallLoweringInfo(
TargetLowering::CallLoweringInfo &CLI, const CallBase *Call,
unsigned ArgIdx, unsigned NumArgs, SDValue Callee, Type *ReturnTy,
- bool IsPatchPoint) {
+ AttributeSet RetAttrs, bool IsPatchPoint) {
TargetLowering::ArgListTy Args;
Args.reserve(NumArgs);
@@ -9749,7 +9749,8 @@ void SelectionDAGBuilder::populateCallLoweringInfo(
CLI.setDebugLoc(getCurSDLoc())
.setChain(getRoot())
- .setCallee(Call->getCallingConv(), ReturnTy, Callee, std::move(Args))
+ .setCallee(Call->getCallingConv(), ReturnTy, Callee, std::move(Args),
+ RetAttrs)
.setDiscardResult(Call->use_empty())
.setIsPatchPoint(IsPatchPoint)
.setIsPreallocated(
@@ -9898,7 +9899,7 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
TargetLowering::CallLoweringInfo CLI(DAG);
populateCallLoweringInfo(CLI, &CB, NumMetaOpers, NumCallArgs, Callee,
- ReturnTy, true);
+ ReturnTy, CB.getAttributes().getRetAttrs(), true);
std::pair<SDValue, SDValue> Result = lowerInvokable(CLI, EHPadBB);
SDNode *CallEnd = Result.second.getNode();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index ec23445b01640ca..a97884f0efb9a9b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -426,7 +426,8 @@ class SelectionDAGBuilder {
void populateCallLoweringInfo(TargetLowering::CallLoweringInfo &CLI,
const CallBase *Call, unsigned ArgIdx,
unsigned NumArgs, SDValue Callee,
- Type *ReturnTy, bool IsPatchPoint);
+ Type *ReturnTy, AttributeSet RetAttrs,
+ bool IsPatchPoint);
std::pair<SDValue, SDValue>
lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index f313d60424c234b..cf32350036d412c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -1033,10 +1033,16 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I,
ActualCallee = Callee;
}
+ const auto GCResultLocality = getGCResultLocality(I);
+ AttributeSet retAttrs;
+ if (GCResultLocality.first)
+ retAttrs = GCResultLocality.first->getAttributes().getRetAttrs();
+
StatepointLoweringInfo SI(DAG);
populateCallLoweringInfo(SI.CLI, &I, GCStatepointInst::CallArgsBeginPos,
I.getNumCallArgs(), ActualCallee,
- I.getActualReturnType(), false /* IsPatchPoint */);
+ I.getActualReturnType(), retAttrs,
+ /*IsPatchPoint=*/false);
// There may be duplication in the gc.relocate list; such as two copies of
// each relocation on normal and exceptional path for an invoke. We only
@@ -1092,8 +1098,6 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I,
SDValue ReturnValue = LowerAsSTATEPOINT(SI);
// Export the result value if needed
- const auto GCResultLocality = getGCResultLocality(I);
-
if (!GCResultLocality.first && !GCResultLocality.second) {
// The return value is not needed, just generate a poison value.
// Note: This covers the void return case.
@@ -1138,7 +1142,7 @@ void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl(
populateCallLoweringInfo(
SI.CLI, Call, ArgBeginIndex, Call->arg_size(), Callee,
ForceVoidReturnTy ? Type::getVoidTy(*DAG.getContext()) : Call->getType(),
- false);
+ Call->getAttributes().getRetAttrs(), /*IsPatchPoint=*/false);
if (!VarArgDisallowed)
SI.CLI.IsVarArg = Call->getFunctionType()->isVarArg();
diff --git a/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll b/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll
index 6326d3db9afb819..9619895c450cac3 100644
--- a/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll
+++ b/llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll
@@ -23,7 +23,6 @@ define i1 @test_i1_return() gc "statepoint-example" {
; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: bl return_i1
; 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
@@ -106,7 +105,6 @@ define i1 @test_relocate(ptr addrspace(1) %a) gc "statepoint-example" {
; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: bl return_i1
; CHECK-NEXT: .Ltmp5:
-; CHECK-NEXT: and w0, w0, #0x1
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: ret
; Check that an ununsed relocate has no code-generation impact
@@ -145,7 +143,6 @@ define i1 @test_i1_return_patchable() gc "statepoint-example" {
; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: nop
; 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
diff --git a/llvm/test/CodeGen/X86/statepoint-call-lowering.ll b/llvm/test/CodeGen/X86/statepoint-call-lowering.ll
index 66088046ef5ec0f..758cb8b7b63d5cc 100644
--- a/llvm/test/CodeGen/X86/statepoint-call-lowering.ll
+++ b/llvm/test/CodeGen/X86/statepoint-call-lowering.ll
@@ -247,8 +247,6 @@ define i8 @test_signext_return(ptr) gc "statepoint-example" {
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: callq signext_return_i1 at PLT
; CHECK-NEXT: .Ltmp10:
-; CHECK-NEXT: andb $1, %al
-; CHECK-NEXT: negb %al
; CHECK-NEXT: popq %rcx
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
@@ -266,7 +264,6 @@ define i8 @test_zeroext_return() gc "statepoint-example" {
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: callq return_i1 at PLT
; CHECK-NEXT: .Ltmp11:
-; CHECK-NEXT: andb $1, %al
; CHECK-NEXT: popq %rcx
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
@@ -277,6 +274,24 @@ entry:
ret i8 %ext
}
+define signext i1 @test_noext_signext_return() gc "statepoint-example" {
+; CHECK-LABEL: test_noext_signext_return:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: callq return_i1 at PLT
+; CHECK-NEXT: .Ltmp12:
+; CHECK-NEXT: andb $1, %al
+; CHECK-NEXT: negb %al
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: .cfi_def_cfa_offset 8
+; CHECK-NEXT: retq
+entry:
+ %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)
+ %call1 = call i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
+ ret i1 %call1
+}
+
declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
declare i1 @llvm.experimental.gc.result.i1(token)
More information about the llvm-commits
mailing list