Skip to content

Commit 384770e

Browse files
committed
[IR] Don't DCE llvm.ret.popless.
We originally had the intrinsic forward its return value to the ret to have musttail-like behavior, which ensured it was always preserved. Now that the intrinsic call is musttail but doesn't have any forwarded operands, it needs to be kept alive through other means. It might make sense to mark it as having side effects, and not duplicable, but that shouldn't be necessary, and it's as duplicable as any musttail call+ret sequence would be. Because of this, we can't rely on it being DCE'd in ISel either, so drop it explicitly in IRTranslator for GISel. We already had to do it in SDISel anyway. While there, explicitly reject it in FastISel. rdar://147236255
1 parent 52307ab commit 384770e

File tree

6 files changed

+27
-3
lines changed

6 files changed

+27
-3
lines changed

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ def int_localrecover : DefaultAttrsIntrinsic<[llvm_ptr_ty],
850850
//
851851
// Calls to this intrinsic need to be musttail, but don't follow the other ABI
852852
// requirements for musttail calls, since this is really annotating the ret.
853-
def int_ret_popless : DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
853+
def int_ret_popless : DefaultAttrsIntrinsic<[], [], [IntrInaccessibleMemOnly]>;
854854

855855
// Given the frame pointer passed into an SEH filter function, returns a
856856
// pointer to the local variable area suitable for use with llvm.localrecover.

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,6 +2393,13 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
23932393
{getOrCreateVReg(*CI.getArgOperand(0))});
23942394
return true;
23952395
}
2396+
case Intrinsic::ret_popless: {
2397+
// The ret.popless intrin call itself is only annotating the following ret.
2398+
// To achieve that, it does need to be musttail and reachable from the ret.
2399+
assert(CI.getParent()->getTerminatingMustTailCall() == &CI &&
2400+
"llvm.ret.popless not in musttail position");
2401+
return true;
2402+
}
23962403
case Intrinsic::cttz:
23972404
case Intrinsic::ctlz: {
23982405
ConstantInt *Cst = cast<ConstantInt>(CI.getArgOperand(1));

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7958,7 +7958,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
79587958
}
79597959

79607960
case Intrinsic::ret_popless:
7961-
// We're handling this on the associated ret itself.
7961+
// The ret.popless intrin call itself is only annotating the following ret.
7962+
// To achieve that, it does need to be musttail and reachable from the ret.
7963+
assert(I.getParent()->getTerminatingMustTailCall() == &I &&
7964+
"llvm.ret.popless not in musttail position");
79627965
return;
79637966

79647967
case Intrinsic::threadlocal_address: {

llvm/lib/Target/AArch64/AArch64FastISel.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,6 +3867,9 @@ bool AArch64FastISel::selectRet(const Instruction *I) {
38673867
if (TLI.supportSplitCSR(FuncInfo.MF))
38683868
return false;
38693869

3870+
if (I->getParent()->getTerminatingMustTailCall())
3871+
return false;
3872+
38703873
// Build a list of return value registers.
38713874
SmallVector<unsigned, 4> RetRegs;
38723875

llvm/test/CodeGen/AArch64/swiftcorocc-ret-popless.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
22
; RUN: llc -verify-machineinstrs -mtriple arm64e-apple-darwin -o - %s | FileCheck %s --check-prefixes=CHECK,SDISEL
3-
; RUN: llc -verify-machineinstrs -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=2 -o - %s | FileCheck %s --check-prefixes=CHECK,GISEL
3+
; RUN: llc -verify-machineinstrs -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 -o - %s | FileCheck %s --check-prefixes=CHECK,GISEL
44

55
declare i64 @g(ptr, ptr)
66

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S < %s -passes=dce | FileCheck %s
3+
4+
define void @test_ret_popless() {
5+
; CHECK-LABEL: define void @test_ret_popless() {
6+
; CHECK-NEXT: musttail call void @llvm.ret.popless()
7+
; CHECK-NEXT: ret void
8+
;
9+
musttail call void @llvm.ret.popless()
10+
ret void
11+
}

0 commit comments

Comments
 (0)