Skip to content

Commit 0ad92c0

Browse files
authored
[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.
1 parent c442d20 commit 0ad92c0

File tree

6 files changed

+39
-15
lines changed

6 files changed

+39
-15
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4397,8 +4397,14 @@ class TargetLowering : public TargetLoweringBase {
43974397
}
43984398

43994399
CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType,
4400-
SDValue Target, ArgListTy &&ArgsList) {
4400+
SDValue Target, ArgListTy &&ArgsList,
4401+
AttributeSet ResultAttrs = {}) {
44014402
RetTy = ResultType;
4403+
IsInReg = ResultAttrs.hasAttribute(Attribute::InReg);
4404+
RetSExt = ResultAttrs.hasAttribute(Attribute::SExt);
4405+
RetZExt = ResultAttrs.hasAttribute(Attribute::ZExt);
4406+
NoMerge = ResultAttrs.hasAttribute(Attribute::NoMerge);
4407+
44024408
Callee = Target;
44034409
CallConv = CC;
44044410
NumFixedArgs = ArgsList.size();

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9728,7 +9728,7 @@ SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
97289728
void SelectionDAGBuilder::populateCallLoweringInfo(
97299729
TargetLowering::CallLoweringInfo &CLI, const CallBase *Call,
97309730
unsigned ArgIdx, unsigned NumArgs, SDValue Callee, Type *ReturnTy,
9731-
bool IsPatchPoint) {
9731+
AttributeSet RetAttrs, bool IsPatchPoint) {
97329732
TargetLowering::ArgListTy Args;
97339733
Args.reserve(NumArgs);
97349734

@@ -9749,7 +9749,8 @@ void SelectionDAGBuilder::populateCallLoweringInfo(
97499749

97509750
CLI.setDebugLoc(getCurSDLoc())
97519751
.setChain(getRoot())
9752-
.setCallee(Call->getCallingConv(), ReturnTy, Callee, std::move(Args))
9752+
.setCallee(Call->getCallingConv(), ReturnTy, Callee, std::move(Args),
9753+
RetAttrs)
97539754
.setDiscardResult(Call->use_empty())
97549755
.setIsPatchPoint(IsPatchPoint)
97559756
.setIsPreallocated(
@@ -9898,7 +9899,7 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
98989899

98999900
TargetLowering::CallLoweringInfo CLI(DAG);
99009901
populateCallLoweringInfo(CLI, &CB, NumMetaOpers, NumCallArgs, Callee,
9901-
ReturnTy, true);
9902+
ReturnTy, CB.getAttributes().getRetAttrs(), true);
99029903
std::pair<SDValue, SDValue> Result = lowerInvokable(CLI, EHPadBB);
99039904

99049905
SDNode *CallEnd = Result.second.getNode();

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ class SelectionDAGBuilder {
426426
void populateCallLoweringInfo(TargetLowering::CallLoweringInfo &CLI,
427427
const CallBase *Call, unsigned ArgIdx,
428428
unsigned NumArgs, SDValue Callee,
429-
Type *ReturnTy, bool IsPatchPoint);
429+
Type *ReturnTy, AttributeSet RetAttrs,
430+
bool IsPatchPoint);
430431

431432
std::pair<SDValue, SDValue>
432433
lowerInvokable(TargetLowering::CallLoweringInfo &CLI,

llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,10 +1033,16 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I,
10331033
ActualCallee = Callee;
10341034
}
10351035

1036+
const auto GCResultLocality = getGCResultLocality(I);
1037+
AttributeSet retAttrs;
1038+
if (GCResultLocality.first)
1039+
retAttrs = GCResultLocality.first->getAttributes().getRetAttrs();
1040+
10361041
StatepointLoweringInfo SI(DAG);
10371042
populateCallLoweringInfo(SI.CLI, &I, GCStatepointInst::CallArgsBeginPos,
10381043
I.getNumCallArgs(), ActualCallee,
1039-
I.getActualReturnType(), false /* IsPatchPoint */);
1044+
I.getActualReturnType(), retAttrs,
1045+
/*IsPatchPoint=*/false);
10401046

10411047
// There may be duplication in the gc.relocate list; such as two copies of
10421048
// each relocation on normal and exceptional path for an invoke. We only
@@ -1092,8 +1098,6 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I,
10921098
SDValue ReturnValue = LowerAsSTATEPOINT(SI);
10931099

10941100
// Export the result value if needed
1095-
const auto GCResultLocality = getGCResultLocality(I);
1096-
10971101
if (!GCResultLocality.first && !GCResultLocality.second) {
10981102
// The return value is not needed, just generate a poison value.
10991103
// Note: This covers the void return case.
@@ -1138,7 +1142,7 @@ void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl(
11381142
populateCallLoweringInfo(
11391143
SI.CLI, Call, ArgBeginIndex, Call->arg_size(), Callee,
11401144
ForceVoidReturnTy ? Type::getVoidTy(*DAG.getContext()) : Call->getType(),
1141-
false);
1145+
Call->getAttributes().getRetAttrs(), /*IsPatchPoint=*/false);
11421146
if (!VarArgDisallowed)
11431147
SI.CLI.IsVarArg = Call->getFunctionType()->isVarArg();
11441148

llvm/test/CodeGen/AArch64/statepoint-call-lowering.ll

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ define i1 @test_i1_return() gc "statepoint-example" {
2323
; CHECK-NEXT: .cfi_offset w30, -16
2424
; CHECK-NEXT: bl return_i1
2525
; CHECK-NEXT: .Ltmp0:
26-
; CHECK-NEXT: and w0, w0, #0x1
2726
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
2827
; CHECK-NEXT: ret
2928
; 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" {
106105
; CHECK-NEXT: .cfi_offset w30, -16
107106
; CHECK-NEXT: bl return_i1
108107
; CHECK-NEXT: .Ltmp5:
109-
; CHECK-NEXT: and w0, w0, #0x1
110108
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
111109
; CHECK-NEXT: ret
112110
; Check that an ununsed relocate has no code-generation impact
@@ -145,7 +143,6 @@ define i1 @test_i1_return_patchable() gc "statepoint-example" {
145143
; CHECK-NEXT: .cfi_offset w30, -16
146144
; CHECK-NEXT: nop
147145
; CHECK-NEXT: .Ltmp7:
148-
; CHECK-NEXT: and w0, w0, #0x1
149146
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
150147
; CHECK-NEXT: ret
151148
; A patchable variant of test_i1_return

llvm/test/CodeGen/X86/statepoint-call-lowering.ll

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,6 @@ define i8 @test_signext_return(ptr) gc "statepoint-example" {
247247
; CHECK-NEXT: .cfi_def_cfa_offset 16
248248
; CHECK-NEXT: callq signext_return_i1@PLT
249249
; CHECK-NEXT: .Ltmp10:
250-
; CHECK-NEXT: andb $1, %al
251-
; CHECK-NEXT: negb %al
252250
; CHECK-NEXT: popq %rcx
253251
; CHECK-NEXT: .cfi_def_cfa_offset 8
254252
; CHECK-NEXT: retq
@@ -266,7 +264,6 @@ define i8 @test_zeroext_return() gc "statepoint-example" {
266264
; CHECK-NEXT: .cfi_def_cfa_offset 16
267265
; CHECK-NEXT: callq return_i1@PLT
268266
; CHECK-NEXT: .Ltmp11:
269-
; CHECK-NEXT: andb $1, %al
270267
; CHECK-NEXT: popq %rcx
271268
; CHECK-NEXT: .cfi_def_cfa_offset 8
272269
; CHECK-NEXT: retq
@@ -277,6 +274,24 @@ entry:
277274
ret i8 %ext
278275
}
279276

277+
define signext i1 @test_noext_signext_return() gc "statepoint-example" {
278+
; CHECK-LABEL: test_noext_signext_return:
279+
; CHECK: # %bb.0: # %entry
280+
; CHECK-NEXT: pushq %rax
281+
; CHECK-NEXT: .cfi_def_cfa_offset 16
282+
; CHECK-NEXT: callq return_i1@PLT
283+
; CHECK-NEXT: .Ltmp12:
284+
; CHECK-NEXT: andb $1, %al
285+
; CHECK-NEXT: negb %al
286+
; CHECK-NEXT: popq %rcx
287+
; CHECK-NEXT: .cfi_def_cfa_offset 8
288+
; CHECK-NEXT: retq
289+
entry:
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 %call1
293+
}
294+
280295
declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
281296
declare i1 @llvm.experimental.gc.result.i1(token)
282297

0 commit comments

Comments
 (0)