Skip to content

Commit 308ed02

Browse files
authored
[Intrinsics] Make patchpoint.i64 generic on its return type (#85911)
Currently patchpoints can only have two result types, `void` and `i64`. This limits the result to general purpose registers. This patch makes `patchpoint.i64` an overloadable intrinsic, allowing result values that can fit in a single register (e.g. integers, pointers, floats).
1 parent 93d33a1 commit 308ed02

File tree

11 files changed

+404
-30
lines changed

11 files changed

+404
-30
lines changed

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,11 +1590,11 @@ def int_experimental_patchpoint_void : Intrinsic<[],
15901590
llvm_ptr_ty, llvm_i32_ty,
15911591
llvm_vararg_ty],
15921592
[Throws]>;
1593-
def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
1594-
[llvm_i64_ty, llvm_i32_ty,
1595-
llvm_ptr_ty, llvm_i32_ty,
1596-
llvm_vararg_ty],
1597-
[Throws]>;
1593+
def int_experimental_patchpoint : Intrinsic<[llvm_any_ty],
1594+
[llvm_i64_ty, llvm_i32_ty,
1595+
llvm_ptr_ty, llvm_i32_ty,
1596+
llvm_vararg_ty],
1597+
[Throws]>;
15981598

15991599

16001600
//===------------------------ Garbage Collection Intrinsics ---------------===//

llvm/lib/CodeGen/SelectionDAG/FastISel.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -752,17 +752,25 @@ FastISel::CallLoweringInfo &FastISel::CallLoweringInfo::setCallee(
752752
}
753753

754754
bool FastISel::selectPatchpoint(const CallInst *I) {
755-
// void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>,
756-
// i32 <numBytes>,
757-
// i8* <target>,
758-
// i32 <numArgs>,
759-
// [Args...],
760-
// [live variables...])
755+
// <ty> @llvm.experimental.patchpoint.<ty>(i64 <id>,
756+
// i32 <numBytes>,
757+
// i8* <target>,
758+
// i32 <numArgs>,
759+
// [Args...],
760+
// [live variables...])
761761
CallingConv::ID CC = I->getCallingConv();
762762
bool IsAnyRegCC = CC == CallingConv::AnyReg;
763763
bool HasDef = !I->getType()->isVoidTy();
764764
Value *Callee = I->getOperand(PatchPointOpers::TargetPos)->stripPointerCasts();
765765

766+
// Check if we can lower the return type when using anyregcc.
767+
MVT ValueType;
768+
if (IsAnyRegCC && HasDef) {
769+
ValueType = TLI.getSimpleValueType(DL, I->getType(), /*AllowUnknown=*/true);
770+
if (ValueType == MVT::Other)
771+
return false;
772+
}
773+
766774
// Get the real number of arguments participating in the call <numArgs>
767775
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos)) &&
768776
"Expected a constant integer.");
@@ -790,7 +798,8 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
790798
// Add an explicit result reg if we use the anyreg calling convention.
791799
if (IsAnyRegCC && HasDef) {
792800
assert(CLI.NumResultRegs == 0 && "Unexpected result register.");
793-
CLI.ResultReg = createResultReg(TLI.getRegClassFor(MVT::i64));
801+
assert(ValueType.isValid());
802+
CLI.ResultReg = createResultReg(TLI.getRegClassFor(ValueType));
794803
CLI.NumResultRegs = 1;
795804
Ops.push_back(MachineOperand::CreateReg(CLI.ResultReg, /*isDef=*/true));
796805
}
@@ -1464,7 +1473,7 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
14641473
case Intrinsic::experimental_stackmap:
14651474
return selectStackmap(II);
14661475
case Intrinsic::experimental_patchpoint_void:
1467-
case Intrinsic::experimental_patchpoint_i64:
1476+
case Intrinsic::experimental_patchpoint:
14681477
return selectPatchpoint(II);
14691478

14701479
case Intrinsic::xray_customevent:

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3331,7 +3331,7 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
33313331
EHPadMBB->setMachineBlockAddressTaken();
33323332
break;
33333333
case Intrinsic::experimental_patchpoint_void:
3334-
case Intrinsic::experimental_patchpoint_i64:
3334+
case Intrinsic::experimental_patchpoint:
33353335
visitPatchpoint(I, EHPadBB);
33363336
break;
33373337
case Intrinsic::experimental_gc_statepoint:
@@ -7445,7 +7445,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
74457445
visitStackmap(I);
74467446
return;
74477447
case Intrinsic::experimental_patchpoint_void:
7448-
case Intrinsic::experimental_patchpoint_i64:
7448+
case Intrinsic::experimental_patchpoint:
74497449
visitPatchpoint(I);
74507450
return;
74517451
case Intrinsic::experimental_gc_statepoint:
@@ -10257,12 +10257,12 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) {
1025710257
/// Lower llvm.experimental.patchpoint directly to its target opcode.
1025810258
void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
1025910259
const BasicBlock *EHPadBB) {
10260-
// void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>,
10261-
// i32 <numBytes>,
10262-
// i8* <target>,
10263-
// i32 <numArgs>,
10264-
// [Args...],
10265-
// [live variables...])
10260+
// <ty> @llvm.experimental.patchpoint.<ty>(i64 <id>,
10261+
// i32 <numBytes>,
10262+
// i8* <target>,
10263+
// i32 <numArgs>,
10264+
// [Args...],
10265+
// [live variables...])
1026610266

1026710267
CallingConv::ID CC = CB.getCallingConv();
1026810268
bool IsAnyRegCC = CC == CallingConv::AnyReg;

llvm/lib/IR/Verifier.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5016,7 +5016,7 @@ void Verifier::visitInstruction(Instruction &I) {
50165016
F->getIntrinsicID() == Intrinsic::coro_await_suspend_handle ||
50175017
F->getIntrinsicID() ==
50185018
Intrinsic::experimental_patchpoint_void ||
5019-
F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 ||
5019+
F->getIntrinsicID() == Intrinsic::experimental_patchpoint ||
50205020
F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint ||
50215021
F->getIntrinsicID() == Intrinsic::wasm_rethrow ||
50225022
IsAttachedCallOperand(F, CBI, i),
@@ -5661,6 +5661,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
56615661
}
56625662
break;
56635663
}
5664+
case Intrinsic::experimental_patchpoint: {
5665+
if (Call.getCallingConv() == CallingConv::AnyReg) {
5666+
Check(Call.getType()->isSingleValueType(),
5667+
"patchpoint: invalid return type used with anyregcc", Call);
5668+
}
5669+
break;
5670+
}
56645671
case Intrinsic::eh_exceptioncode:
56655672
case Intrinsic::eh_exceptionpointer: {
56665673
Check(isa<CatchPadInst>(Call.getArgOperand(0)),

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ AArch64TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
479479
return TTI::TCC_Free;
480480
break;
481481
case Intrinsic::experimental_patchpoint_void:
482-
case Intrinsic::experimental_patchpoint_i64:
482+
case Intrinsic::experimental_patchpoint:
483483
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
484484
return TTI::TCC_Free;
485485
break;

llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ InstructionCost PPCTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
219219
return TTI::TCC_Free;
220220
break;
221221
case Intrinsic::experimental_patchpoint_void:
222-
case Intrinsic::experimental_patchpoint_i64:
222+
case Intrinsic::experimental_patchpoint:
223223
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
224224
return TTI::TCC_Free;
225225
break;

llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ SystemZTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
265265
return TTI::TCC_Free;
266266
break;
267267
case Intrinsic::experimental_patchpoint_void:
268-
case Intrinsic::experimental_patchpoint_i64:
268+
case Intrinsic::experimental_patchpoint:
269269
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
270270
return TTI::TCC_Free;
271271
break;

llvm/lib/Target/X86/X86TargetTransformInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5659,7 +5659,7 @@ InstructionCost X86TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
56595659
return TTI::TCC_Free;
56605660
break;
56615661
case Intrinsic::experimental_patchpoint_void:
5662-
case Intrinsic::experimental_patchpoint_i64:
5662+
case Intrinsic::experimental_patchpoint:
56635663
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
56645664
return TTI::TCC_Free;
56655665
break;

llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ static bool doesNotRequireEntrySafepointBefore(CallBase *Call) {
517517
switch (II->getIntrinsicID()) {
518518
case Intrinsic::experimental_gc_statepoint:
519519
case Intrinsic::experimental_patchpoint_void:
520-
case Intrinsic::experimental_patchpoint_i64:
520+
case Intrinsic::experimental_patchpoint:
521521
// The can wrap an actual call which may grow the stack by an unbounded
522522
// amount or run forever.
523523
return false;

0 commit comments

Comments
 (0)