Skip to content

Commit a8751cc

Browse files
committed
[Intrinsics] Make patchpoint.i64 generic on its return type
This allows patchpoints to allocate different registers for their result values, e.g. FP registers.
1 parent 4462bb5 commit a8751cc

File tree

10 files changed

+89
-27
lines changed

10 files changed

+89
-27
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: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -752,12 +752,12 @@ 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();
@@ -790,7 +790,9 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
790790
// Add an explicit result reg if we use the anyreg calling convention.
791791
if (IsAnyRegCC && HasDef) {
792792
assert(CLI.NumResultRegs == 0 && "Unexpected result register.");
793-
CLI.ResultReg = createResultReg(TLI.getRegClassFor(MVT::i64));
793+
assert(I->getType()->isSingleValueType());
794+
MVT ValueType = TLI.getSimpleValueType(DL, I->getType());
795+
CLI.ResultReg = createResultReg(TLI.getRegClassFor(ValueType));
794796
CLI.NumResultRegs = 1;
795797
Ops.push_back(MachineOperand::CreateReg(CLI.ResultReg, /*isDef=*/true));
796798
}
@@ -1464,7 +1466,7 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
14641466
case Intrinsic::experimental_stackmap:
14651467
return selectStackmap(II);
14661468
case Intrinsic::experimental_patchpoint_void:
1467-
case Intrinsic::experimental_patchpoint_i64:
1469+
case Intrinsic::experimental_patchpoint:
14681470
return selectPatchpoint(II);
14691471

14701472
case Intrinsic::xray_customevent:

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3330,7 +3330,7 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
33303330
EHPadMBB->setMachineBlockAddressTaken();
33313331
break;
33323332
case Intrinsic::experimental_patchpoint_void:
3333-
case Intrinsic::experimental_patchpoint_i64:
3333+
case Intrinsic::experimental_patchpoint:
33343334
visitPatchpoint(I, EHPadBB);
33353335
break;
33363336
case Intrinsic::experimental_gc_statepoint:
@@ -7443,7 +7443,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
74437443
visitStackmap(I);
74447444
return;
74457445
case Intrinsic::experimental_patchpoint_void:
7446-
case Intrinsic::experimental_patchpoint_i64:
7446+
case Intrinsic::experimental_patchpoint:
74477447
visitPatchpoint(I);
74487448
return;
74497449
case Intrinsic::experimental_gc_statepoint:
@@ -10255,12 +10255,12 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) {
1025510255
/// Lower llvm.experimental.patchpoint directly to its target opcode.
1025610256
void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
1025710257
const BasicBlock *EHPadBB) {
10258-
// void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>,
10259-
// i32 <numBytes>,
10260-
// i8* <target>,
10261-
// i32 <numArgs>,
10262-
// [Args...],
10263-
// [live variables...])
10258+
// <ty> @llvm.experimental.patchpoint.<ty>(i64 <id>,
10259+
// i32 <numBytes>,
10260+
// i8* <target>,
10261+
// i32 <numArgs>,
10262+
// [Args...],
10263+
// [live variables...])
1026410264

1026510265
CallingConv::ID CC = CB.getCallingConv();
1026610266
bool IsAnyRegCC = CC == CallingConv::AnyReg;

llvm/lib/IR/Verifier.cpp

Lines changed: 6 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,11 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
56615661
}
56625662
break;
56635663
}
5664+
case Intrinsic::experimental_patchpoint: {
5665+
Check(Call.getType()->isSingleValueType(),
5666+
"patchpoint result type is not a valid type for a register", Call);
5667+
break;
5668+
}
56645669
case Intrinsic::eh_exceptioncode:
56655670
case Intrinsic::eh_exceptionpointer: {
56665671
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
@@ -5651,7 +5651,7 @@ InstructionCost X86TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
56515651
return TTI::TCC_Free;
56525652
break;
56535653
case Intrinsic::experimental_patchpoint_void:
5654-
case Intrinsic::experimental_patchpoint_i64:
5654+
case Intrinsic::experimental_patchpoint:
56555655
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
56565656
return TTI::TCC_Free;
56575657
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;

llvm/test/CodeGen/AArch64/arm64-patchpoint.ll

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,61 @@ entry:
7979
ret void
8080
}
8181

82+
; Test register allocation for an i32 result value of patchpoint.
83+
define i32 @generic_patchpoint_i32() {
84+
entry:
85+
; CHECK-LABEL: generic_patchpoint_i32:
86+
; CHECK: Ltmp
87+
; CHECK-NEXT: nop
88+
; The return value is already in w0.
89+
; CHECK-NEXT: ldp
90+
; CHECK-NEXT: ret
91+
%result = tail call i32 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i32(i64 5, i32 4, ptr null, i32 0)
92+
ret i32 %result
93+
}
94+
95+
; Test register allocation for an i64 result value of patchpoint.
96+
define i64 @generic_patchpoint_i64() {
97+
entry:
98+
; CHECK-LABEL: generic_patchpoint_i64:
99+
; CHECK: Ltmp
100+
; CHECK-NEXT: nop
101+
; The return value is already in x0.
102+
; CHECK-NEXT: ldp
103+
; CHECK-NEXT: ret
104+
%result = tail call i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 4, ptr null, i32 0)
105+
ret i64 %result
106+
}
107+
108+
; Test register allocation for a float result value of patchpoint.
109+
define float @generic_patchpoint_f32() {
110+
entry:
111+
; CHECK-LABEL: generic_patchpoint_f32:
112+
; CHECK: Ltmp
113+
; CHECK-NEXT: nop
114+
; The return value is already in s0.
115+
; CHECK-NEXT: ldp
116+
; CHECK-NEXT: ret
117+
%result = tail call float (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.f32(i64 5, i32 4, ptr null, i32 0)
118+
ret float %result
119+
}
120+
121+
; Test register allocation for a double result value of patchpoint.
122+
define double @generic_patchpoint_f64() {
123+
entry:
124+
; CHECK-LABEL: generic_patchpoint_f64:
125+
; CHECK: Ltmp
126+
; CHECK-NEXT: nop
127+
; The return value is already in d0.
128+
; CHECK-NEXT: ldp
129+
; CHECK-NEXT: ret
130+
%result = tail call double (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.f64(i64 5, i32 4, ptr null, i32 0)
131+
ret double %result
132+
}
133+
82134
declare void @llvm.experimental.stackmap(i64, i32, ...)
83135
declare void @llvm.experimental.patchpoint.void(i64, i32, ptr, i32, ...)
136+
declare i32 @llvm.experimental.patchpoint.i32(i64, i32, ptr, i32, ...)
84137
declare i64 @llvm.experimental.patchpoint.i64(i64, i32, ptr, i32, ...)
138+
declare float @llvm.experimental.patchpoint.f32(i64, i32, ptr, i32, ...)
139+
declare double @llvm.experimental.patchpoint.f64(i64, i32, ptr, i32, ...)

0 commit comments

Comments
 (0)